diff --git a/.all-contributorsrc b/.all-contributorsrc deleted file mode 100644 index aa9d9ec4..00000000 --- a/.all-contributorsrc +++ /dev/null @@ -1,1083 +0,0 @@ -{ - "projectName": "netlify-cms", - "projectOwner": "netlify", - "files": [ - "README.md" - ], - "imageSize": 100, - "commit": false, - "badgeTemplate": "[![All Contributors](https://img.shields.io/badge/all_contributors-<%= contributors.length %>-orange.svg)](#contributors)", - "contributors": [ - { - "login": "cassiozen", - "name": "Cássio Souza", - "avatar_url": "https://avatars2.githubusercontent.com/u/33676?v=4", - "profile": "https://twitter.com/cassiozen", - "contributions": [ - "code" - ] - }, - { - "login": "erquhart", - "name": "Shawn Erquhart", - "avatar_url": "https://avatars3.githubusercontent.com/u/2112202?v=4", - "profile": "https://erquh.art", - "contributions": [ - "code" - ] - }, - { - "login": "okonet", - "name": "Andrey Okonetchnikov", - "avatar_url": "https://avatars3.githubusercontent.com/u/11071?v=4", - "profile": "http://okonet.ru", - "contributions": [ - "code" - ] - }, - { - "login": "biilmann", - "name": "Mathias Biilmann", - "avatar_url": "https://avatars0.githubusercontent.com/u/6515?v=4", - "profile": "https://www.netlify.com", - "contributions": [ - "code" - ] - }, - { - "login": "Benaiah", - "name": "Benaiah Mischenko", - "avatar_url": "https://avatars1.githubusercontent.com/u/1425133?v=4", - "profile": "http://benaiah.me", - "contributions": [ - "code" - ] - }, - { - "login": "rafaelconde", - "name": "Rafael Conde", - "avatar_url": "https://avatars0.githubusercontent.com/u/2281080?v=4", - "profile": "http://rafaelconde.net", - "contributions": [ - "design", - "code" - ] - }, - { - "login": "josephearl", - "name": "Joseph Earl", - "avatar_url": "https://avatars0.githubusercontent.com/u/2513147?v=4", - "profile": "http://josephearl.co.uk", - "contributions": [ - "code" - ] - }, - { - "login": "bdougie", - "name": "Brian Douglas", - "avatar_url": "https://avatars2.githubusercontent.com/u/5713670?v=4", - "profile": "https://briandouglas.me/", - "contributions": [ - "code" - ] - }, - { - "login": "phae", - "name": "Frances Berriman", - "avatar_url": "https://avatars3.githubusercontent.com/u/44568?v=4", - "profile": "https://fberriman.com", - "contributions": [ - "design" - ] - }, - { - "login": "calavera", - "name": "David Calavera", - "avatar_url": "https://avatars0.githubusercontent.com/u/1050?v=4", - "profile": "https://github.com/calavera", - "contributions": [ - "code" - ] - }, - { - "login": "lmcorreia", - "name": "Luis Correia", - "avatar_url": "https://avatars0.githubusercontent.com/u/8883545?v=4", - "profile": "https://luisc.pt", - "contributions": [ - "code" - ] - }, - { - "login": "tech4him1", - "name": "Caleb", - "avatar_url": "https://avatars1.githubusercontent.com/u/20345941?v=4", - "profile": "https://github.com/tech4him1", - "contributions": [ - "code" - ] - }, - { - "login": "jholmes033169", - "name": "Jerry Holmes", - "avatar_url": "https://avatars0.githubusercontent.com/u/3292160?v=4", - "profile": "http://www.pagedragon.com", - "contributions": [ - "code" - ] - }, - { - "login": "abumalick", - "name": "abumalick", - "avatar_url": "https://avatars0.githubusercontent.com/u/8377185?v=4", - "profile": "https://github.com/abumalick", - "contributions": [ - "code" - ] - }, - { - "login": "eamonnbell", - "name": "Eamonn Bell", - "avatar_url": "https://avatars1.githubusercontent.com/u/4513526?v=4", - "profile": "http://www.eamonnbell.com", - "contributions": [ - "code" - ] - }, - { - "login": "verythorough", - "name": "Jessica Parsons", - "avatar_url": "https://avatars2.githubusercontent.com/u/6111186?v=4", - "profile": "https://github.com/verythorough", - "contributions": [ - "doc" - ] - }, - { - "login": "KyleAMathews", - "name": "Kyle Mathews", - "avatar_url": "https://avatars3.githubusercontent.com/u/71047?v=4", - "profile": "https://www.bricolage.io", - "contributions": [ - "code" - ] - }, - { - "login": "americool", - "name": "americool", - "avatar_url": "https://avatars1.githubusercontent.com/u/16258690?v=4", - "profile": "https://github.com/americool", - "contributions": [ - "code" - ] - }, - { - "login": "Dammmien", - "name": "Damien Duhamel", - "avatar_url": "https://avatars3.githubusercontent.com/u/3051737?v=4", - "profile": "http://www.damienduhamel.fr", - "contributions": [ - "code" - ] - }, - { - "login": "juliankrispel", - "name": "Julian Krispel-Samsel", - "avatar_url": "https://avatars1.githubusercontent.com/u/1188186?v=4", - "profile": "http://reactrocket.com", - "contributions": [] - }, - { - "login": "HarlemSquirrel", - "name": "Kevin McCormack", - "avatar_url": "https://avatars0.githubusercontent.com/u/6445815?v=4", - "profile": "http://harlemsquirrel.github.io/", - "contributions": [] - }, - { - "login": "kalinchernev", - "name": "Kalin Chernev", - "avatar_url": "https://avatars3.githubusercontent.com/u/1923476?v=4", - "profile": "https://github.com/kalinchernev", - "contributions": [] - }, - { - "login": "tortilaman", - "name": "tortilaman", - "avatar_url": "https://avatars2.githubusercontent.com/u/5018268?v=4", - "profile": "https://github.com/tortilaman", - "contributions": [] - }, - { - "login": "vencax", - "name": "Václav Klecanda", - "avatar_url": "https://avatars0.githubusercontent.com/u/1184334?v=4", - "profile": "http://www.vxk.cz", - "contributions": [] - }, - { - "login": "DrianHillman", - "name": "DrianHillman", - "avatar_url": "https://avatars0.githubusercontent.com/u/2983665?v=4", - "profile": "http://drianhillman.me", - "contributions": [] - }, - { - "login": "seantcoyote", - "name": "Sean Crawford", - "avatar_url": "https://avatars1.githubusercontent.com/u/1198032?v=4", - "profile": "https://github.com/seantcoyote", - "contributions": [] - }, - { - "login": "rriemann", - "name": "Robert Riemann", - "avatar_url": "https://avatars1.githubusercontent.com/u/111932?v=4", - "profile": "http://blog.riemann.cc", - "contributions": [] - }, - { - "login": "rivertam", - "name": "Ben Berman", - "avatar_url": "https://avatars1.githubusercontent.com/u/4165105?v=4", - "profile": "http://jygabyte.com", - "contributions": [] - }, - { - "login": "bkniffler", - "name": "Benjamin Kniffler", - "avatar_url": "https://avatars3.githubusercontent.com/u/4349324?v=4", - "profile": "https://github.com/bkniffler", - "contributions": [] - }, - { - "login": "mwickett", - "name": "Mike Wickett", - "avatar_url": "https://avatars1.githubusercontent.com/u/845983?v=4", - "profile": "http://www.wickett.ca", - "contributions": [] - }, - { - "login": "GOGO98901", - "name": "Rory Claasen", - "avatar_url": "https://avatars1.githubusercontent.com/u/2751799?v=4", - "profile": "http://roryclaasen.me", - "contributions": [] - }, - { - "login": "freder", - "name": "Frederic Brodbeck", - "avatar_url": "https://avatars3.githubusercontent.com/u/724844?v=4", - "profile": "http://www.freder.io/", - "contributions": [] - }, - { - "login": "simplystuart", - "name": "Stuart Dum", - "avatar_url": "https://avatars2.githubusercontent.com/u/1245746?v=4", - "profile": "https://github.com/simplystuart", - "contributions": [] - }, - { - "login": "rdwatters", - "name": "Ryan Watters", - "avatar_url": "https://avatars0.githubusercontent.com/u/8184251?v=4", - "profile": "https://github.com/rdwatters", - "contributions": [] - }, - { - "login": "hsribei", - "name": "Helder S Ribeiro", - "avatar_url": "https://avatars3.githubusercontent.com/u/4315?v=4", - "profile": "https://twitter.com/hsribei", - "contributions": [] - }, - { - "login": "ArtemGovorov", - "name": "Artem Govorov", - "avatar_url": "https://avatars1.githubusercontent.com/u/979966?v=4", - "profile": "http://dm.gl", - "contributions": [] - }, - { - "login": "xuopled", - "name": "Cédric Delpoux", - "avatar_url": "https://avatars3.githubusercontent.com/u/2683300?v=4", - "profile": "http://xuopled.netlify.com/", - "contributions": [] - }, - { - "login": "imorente", - "name": "imorente", - "avatar_url": "https://avatars3.githubusercontent.com/u/83225?v=4", - "profile": "https://github.com/imorente", - "contributions": [] - }, - { - "login": "daddykotex", - "name": "David Francoeur", - "avatar_url": "https://avatars3.githubusercontent.com/u/5230460?v=4", - "profile": "http://davidfrancoeur.com", - "contributions": [] - }, - { - "login": "Rusta", - "name": "Rusta", - "avatar_url": "https://avatars3.githubusercontent.com/u/1954977?v=4", - "profile": "https://github.com/Rusta", - "contributions": [] - }, - { - "login": "hlaueriksson", - "name": "Henrik Lau Eriksson", - "avatar_url": "https://avatars1.githubusercontent.com/u/1299786?v=4", - "profile": "http://henrik.laueriksson.com", - "contributions": [] - }, - { - "login": "KraigWalker", - "name": "Kraig Walker", - "avatar_url": "https://avatars0.githubusercontent.com/u/1294877?v=4", - "profile": "https://www.kraigwalker.com", - "contributions": [] - }, - { - "login": "flaturtha", - "name": "Rich Cook", - "avatar_url": "https://avatars1.githubusercontent.com/u/2994311?v=4", - "profile": "http://www.TalesofMurder.com", - "contributions": [] - }, - { - "login": "damienvdw", - "name": "Damien Van Der Windt", - "avatar_url": "https://avatars3.githubusercontent.com/u/1309950?v=4", - "profile": "https://github.com/damienvdw", - "contributions": [] - }, - { - "login": "mattjared", - "name": "Matt Jared", - "avatar_url": "https://avatars2.githubusercontent.com/u/1571899?v=4", - "profile": "http://mattjared.github.io/", - "contributions": [] - }, - { - "login": "bruce-one", - "name": "bruce-one", - "avatar_url": "https://avatars1.githubusercontent.com/u/1100280?v=4", - "profile": "https://github.com/bruce-one", - "contributions": [] - }, - { - "login": "DirtyF", - "name": "Frank Taillandier", - "avatar_url": "https://avatars3.githubusercontent.com/u/103008?v=4", - "profile": "https://frank.taillandier.me", - "contributions": [ - "doc" - ] - }, - { - "login": "aquibm", - "name": "Aquib Master", - "avatar_url": "https://avatars0.githubusercontent.com/u/2936813?v=4", - "profile": "http://aquibm.com/", - "contributions": [ - "code" - ] - }, - { - "login": "Jinksi", - "name": "Eric Jinks", - "avatar_url": "https://avatars0.githubusercontent.com/u/3147296?v=4", - "profile": "http://ericjinks.com", - "contributions": [ - "code" - ] - }, - { - "login": "talves", - "name": "Tony Alves", - "avatar_url": "https://avatars3.githubusercontent.com/u/784848?v=4", - "profile": "https://github.com/talves", - "contributions": [ - "code" - ] - }, - { - "login": "ebello", - "name": "Ernie Bello", - "avatar_url": "https://avatars3.githubusercontent.com/u/782?v=4", - "profile": "http://ern.me", - "contributions": [ - "bug" - ] - }, - { - "login": "ackushiw", - "name": "Alexander Kushi-Willis", - "avatar_url": "https://avatars3.githubusercontent.com/u/6202476?v=4", - "profile": "https://ackushiw.com", - "contributions": [ - "doc" - ] - }, - { - "login": "igk1972", - "name": "Igor Kuznetsov", - "avatar_url": "https://avatars3.githubusercontent.com/u/54089?v=4", - "profile": "http://www.igk.ru", - "contributions": [ - "bug", - "code", - "plugin" - ] - }, - { - "login": "neutyp", - "name": "Tim Erickson", - "avatar_url": "https://avatars2.githubusercontent.com/u/1312538?v=4", - "profile": "http://neutyp.com", - "contributions": [ - "design" - ] - }, - { - "login": "davidejones", - "name": "David Jones", - "avatar_url": "https://avatars0.githubusercontent.com/u/871552?v=4", - "profile": "http://davidejones.com", - "contributions": [ - "doc" - ] - }, - { - "login": "hcavalieri", - "name": "Henrique Cavalieri", - "avatar_url": "https://avatars0.githubusercontent.com/u/27744332?v=4", - "profile": "https://kaordica.com.br", - "contributions": [ - "doc" - ] - }, - { - "login": "ebernard", - "name": "Etienne Bernard", - "avatar_url": "https://avatars0.githubusercontent.com/u/250958?v=4", - "profile": "https://github.com/ebernard", - "contributions": [ - "doc" - ] - }, - { - "login": "eliwilliamson", - "name": "Eli Williamson", - "avatar_url": "https://avatars3.githubusercontent.com/u/871660?v=4", - "profile": "http://eliwilliamson.com", - "contributions": [ - "code", - "design" - ] - }, - { - "login": "covingtondoan", - "name": "Covington Doan", - "avatar_url": "https://avatars0.githubusercontent.com/u/858837?v=4", - "profile": "https://www.covingtondoan.com", - "contributions": [ - "doc" - ] - }, - { - "login": "ziburski", - "name": "Lennart Ziburski", - "avatar_url": "https://avatars3.githubusercontent.com/u/1299080?v=4", - "profile": "http://lennartziburski.com", - "contributions": [ - "code", - "design", - "doc" - ] - }, - { - "login": "dopry", - "name": "Darrel O'Pry", - "avatar_url": "https://avatars1.githubusercontent.com/u/387640?v=4", - "profile": "http://darrelopry.com", - "contributions": [ - "code", - "infra", - "test" - ] - }, - { - "login": "yourfrienderin", - "name": "Erin Symons", - "avatar_url": "https://avatars1.githubusercontent.com/u/13856868?v=4", - "profile": "https://github.com/yourfrienderin", - "contributions": [ - "doc" - ] - }, - { - "login": "AustinGreen", - "name": "Austin Green", - "avatar_url": "https://avatars0.githubusercontent.com/u/5200555?v=4", - "profile": "https://github.com/AustinGreen", - "contributions": [ - "doc", - "example" - ] - }, - { - "login": "brob", - "name": "Bryan Robinson", - "avatar_url": "https://avatars2.githubusercontent.com/u/799360?v=4", - "profile": "http://bryanlrobinson.com", - "contributions": [ - "doc" - ] - }, - { - "login": "dardub", - "name": "Darren", - "avatar_url": "https://avatars1.githubusercontent.com/u/561983?v=4", - "profile": "https://github.com/dardub", - "contributions": [ - "doc" - ] - }, - { - "login": "rpullinger", - "name": "Richard Pullinger", - "avatar_url": "https://avatars3.githubusercontent.com/u/576512?v=4", - "profile": "http://www.richardpullinger.com", - "contributions": [ - "code" - ] - }, - { - "login": "taylorbryant", - "name": "Taylor Bryant", - "avatar_url": "https://avatars1.githubusercontent.com/u/3718939?v=4", - "profile": "https://taylorbryant.blog", - "contributions": [ - "doc" - ] - }, - { - "login": "kvanerkelens", - "name": "kvanerkelens", - "avatar_url": "https://avatars3.githubusercontent.com/u/5881826?v=4", - "profile": "https://github.com/kvanerkelens", - "contributions": [ - "doc" - ] - }, - { - "login": "pjsier", - "name": "Patrick Sier", - "avatar_url": "https://avatars1.githubusercontent.com/u/8291663?v=4", - "profile": "https://patsier.com/", - "contributions": [ - "code" - ] - }, - { - "login": "drlogout", - "name": "Christian Nolte", - "avatar_url": "https://avatars2.githubusercontent.com/u/6132191?v=4", - "profile": "http://noltech.net", - "contributions": [ - "code" - ] - }, - { - "login": "EdwardBetts", - "name": "Edward Betts", - "avatar_url": "https://avatars1.githubusercontent.com/u/3818?v=4", - "profile": "http://edwardbetts.com/", - "contributions": [ - "doc" - ] - }, - { - "login": "jhardman0830", - "name": "Josh Hardman", - "avatar_url": "https://avatars1.githubusercontent.com/u/8771435?v=4", - "profile": "https://github.com/jhardman0830", - "contributions": [ - "doc" - ] - }, - { - "login": "mistermantas", - "name": "Mantas", - "avatar_url": "https://avatars0.githubusercontent.com/u/11616378?v=4", - "profile": "https://behance.net/mistermantas", - "contributions": [ - "doc" - ] - }, - { - "login": "marcobiedermann", - "name": "Marco Biedermann", - "avatar_url": "https://avatars0.githubusercontent.com/u/5244986?v=4", - "profile": "https://www.marcobiedermann.com", - "contributions": [ - "doc" - ] - }, - { - "login": "mxstbr", - "name": "Max Stoiber", - "avatar_url": "https://avatars0.githubusercontent.com/u/7525670?v=4", - "profile": "https://mxstbr.blog/newsletter", - "contributions": [ - "doc" - ] - }, - { - "login": "berekuk", - "name": "Vyacheslav Matyukhin", - "avatar_url": "https://avatars0.githubusercontent.com/u/89368?v=4", - "profile": "http://berekuk.ru", - "contributions": [ - "doc" - ] - }, - { - "login": "jimmaaay", - "name": "jimmaaay", - "avatar_url": "https://avatars1.githubusercontent.com/u/9059048?v=4", - "profile": "https://jimmythompson.me", - "contributions": [ - "code" - ] - }, - { - "login": "Quicksaver", - "name": "Luís Miguel", - "avatar_url": "https://avatars3.githubusercontent.com/u/802086?v=4", - "profile": "https://github.com/Quicksaver", - "contributions": [ - "bug", - "code" - ] - }, - { - "login": "delucis", - "name": "Chris Swithinbank", - "avatar_url": "https://avatars2.githubusercontent.com/u/357379?v=4", - "profile": "http://chrisswithinbank.net/", - "contributions": [ - "doc", - "code" - ] - }, - { - "login": "remmah", - "name": "remmah", - "avatar_url": "https://avatars3.githubusercontent.com/u/1262221?v=4", - "profile": "https://github.com/remmah", - "contributions": [ - "doc" - ] - }, - { - "login": "sumeetjain", - "name": "Sumeet Jain", - "avatar_url": "https://avatars2.githubusercontent.com/u/29388?v=4", - "profile": "http://sumeetjain.com", - "contributions": [ - "doc" - ] - }, - { - "login": "ragasirtahk", - "name": "Sagar Khatri", - "avatar_url": "https://avatars2.githubusercontent.com/u/26816046?v=4", - "profile": "https://github.com/ragasirtahk", - "contributions": [ - "doc", - "example" - ] - }, - { - "login": "Doocey", - "name": "Kevin Doocey", - "avatar_url": "https://avatars0.githubusercontent.com/u/8182932?v=4", - "profile": "https://www.dooceykev.in", - "contributions": [ - "code" - ] - }, - { - "login": "Swieckowski", - "name": "Swieckowski", - "avatar_url": "https://avatars0.githubusercontent.com/u/31023010?v=4", - "profile": "https://www.linkedin.com/in/arthur-swieckowski/", - "contributions": [ - "code", - "doc", - "test" - ] - }, - { - "login": "pixelastic", - "name": "Tim Carry", - "avatar_url": "https://avatars2.githubusercontent.com/u/283419?v=4", - "profile": "http://www.pixelastic.com/", - "contributions": [ - "code", - "design", - "doc" - ] - }, - { - "login": "solpark", - "name": "Sol Park", - "avatar_url": "https://avatars0.githubusercontent.com/u/30510616?v=4", - "profile": "https://github.com/solpark", - "contributions": [ - "code" - ] - }, - { - "login": "MichaelRomani", - "name": "Michael Romani", - "avatar_url": "https://avatars0.githubusercontent.com/u/29218846?v=4", - "profile": "https://github.com/MichaelRomani", - "contributions": [ - "code" - ] - }, - { - "login": "xifengjin88", - "name": "Xifeng Jin", - "avatar_url": "https://avatars1.githubusercontent.com/u/15175868?v=4", - "profile": "http://linkedin/in/xifengjin88", - "contributions": [ - "bug", - "code" - ] - }, - { - "login": "peduarte", - "name": "Pedro Duarte", - "avatar_url": "https://avatars1.githubusercontent.com/u/372831?v=4", - "profile": "http://pedroduarte.me", - "contributions": [ - "bug", - "code", - "doc" - ] - }, - { - "login": "Strangehill", - "name": "Antonio Argote", - "avatar_url": "https://avatars1.githubusercontent.com/u/6064830?v=4", - "profile": "http://antonioargote.com", - "contributions": [ - "design" - ] - }, - { - "login": "ktaube", - "name": "Kristaps Taube", - "avatar_url": "https://avatars3.githubusercontent.com/u/1479451?v=4", - "profile": "https://www.ktaube.com", - "contributions": [ - "code" - ] - }, - { - "login": "daveyko", - "name": "David Ko", - "avatar_url": "https://avatars3.githubusercontent.com/u/26639499?v=4", - "profile": "https://github.com/daveyko", - "contributions": [ - "code" - ] - }, - { - "login": "igarbla", - "name": "Iñaki García", - "avatar_url": "https://avatars3.githubusercontent.com/u/440562?v=4", - "profile": "http://www.txorua.com", - "contributions": [ - "design" - ] - }, - { - "login": "gazebosx3", - "name": "Sam", - "avatar_url": "https://avatars3.githubusercontent.com/u/27162255?v=4", - "profile": "https://github.com/gazebosx3", - "contributions": [ - "code" - ] - }, - { - "login": "dzello", - "name": "Josh Dzielak", - "avatar_url": "https://avatars1.githubusercontent.com/u/174777?v=4", - "profile": "https://dzello.com", - "contributions": [ - "doc" - ] - }, - { - "login": "jeremybise", - "name": "Jeremy Bise", - "avatar_url": "https://avatars0.githubusercontent.com/u/2193?v=4", - "profile": "http://thosegeeks.com", - "contributions": [ - "doc" - ] - }, - { - "login": "terrierscript", - "name": "terrierscript", - "avatar_url": "https://avatars2.githubusercontent.com/u/13282103?v=4", - "profile": "https://terrierscript.com", - "contributions": [ - "code" - ] - }, - { - "login": "crgeary", - "name": "Christopher Geary", - "avatar_url": "https://avatars0.githubusercontent.com/u/3949335?v=4", - "profile": "https://twitter.com/crgeary", - "contributions": [ - "plugin" - ] - }, - { - "login": "brianlmacdonald", - "name": "Brian Macdonald", - "avatar_url": "https://avatars0.githubusercontent.com/u/23248886?v=4", - "profile": "https://github.com/brianlmacdonald", - "contributions": [ - "code" - ] - }, - { - "login": "jayvdb", - "name": "John Vandenberg", - "avatar_url": "https://avatars1.githubusercontent.com/u/15092?v=4", - "profile": "https://jayvdb.github.io/", - "contributions": [ - "doc" - ] - }, - { - "login": "MarkZither", - "name": "MarkZither", - "avatar_url": "https://avatars2.githubusercontent.com/u/24911956?v=4", - "profile": "https://github.com/MarkZither", - "contributions": [ - "doc" - ] - }, - { - "login": "robphoenix", - "name": "Rob Phoenix", - "avatar_url": "https://avatars1.githubusercontent.com/u/9257284?v=4", - "profile": "https://www.robphoenix.com", - "contributions": [ - "doc" - ] - }, - { - "login": "slathrop", - "name": "Steve Lathrop", - "avatar_url": "https://avatars2.githubusercontent.com/u/3028764?v=4", - "profile": "https://www.SteLa.io", - "contributions": [ - "code", - "doc", - "example" - ] - }, - { - "login": "maciejmatu", - "name": "Maciej Matuszewski", - "avatar_url": "https://avatars0.githubusercontent.com/u/10004167?v=4", - "profile": "https://github.com/maciejmatu", - "contributions": [ - "code" - ] - }, - { - "login": "ekoeryanto", - "name": "Eko Eryanto", - "avatar_url": "https://avatars0.githubusercontent.com/u/36023898?v=4", - "profile": "https://github.com/ekoeryanto", - "contributions": [ - "plugin" - ] - }, - { - "login": "tedmiston", - "name": "Taylor D. Edmiston", - "avatar_url": "https://avatars3.githubusercontent.com/u/366688?v=4", - "profile": "http://blog.tedmiston.com/", - "contributions": [ - "doc" - ] - }, - { - "login": "danielmahon", - "name": "Daniel Mahon", - "avatar_url": "https://avatars2.githubusercontent.com/u/1088089?v=4", - "profile": "https://www.mahonstudios.com", - "contributions": [ - "code" - ] - }, - { - "login": "hennessyevan", - "name": "Evan Hennessy", - "avatar_url": "https://avatars1.githubusercontent.com/u/16711653?v=4", - "profile": "https://www.hennessyevan.com", - "contributions": [ - "plugin" - ] - }, - { - "login": "hasanavi", - "name": "Hasan Azizul Haque", - "avatar_url": "https://avatars1.githubusercontent.com/u/3259517?v=4", - "profile": "https://hasanavi.me", - "contributions": [ - "code", - "doc", - "ideas" - ] - }, - { - "login": "robertkarlsson", - "name": "Robert Karlsson", - "avatar_url": "https://avatars1.githubusercontent.com/u/5166612?v=4", - "profile": "https://github.com/robertkarlsson", - "contributions": [ - "bug" - ] - }, - { - "login": "gil--", - "name": "Gil Greenberg", - "avatar_url": "https://avatars2.githubusercontent.com/u/3484527?v=4", - "profile": "http://gilgreenberg.com", - "contributions": [ - "code" - ] - }, - { - "login": "loremipson", - "name": "Tyler Ipson", - "avatar_url": "https://avatars0.githubusercontent.com/u/649890?v=4", - "profile": "http://loremipson.com", - "contributions": [ - "doc" - ] - }, - { - "login": "growdigital", - "name": "Jake Rayson", - "avatar_url": "https://avatars0.githubusercontent.com/u/1061992?v=4", - "profile": "https://www.growdigital.org/", - "contributions": [ - "code", - "blog", - "example" - ] - }, - { - "login": "mittalyashu", - "name": "Yashu Mittal", - "avatar_url": "https://avatars1.githubusercontent.com/u/29014463?v=4", - "profile": "https://mittalyashu.now.sh/", - "contributions": [ - "doc" - ] - }, - { - "login": "kurtgcollins", - "name": "Kurt collins", - "avatar_url": "https://avatars1.githubusercontent.com/u/42543284?v=4", - "profile": "https://github.com/kurtgcollins", - "contributions": [ - "doc" - ] - }, - { - "login": "cory-wc", - "name": "Cory Williamson-Cardneau", - "avatar_url": "https://avatars2.githubusercontent.com/u/1516558?v=4", - "profile": "http://cory.williamson-cardneau.com", - "contributions": [ - "doc" - ] - }, - { - "login": "cdschroeder", - "name": "Casey Schroeder", - "avatar_url": "https://avatars3.githubusercontent.com/u/31967674?v=4", - "profile": "https://github.com/cdschroeder", - "contributions": [ - "doc" - ] - }, - { - "login": "MitchellCash", - "name": "Mitchell Cash", - "avatar_url": "https://avatars2.githubusercontent.com/u/8009243?v=4", - "profile": "https://mitchellcash.com", - "contributions": [ - "bug", - "doc" - ] - }, - { - "login": "g-hodges", - "name": "Glendon Hodges", - "avatar_url": "https://avatars1.githubusercontent.com/u/22135379?v=4", - "profile": "https://github.com/g-hodges", - "contributions": [ - "doc" - ] - }, - { - "login": "bevanmw", - "name": "Bevan Wentzel", - "avatar_url": "https://avatars0.githubusercontent.com/u/13152809?v=4", - "profile": "https://github.com/bevanmw", - "contributions": [ - "code" - ] - }, - { - "login": "zebapy", - "name": "Zeb Pykosz", - "avatar_url": "https://avatars1.githubusercontent.com/u/2199845?v=4", - "profile": "https://zeb.codes", - "contributions": [ - "doc" - ] - }, - { - "login": "jbutz", - "name": "Jason Butz", - "avatar_url": "https://avatars2.githubusercontent.com/u/736696?v=4", - "profile": "http://www.jasonbutz.info", - "contributions": [ - "code" - ] - } - ], - "repoType": "github" -} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..b7e3201d --- /dev/null +++ b/.eslintignore @@ -0,0 +1,3 @@ +node_modules +dist +dev-test \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 5aaf1615..116dd70c 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -39,7 +39,7 @@ module.exports = { }, ], 'no-duplicate-imports': 'error', - '@emotion/no-vanilla': 'error', + '@emotion/no-vanilla': 'off', '@emotion/import-from-emotion': 'error', '@emotion/styled-import': 'error', 'require-atomic-updates': [0], @@ -51,6 +51,7 @@ module.exports = { }, ], 'unicorn/prefer-string-slice': 'error', + 'react/no-unknown-property': ['error', { ignore: ['css'] }], }, plugins: ['babel', '@emotion', 'cypress', 'unicorn'], settings: { @@ -62,7 +63,7 @@ module.exports = { extensions: ['.js', '.jsx', '.ts', '.tsx'], }, }, - 'import/core-modules': [...packages, 'netlify-cms-app/dist/esm'], + 'import/core-modules': [...packages], }, overrides: [ { diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 0209e106..00000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,8 +0,0 @@ -version = 1 - -[merge.automerge_dependencies] -versions = ["minor", "patch"] -usernames = ["renovate"] - -[approve] -auto_approve_usernames = ["renovate"] \ No newline at end of file diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index e7c9252b..00000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,2 +0,0 @@ -* @netlify/cms-maintainers -website/ @netlify/cms-maintainers @netlify/docs \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 8432e091..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -name: Bug report -about: Report a problem you are experiencing -title: 'Please replace with a clear and descriptive title' -labels: 'type: bug' ---- - - - -**Describe the bug** - - -**To Reproduce** - - -**Expected behavior** - - -**Screenshots** - - -**Applicable Versions:** - - - Netlify CMS version: [e.g. 2.0.4] - - Git provider: [e.g. GitHub, BitBucket] - - OS: [e.g. Windows 7] - - Browser version [e.g. chrome 22, safari 11] - - - Node.JS version: - -**CMS configuration** - - - -**Additional context** - diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index c04deb45..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: 'Please replace with a clear and descriptive title' -labels: 'type: feature' ---- - - - -**Is your feature request related to a problem? Please describe.** - - -**Describe the solution you'd like** - - -**Describe alternatives you've considered** - - -**Additional context** - diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md deleted file mode 100644 index e853c2ff..00000000 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ /dev/null @@ -1,37 +0,0 @@ - - -**Summary** - - - -**Test plan** - - - -**Checklist** - -Please add a `x` inside each checkbox: - -- [ ] I have read the [contribution guidelines](../CONTRIBUTING.md). -- [ ] Code is formatted via running `yarn format`. -- [ ] Tests are passing via running `yarn test`. -- [ ] The status checks are successful (continuous integration). Those can be seen below. - -**A picture of a cute animal (not mandatory but encouraged)** diff --git a/.github/stale.yml b/.github/stale.yml deleted file mode 100644 index 1f0fadf4..00000000 --- a/.github/stale.yml +++ /dev/null @@ -1,17 +0,0 @@ -# Number of days of inactivity before an issue becomes stale -daysUntilStale: 60 -# Number of days of inactivity before a stale issue is closed -daysUntilClose: 14 -# Issues with these labels will never be considered stale -exemptLabels: - - pinned - - security -# Label to use when marking an issue as stale -staleLabel: 'status: stale' -# Comment to post when marking an issue as stale. Set to `false` to disable -markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. -# Comment to post when closing a stale issue. Set to `false` to disable -closeComment: false diff --git a/.github/workflows/create-release.yml b/.github/workflows/create-release.yml deleted file mode 100644 index c24da596..00000000 --- a/.github/workflows/create-release.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Create release - -on: - create - -jobs: - create-release: - name: Create GitHub Release - runs-on: ubuntu-latest - if: startsWith(github.ref, 'refs/tags/netlify-cms@') - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Get semver number - id: get_semver - env: - TAG_NAME: ${{ github.ref }} - run: echo "::set-output name=pkg::${TAG_NAME:10}" - - - name: Create release on GitHub API - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - release_name: ${{ steps.get_semver.outputs.pkg }} - body: | - :scroll: [Changelog](https://github.com/${{ github.repository }}/blob/${{ steps.get_semver.outputs.pkg }}/CHANGELOG.md) - draft: false - prerelease: false diff --git a/.github/workflows/docslint.yml b/.github/workflows/docslint.yml deleted file mode 100644 index 5cf9944c..00000000 --- a/.github/workflows/docslint.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: 'Docs Linting:' -on: - push: - branches: - - master - - paths: - - '.github/workflows/docslint.yml' - - 'website/**' - - pull_request: - types: [opened, synchronize, reopened] - - paths: - - '.github/workflows/docslint.yml' - - 'website/**' - -jobs: - Prose: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Vale Linter - uses: errata-ai/vale-action@0dec3032fa59c4097deece7cf6ee3261b27bb3f1 - with: - # Optional - files: website/content/docs - env: - # Required - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/fossa.yml b/.github/workflows/fossa.yml deleted file mode 100644 index 63d29b45..00000000 --- a/.github/workflows/fossa.yml +++ /dev/null @@ -1,36 +0,0 @@ -name: Dependency License Scanning - -on: - push: - branches: - - master - - chore/fossa-workflow - -defaults: - run: - shell: bash - -jobs: - fossa: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Download fossa cli - run: |- - mkdir -p $HOME/.local/bin - curl https://raw.githubusercontent.com/fossas/fossa-cli/master/install.sh | bash -s -- -b $HOME/.local/bin - echo "$HOME/.local/bin" >> $GITHUB_PATH - - - name: Fossa init - run: fossa init - - name: Set env - run: echo "line_number=$(grep -n "project" .fossa.yml | cut -f1 -d:)" >> $GITHUB_ENV - - name: Configuration - run: |- - sed -i "${line_number}s|.*| project: git@github.com:${GITHUB_REPOSITORY}.git|" .fossa.yml - cat .fossa.yml - - name: Upload dependencies - run: fossa analyze --debug - env: - FOSSA_API_KEY: ${{ secrets.FOSSA_API_KEY }} diff --git a/.github/workflows/labeler.yml b/.github/workflows/labeler.yml deleted file mode 100644 index 0cac4afe..00000000 --- a/.github/workflows/labeler.yml +++ /dev/null @@ -1,30 +0,0 @@ -name: Label PR -on: - pull_request: - types: [opened, edited] - -jobs: - label-pr: - if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == false - runs-on: ubuntu-latest - steps: - - uses: netlify/pr-labeler-action@v1.0.0 - if: startsWith(github.event.pull_request.title, 'fix') - with: - token: '${{ secrets.GITHUB_TOKEN }}' - label: 'type: bug' - - uses: netlify/pr-labeler-action@v1.0.0 - if: startsWith(github.event.pull_request.title, 'chore') - with: - token: '${{ secrets.GITHUB_TOKEN }}' - label: 'type: chore' - - uses: netlify/pr-labeler-action@v1.0.0 - if: startsWith(github.event.pull_request.title, 'feat') - with: - token: '${{ secrets.GITHUB_TOKEN }}' - label: 'type: feature' - - uses: netlify/pr-labeler-action@v1.0.0 - if: startsWith(github.event.pull_request.title, 'security') - with: - token: '${{ secrets.GITHUB_TOKEN }}' - label: 'type: security' diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml deleted file mode 100644 index 8449c449..00000000 --- a/.github/workflows/nodejs.yml +++ /dev/null @@ -1,108 +0,0 @@ -name: Node CI - -on: - push: - branches: - - master - pull_request: - types: [opened, synchronize, reopened] - -jobs: - changes: - runs-on: ubuntu-latest - outputs: - cms: ${{ steps.filter.outputs.cms }} - steps: - - uses: actions/checkout@v3 - - uses: dorny/paths-filter@v2 - id: filter - with: - filters: | - cms: - - '!website/**' - build: - needs: changes - runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-latest, windows-latest, ubuntu-latest] - steps: - - uses: actions/checkout@v3 - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '*' - check-latest: true - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: log versions - run: node --version && npm --version && yarn --version - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: install dependecies - run: yarn --frozen-lockfile --network-timeout 1000000 && yarn bootstrap - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: run unit tests - run: yarn test:ci - env: - CI: true - NODE_OPTIONS: --max-old-space-size=4096 - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: build demo site - run: yarn build:demo - env: - NODE_OPTIONS: --max-old-space-size=4096 - if: ${{ needs.changes.outputs.cms == 'true' }} - - uses: actions/upload-artifact@master - with: - name: dev-test-website-${{ runner.os }} - path: dev-test - if: ${{ needs.changes.outputs.cms == 'true' }} - - e2e-with-cypress: - needs: [changes, build] - runs-on: ubuntu-latest - - strategy: - matrix: - machine: [1, 2, 3, 4, 5, 6, 7, 8] - fail-fast: false - - steps: - - uses: actions/checkout@v3 - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: Use Node.js - uses: actions/setup-node@v3 - with: - node-version: '*' - check-latest: true - cache: yarn - if: ${{ needs.changes.outputs.cms == 'true' }} - - uses: actions/download-artifact@master - with: - name: dev-test-website-${{ runner.os }} - path: dev-test - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: npm install - run: | - node --version - npm --version - yarn --version - yarn --frozen-lockfile - if: ${{ needs.changes.outputs.cms == 'true' }} - - name: e2e test - run: | - yarn test:e2e:run-ci - env: - IS_FORK: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.fork == true }} - CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} - NODE_OPTIONS: --max-old-space-size=4096 - MACHINE_COUNT: 8 - MACHINE_INDEX: ${{ matrix.machine }} - if: ${{ needs.changes.outputs.cms == 'true' }} - - uses: actions/upload-artifact@v3 - if: ${{ always() && needs.changes.outputs.cms == 'true' }} - with: - name: cypress-results-${{ matrix.machine }} - path: | - cypress/screenshots - cypress/videos diff --git a/.gitignore b/.gitignore index c01d7940..938403c3 100644 --- a/.gitignore +++ b/.gitignore @@ -19,5 +19,5 @@ coverage/ *.log .env .temp/ -storybook-static/ *.tgz +content diff --git a/.prettierignore b/.prettierignore index 3b3bb211..485fb2a0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,5 +1,4 @@ dist/ bin/ public/ -.cache/ -packages/netlify-cms-backend-github/src/fragmentTypes.js \ No newline at end of file +.cache/ \ No newline at end of file diff --git a/.storybook/main.js b/.storybook/main.js deleted file mode 100644 index 4f5fd28e..00000000 --- a/.storybook/main.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - stories: [ - '../packages/netlify-cms-core/src/**/*.stories.js', - '../packages/netlify-cms-ui-default/src/**/*.stories.js', - ], - addons: ['@storybook/addon-actions', '@storybook/addon-links'], -}; diff --git a/.stylelintrc b/.stylelintrc index 135a0fcf..5db28b50 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -29,6 +29,5 @@ "lower", { "ignoreKeywords": ["dummyValue"], "camelCaseSvgKeywords": true } ] - }, - "ignoreFiles": ["packages/netlify-cms-lib-auth/index.d.ts"] + } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 31493a9a..3cb0a967 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,36 +6,6 @@ below. The legacy pre-2.0 changelog is below as well. - [netlify-cms](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms/CHANGELOG.md) - [netlify-cms-core](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-core/CHANGELOG.md) -## Shared libraries -- [netlify-cms-lib-auth](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-lib-auth/CHANGELOG.md) -- [netlify-cms-lib-util](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-lib-util/CHANGELOG.md) -- [netlify-cms-ui-default](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-ui-default/CHANGELOG.md) - -## Backends -- [netlify-cms-backend-bitbucket](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-backend-bitbucket/CHANGELOG.md) -- [netlify-cms-backend-git-gateway](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-backend-git-gateway/CHANGELOG.md) -- [netlify-cms-backend-github](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-backend-github/CHANGELOG.md) -- [netlify-cms-backend-gitlab](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-backend-gitlab/CHANGELOG.md) -- [netlify-cms-backend-test](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-backend-test/CHANGELOG.md) - -## Editor Components -- [netlify-cms-editor-component-image](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-editor-component-image/CHANGELOG.md) - -## Widgets -- [netlify-cms-widget-boolean](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-boolean/CHANGELOG.md) -- [netlify-cms-widget-date](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-date/CHANGELOG.md) -- [netlify-cms-widget-datetime](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-datetime/CHANGELOG.md) -- [netlify-cms-widget-file](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-file/CHANGELOG.md) -- [netlify-cms-widget-image](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-image/CHANGELOG.md) -- [netlify-cms-widget-list](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-list/CHANGELOG.md) -- [netlify-cms-widget-markdown](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-markdown/CHANGELOG.md) -- [netlify-cms-widget-number](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-number/CHANGELOG.md) -- [netlify-cms-widget-object](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-object/CHANGELOG.md) -- [netlify-cms-widget-relation](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-relation/CHANGELOG.md) -- [netlify-cms-widget-select](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-select/CHANGELOG.md) -- [netlify-cms-widget-string](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-string/CHANGELOG.md) -- [netlify-cms-widget-text](https://github.com/netlify/netlify-cms/blob/master/packages/netlify-cms-widget-text/CHANGELOG.md) - ## Legacy Changelog ## [Unreleased] ([demo](https://cms-demo.netlify.com/)) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index da31ce23..37b96953 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -164,7 +164,7 @@ backend: Netlify CMS - + - - - - - - - - - -``` - -Install via npm: - -``` -npm i react react-dom netlify-cms-app -``` - -```js -import CMS from 'netlify-cms-app'; - -CMS.init(); -``` diff --git a/packages/netlify-cms-app/index.d.ts b/packages/netlify-cms-app/index.d.ts deleted file mode 100644 index df777604..00000000 --- a/packages/netlify-cms-app/index.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -declare module 'netlify-cms-app' { - import type { CMS } from 'netlify-cms-core'; - - export const NetlifyCmsApp: CMS; - - export default NetlifyCmsApp; -} diff --git a/packages/netlify-cms-app/package.json b/packages/netlify-cms-app/package.json deleted file mode 100644 index a16e2a0c..00000000 --- a/packages/netlify-cms-app/package.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "name": "netlify-cms-app", - "description": "An extensible, open source, Git-based, React CMS for static sites. Reusable congiuration with React as peer.", - "version": "2.15.108", - "homepage": "https://www.netlifycms.org", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-app", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "main": "dist/netlify-cms-app.js", - "files": [ - "src/", - "dist/", - "index.d.ts" - ], - "types": "index.d.ts", - "scripts": { - "develop": "yarn build:esm --watch", - "webpack": "node --max_old_space_size=4096 ../../node_modules/webpack/bin/webpack.js", - "build": "cross-env NODE_ENV=production run-s webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "keywords": [ - "netlify", - "cms", - "content editing", - "static site generators", - "jamstack" - ], - "license": "MIT", - "dependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "codemirror": "^5.46.0", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "netlify-cms-backend-azure": "^1.3.3", - "netlify-cms-backend-bitbucket": "^2.14.2", - "netlify-cms-backend-git-gateway": "^2.13.4", - "netlify-cms-backend-github": "^2.14.3", - "netlify-cms-backend-gitlab": "^2.13.2", - "netlify-cms-backend-proxy": "^1.2.5", - "netlify-cms-backend-test": "^2.11.5", - "netlify-cms-core": "^2.55.36", - "netlify-cms-editor-component-image": "^2.7.0", - "netlify-cms-lib-auth": "^2.4.2", - "netlify-cms-lib-util": "^2.15.3", - "netlify-cms-lib-widgets": "^1.8.1", - "netlify-cms-locales": "^1.39.0", - "netlify-cms-ui-default": "^2.15.21", - "netlify-cms-widget-boolean": "^2.4.3", - "netlify-cms-widget-code": "^1.3.6", - "netlify-cms-widget-colorstring": "^1.1.4", - "netlify-cms-widget-date": "^2.6.5", - "netlify-cms-widget-datetime": "^2.7.6", - "netlify-cms-widget-file": "^2.12.5", - "netlify-cms-widget-image": "^2.8.3", - "netlify-cms-widget-list": "^2.10.3", - "netlify-cms-widget-map": "^1.5.3", - "netlify-cms-widget-markdown": "^2.15.3", - "netlify-cms-widget-number": "^2.5.0", - "netlify-cms-widget-object": "^2.7.4", - "netlify-cms-widget-relation": "^2.11.3", - "netlify-cms-widget-select": "^2.8.2", - "netlify-cms-widget-string": "^2.3.0", - "netlify-cms-widget-text": "^2.4.1", - "prop-types": "^15.7.2", - "react-immutable-proptypes": "^2.1.0", - "uuid": "^3.3.2" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - }, - "incrementToForceBump": 2 -} diff --git a/packages/netlify-cms-app/src/extensions.js b/packages/netlify-cms-app/src/extensions.js deleted file mode 100644 index c09f1a9b..00000000 --- a/packages/netlify-cms-app/src/extensions.js +++ /dev/null @@ -1,74 +0,0 @@ -import React from 'react'; -// Core -import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -// Backends -import { AzureBackend } from 'netlify-cms-backend-azure'; -import { GitHubBackend } from 'netlify-cms-backend-github'; -import { GitLabBackend } from 'netlify-cms-backend-gitlab'; -import { GitGatewayBackend } from 'netlify-cms-backend-git-gateway'; -import { BitbucketBackend } from 'netlify-cms-backend-bitbucket'; -import { TestBackend } from 'netlify-cms-backend-test'; -import { ProxyBackend } from 'netlify-cms-backend-proxy'; -// Widgets -import NetlifyCmsWidgetString from 'netlify-cms-widget-string'; -import NetlifyCmsWidgetNumber from 'netlify-cms-widget-number'; -import NetlifyCmsWidgetText from 'netlify-cms-widget-text'; -import NetlifyCmsWidgetImage from 'netlify-cms-widget-image'; -import NetlifyCmsWidgetFile from 'netlify-cms-widget-file'; -import NetlifyCmsWidgetSelect from 'netlify-cms-widget-select'; -import NetlifyCmsWidgetMarkdown from 'netlify-cms-widget-markdown'; -import NetlifyCmsWidgetList from 'netlify-cms-widget-list'; -import NetlifyCmsWidgetObject from 'netlify-cms-widget-object'; -import NetlifyCmsWidgetRelation from 'netlify-cms-widget-relation'; -import NetlifyCmsWidgetBoolean from 'netlify-cms-widget-boolean'; -import NetlifyCmsWidgetMap from 'netlify-cms-widget-map'; -import NetlifyCmsWidgetDate from 'netlify-cms-widget-date'; -import NetlifyCmsWidgetDatetime from 'netlify-cms-widget-datetime'; -import NetlifyCmsWidgetCode from 'netlify-cms-widget-code'; -import NetlifyCmsWidgetColorString from 'netlify-cms-widget-colorstring'; -// Editor Components -import image from 'netlify-cms-editor-component-image'; -// Locales -import * as locales from 'netlify-cms-locales'; -import { images, Icon } from 'netlify-cms-ui-default'; - -// Register all the things -CMS.registerBackend('git-gateway', GitGatewayBackend); -CMS.registerBackend('azure', AzureBackend); -CMS.registerBackend('github', GitHubBackend); -CMS.registerBackend('gitlab', GitLabBackend); -CMS.registerBackend('bitbucket', BitbucketBackend); -CMS.registerBackend('test-repo', TestBackend); -CMS.registerBackend('proxy', ProxyBackend); -CMS.registerWidget([ - NetlifyCmsWidgetString.Widget(), - NetlifyCmsWidgetNumber.Widget(), - NetlifyCmsWidgetText.Widget(), - NetlifyCmsWidgetImage.Widget(), - NetlifyCmsWidgetFile.Widget(), - NetlifyCmsWidgetSelect.Widget(), - NetlifyCmsWidgetMarkdown.Widget(), - NetlifyCmsWidgetList.Widget(), - NetlifyCmsWidgetObject.Widget(), - NetlifyCmsWidgetRelation.Widget(), - NetlifyCmsWidgetBoolean.Widget(), - NetlifyCmsWidgetMap.Widget(), - NetlifyCmsWidgetDate.Widget(), - NetlifyCmsWidgetDatetime.Widget(), - NetlifyCmsWidgetCode.Widget(), - NetlifyCmsWidgetColorString.Widget(), -]); -CMS.registerEditorComponent(image); -CMS.registerEditorComponent({ - id: 'code-block', - label: 'Code Block', - widget: 'code', - type: 'code-block', -}); -Object.keys(locales).forEach(locale => { - CMS.registerLocale(locale, locales[locale]); -}); - -Object.keys(images).forEach(iconName => { - CMS.registerIcon(iconName, ); -}); diff --git a/packages/netlify-cms-app/src/index.js b/packages/netlify-cms-app/src/index.js deleted file mode 100644 index 316e8daf..00000000 --- a/packages/netlify-cms-app/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -import moment from 'moment'; -import './extensions.js'; - -// Log version -if (typeof window !== 'undefined') { - if (typeof NETLIFY_CMS_APP_VERSION === 'string') { - console.log(`netlify-cms-app ${NETLIFY_CMS_APP_VERSION}`); - } -} - -export const NetlifyCmsApp = { - ...CMS, - moment, -}; -export default CMS; diff --git a/packages/netlify-cms-app/src/locales.js b/packages/netlify-cms-app/src/locales.js deleted file mode 100644 index 51f7c759..00000000 --- a/packages/netlify-cms-app/src/locales.js +++ /dev/null @@ -1,4 +0,0 @@ -import { NetlifyCmsCore as CMS } from 'netlify-cms-core'; -import { en } from 'netlify-cms-locales'; - -CMS.registerLocale('en', en); diff --git a/packages/netlify-cms-app/webpack.config.js b/packages/netlify-cms-app/webpack.config.js deleted file mode 100644 index 511a53ae..00000000 --- a/packages/netlify-cms-app/webpack.config.js +++ /dev/null @@ -1,22 +0,0 @@ -const webpack = require('webpack'); - -const pkg = require('./package.json'); -const { getConfig, plugins } = require('../../scripts/webpack'); -const baseWebpackConfig = getConfig({ baseOnly: true }); - -const isProduction = process.env.NODE_ENV === 'production'; -console.log(`${pkg.version}${isProduction ? '' : '-dev'}`); - -const baseConfig = { - ...baseWebpackConfig, - plugins: [ - ...Object.entries(plugins) - .filter(([key]) => key !== 'friendlyErrors') - .map(([, plugin]) => plugin()), - new webpack.DefinePlugin({ - NETLIFY_CMS_APP_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), - }), - ], -}; - -module.exports = baseConfig; diff --git a/packages/netlify-cms-backend-azure/CHANGELOG.md b/packages/netlify-cms-backend-azure/CHANGELOG.md deleted file mode 100644 index 1b7b5182..00000000 --- a/packages/netlify-cms-backend-azure/CHANGELOG.md +++ /dev/null @@ -1,89 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.3.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-azure@1.3.2...netlify-cms-backend-azure@1.3.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -## [1.3.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-azure@1.3.1...netlify-cms-backend-azure@1.3.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -## [1.3.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-azure@1.3.0...netlify-cms-backend-azure@1.3.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-azure@1.2.2...netlify-cms-backend-azure@1.3.0) (2021-10-18) - - -### Features - -* display author of changes in workflow tab ([#5780](https://github.com/netlify/netlify-cms/issues/5780)) ([3f607e4](https://github.com/netlify/netlify-cms/commit/3f607e41d9c4d8fe5329a9ab6841cada7742825e)) - - - - - -## [1.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/compare/netlify-cms-backend-azure@1.2.1...netlify-cms-backend-azure@1.2.2) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -## [1.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/compare/netlify-cms-backend-azure@1.2.0...netlify-cms-backend-azure@1.2.1) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/compare/netlify-cms-backend-azure@1.1.2...netlify-cms-backend-azure@1.2.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [1.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/compare/netlify-cms-backend-azure@1.1.1...netlify-cms-backend-azure@1.1.2) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -## [1.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/compare/netlify-cms-backend-azure@1.1.0...netlify-cms-backend-azure@1.1.1) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-azure - - - - - -# 1.1.0 (2020-11-26) - - -### Features - -* add azure devops backend ([#4427](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/issues/4427)) ([4e6dc88](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure/commit/4e6dc88efb1dae4cf6137730c3b4fb6d0f75a8cc)) diff --git a/packages/netlify-cms-backend-azure/README.md b/packages/netlify-cms-backend-azure/README.md deleted file mode 100644 index 78bbc746..00000000 --- a/packages/netlify-cms-backend-azure/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Azure backend - -An abstraction layer between the CMS and [Azure DevOps](https://docs.microsoft.com/en-us/rest/api/azure/devops/git/) - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on `Api`. - -`Api` - A wrapper for Azure DevOps REST API. - -`AuthenticationPage` - facilitates implicit authentication flow. Uses [lib-auth](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/README.md). - -Look at tests or types for more info. diff --git a/packages/netlify-cms-backend-azure/package.json b/packages/netlify-cms-backend-azure/package.json deleted file mode 100644 index 0689a073..00000000 --- a/packages/netlify-cms-backend-azure/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "netlify-cms-backend-azure", - "description": "Azure DevOps backend for Netlify CMS", - "version": "1.3.3", - "license": "MIT", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-azure", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-azure.js", - "keywords": [ - "netlify", - "netlify-cms", - "backend", - "azure", - "devops" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore **/__tests__ --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "dependencies": { - "js-base64": "^3.0.0", - "semaphore": "^1.1.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-azure/webpack.config.js b/packages/netlify-cms-backend-azure/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-azure/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-bitbucket/CHANGELOG.md b/packages/netlify-cms-backend-bitbucket/CHANGELOG.md deleted file mode 100644 index b06cf0d0..00000000 --- a/packages/netlify-cms-backend-bitbucket/CHANGELOG.md +++ /dev/null @@ -1,570 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.14.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-bitbucket@2.14.1...netlify-cms-backend-bitbucket@2.14.2) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.14.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-bitbucket@2.14.0...netlify-cms-backend-bitbucket@2.14.1) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.14.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-bitbucket@2.13.3...netlify-cms-backend-bitbucket@2.14.0) (2021-10-18) - - -### Features - -* display author of changes in workflow tab ([#5780](https://github.com/netlify/netlify-cms/issues/5780)) ([3f607e4](https://github.com/netlify/netlify-cms/commit/3f607e41d9c4d8fe5329a9ab6841cada7742825e)) - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.13.2...netlify-cms-backend-bitbucket@2.13.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.13.1...netlify-cms-backend-bitbucket@2.13.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.13.0...netlify-cms-backend-bitbucket@2.13.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.8...netlify-cms-backend-bitbucket@2.13.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.12.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.7...netlify-cms-backend-bitbucket@2.12.8) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.12.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.6...netlify-cms-backend-bitbucket@2.12.7) (2021-02-15) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.12.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.5...netlify-cms-backend-bitbucket@2.12.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.12.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.4...netlify-cms-backend-bitbucket@2.12.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.12.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.12.3...netlify-cms-backend-bitbucket@2.12.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## 2.12.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.12.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.12.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.5...netlify-cms-backend-bitbucket@2.12.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) -* **backend-gitgateway:** improve deploy preview visibility ([#3882](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3882)) ([afc9bf4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/afc9bf4f3fe14ccb60851fc24e68922a6e4a85a9)) - - - - - -## [2.11.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.4...netlify-cms-backend-bitbucket@2.11.5) (2020-05-19) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.11.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.3...netlify-cms-backend-bitbucket@2.11.4) (2020-04-21) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.11.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.2...netlify-cms-backend-bitbucket@2.11.3) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.11.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.1...netlify-cms-backend-bitbucket@2.11.2) (2020-03-20) - - -### Bug Fixes - -* missing workflow timestamp ([#3445](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3445)) ([9616cdb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/9616cdb8bb0a564771e5755bcd3718a07f2e2072)) - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.11.0...netlify-cms-backend-bitbucket@2.11.1) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.10.1...netlify-cms-backend-bitbucket@2.11.0) (2020-02-25) - - -### Features - -* **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3316)) ([7e0a8ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3292) - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.10.0...netlify-cms-backend-bitbucket@2.10.1) (2020-02-22) - - -### Reverts - -* Revert "feat(core): Align GitHub metadata handling with other backends (#3292)" ([5bdd3df](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3292) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.9.0...netlify-cms-backend-bitbucket@2.10.0) (2020-02-22) - - -### Features - -* **core:** Align GitHub metadata handling with other backends ([#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3292)) ([8193b5a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/8193b5ace89d6f14a6c756235a50b186a763b6b1)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.8.1...netlify-cms-backend-bitbucket@2.9.0) (2020-02-10) - - -### Bug Fixes - -* filter paginated results ([#3216](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3216)) ([0a482b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/0a482b10049bcfa022b81165cabf4512d77e0b88)) -* workflow file collection ([#3207](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3207)) ([d22f7e6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/d22f7e680e7064e8607cf8b420571fa40a6c314e)) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.8.0...netlify-cms-backend-bitbucket@2.8.1) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.7.2...netlify-cms-backend-bitbucket@2.8.0) (2020-01-21) - - -### Features - -* **backend-bitbucket:** Add Git-LFS support ([#3118](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3118)) ([a48c02d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/a48c02d852ca5e11055da3a14cefae8d17a68498)) - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.7.1...netlify-cms-backend-bitbucket@2.7.2) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.7.0...netlify-cms-backend-bitbucket@2.7.1) (2020-01-09) - - -### Bug Fixes - -* **backend-bitbucket:** fix media library not loaded on BitBucket ([#3059](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/3059)) ([8849c0e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/8849c0ea5777ee0eb85375d6e4a74d7f956c77ee)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.7.0-beta.0...netlify-cms-backend-bitbucket@2.7.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.7.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.6.0...netlify-cms-backend-bitbucket@2.7.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.6.0-beta.1...netlify-cms-backend-bitbucket@2.6.0) (2019-12-18) - - -### Bug Fixes - -* **backend-bitbucket:** 404 for new entry ([#2976](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2976)) ([20851fe](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/20851fe7eae0487484e775c9cb219d1aa973e878)) - - - - - -# [2.6.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.6.0-beta.0...netlify-cms-backend-bitbucket@2.6.0-beta.1) (2019-12-16) - - -### Bug Fixes - -* **bitbucket:** branchname containing slash ([#2963](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2963)) ([afea448](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/afea44895b9ef7379f5a8726a60fb4d371c76ebf)) - - - - - -# [2.6.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.5.0...netlify-cms-backend-bitbucket@2.6.0-beta.0) (2019-12-02) - - -### Features - -* content in sub folders ([#2897](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2897)) ([afcfe5b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/afcfe5b6d5f32669e9061ec596bd35ad545d61a3)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.4.2...netlify-cms-backend-bitbucket@2.5.0) (2019-11-07) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) -* enable specifying custom open authoring commit message ([#2810](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2810)) ([2841ff9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/2841ff9ffe58afcf4dba45514a84a262ad370f1d)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.4.1...netlify-cms-backend-bitbucket@2.4.2) (2019-09-26) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.4.0...netlify-cms-backend-bitbucket@2.4.1) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.4.0-beta.0...netlify-cms-backend-bitbucket@2.4.0) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.4.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.3.1...netlify-cms-backend-bitbucket@2.4.0-beta.0) (2019-04-05) - - -### Features - -* **backend-bitbucket:** add implicit auth ([#2247](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2247)) ([54fde06](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/54fde06)) - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.3.1-beta.1...netlify-cms-backend-bitbucket@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.3.1-beta.0...netlify-cms-backend-bitbucket@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.3.0...netlify-cms-backend-bitbucket@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.2.0...netlify-cms-backend-bitbucket@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.2.0-beta.0...netlify-cms-backend-bitbucket@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.1.3-beta.0...netlify-cms-backend-bitbucket@2.2.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/82cc794)) - - - - - -## [2.1.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.1.2...netlify-cms-backend-bitbucket@2.1.3-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/ccef446)) - - - - - -## [2.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.1.1...netlify-cms-backend-bitbucket@2.1.2) (2019-03-08) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.1.0...netlify-cms-backend-bitbucket@2.1.1) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.7...netlify-cms-backend-bitbucket@2.1.0) (2018-11-12) - - -### Features - -* allow custom logo on auth page ([#1818](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/1818)) ([c6ae1e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/c6ae1e8)) - - - - - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.6...netlify-cms-backend-bitbucket@2.0.7) (2018-09-06) - - -### Bug Fixes - -* **bitbucket:** setting site_id for BitBucket auth ([#1660](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/1660)) ([d139ac4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/d139ac4)) - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.5...netlify-cms-backend-bitbucket@2.0.6) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.4...netlify-cms-backend-bitbucket@2.0.5) (2018-08-24) - - -### Bug Fixes - -* **gitlab:** fetch media library images through API ([#1433](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/1433)) ([83d2adc](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/83d2adc)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.3...netlify-cms-backend-bitbucket@2.0.4) (2018-08-07) - - -### Bug Fixes - -* **backends:** fix commit message handling ([#1568](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/issues/1568)) ([f7e7120](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/commit/f7e7120)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.2...netlify-cms-backend-bitbucket@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket/compare/netlify-cms-backend-bitbucket@2.0.1...netlify-cms-backend-bitbucket@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-backend-bitbucket - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - -### Bug Fixes - -* **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/netlify/netlify-cms/issues/1522)) ([bdfd944](https://github.com/netlify/netlify-cms/commit/bdfd944)) diff --git a/packages/netlify-cms-backend-bitbucket/README.md b/packages/netlify-cms-backend-bitbucket/README.md deleted file mode 100644 index 6c01511e..00000000 --- a/packages/netlify-cms-backend-bitbucket/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Bitbucket backend - -An abstraction layer between the CMS and [Bitbucket](https://docs.microsoft.com/en-us/rest/api/azure/devops/git/) - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on `Api` and `LargeMedia(LFS)`. With [Editorial Workflow](https://www.netlifycms.org/docs/beta-features/#gitlab-and-bitbucket-editorial-workflow-support) uses pull requests comments to track unpublished entries statuses. - -`Api` - A wrapper for Bitbucket REST API. - -`AuthenticationPage` - uses [lib-auth](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/README.md) to facilitate OAuth and implicit authentication. - -Look at tests or types for more info. diff --git a/packages/netlify-cms-backend-bitbucket/package.json b/packages/netlify-cms-backend-bitbucket/package.json deleted file mode 100644 index 8b8add85..00000000 --- a/packages/netlify-cms-backend-bitbucket/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "netlify-cms-backend-bitbucket", - "description": "Bitbucket backend for Netlify CMS", - "version": "2.14.2", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbucket", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-bitbucket.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "backend", - "bitbucket" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "dependencies": { - "common-tags": "^1.8.0", - "js-base64": "^3.0.0", - "semaphore": "^1.1.0", - "what-the-diff": "^0.6.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-bitbucket/src/__tests__/api.spec.js b/packages/netlify-cms-backend-bitbucket/src/__tests__/api.spec.js deleted file mode 100644 index 0237ff3f..00000000 --- a/packages/netlify-cms-backend-bitbucket/src/__tests__/api.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import API from '../API'; - -global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests')); - -describe('bitbucket API', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - test('should get preview statuses', async () => { - const api = new API({}); - - const pr = { id: 1 }; - const statuses = [ - { key: 'deploy', state: 'SUCCESSFUL', url: 'deploy-url' }, - { key: 'build', state: 'FAILED' }, - ]; - - api.getBranchPullRequest = jest.fn(() => Promise.resolve(pr)); - api.getPullRequestStatuses = jest.fn(() => Promise.resolve(statuses)); - - const collectionName = 'posts'; - const slug = 'title'; - await expect(api.getStatuses(collectionName, slug)).resolves.toEqual([ - { context: 'deploy', state: 'success', target_url: 'deploy-url' }, - { context: 'build', state: 'other' }, - ]); - - expect(api.getBranchPullRequest).toHaveBeenCalledTimes(1); - expect(api.getBranchPullRequest).toHaveBeenCalledWith(`cms/posts/title`); - - expect(api.getPullRequestStatuses).toHaveBeenCalledTimes(1); - expect(api.getPullRequestStatuses).toHaveBeenCalledWith(pr); - }); -}); diff --git a/packages/netlify-cms-backend-bitbucket/webpack.config.js b/packages/netlify-cms-backend-bitbucket/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-bitbucket/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-git-gateway/CHANGELOG.md b/packages/netlify-cms-backend-git-gateway/CHANGELOG.md deleted file mode 100644 index 8c1173f6..00000000 --- a/packages/netlify-cms-backend-git-gateway/CHANGELOG.md +++ /dev/null @@ -1,725 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.13.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-git-gateway@2.13.3...netlify-cms-backend-git-gateway@2.13.4) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-git-gateway@2.13.2...netlify-cms-backend-git-gateway@2.13.3) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-git-gateway@2.13.1...netlify-cms-backend-git-gateway@2.13.2) (2022-09-20) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-git-gateway@2.13.0...netlify-cms-backend-git-gateway@2.13.1) (2022-03-08) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-git-gateway@2.12.2...netlify-cms-backend-git-gateway@2.13.0) (2021-12-28) - - -### Bug Fixes - -* **netlify-cms-ui-default:** use grayDark for button ([#6069](https://github.com/netlify/netlify-cms/issues/6069)) ([ad85514](https://github.com/netlify/netlify-cms/commit/ad85514cba607f066ab7071bee5932b2192466ee)), closes [/github.com/netlify/netlify-cms/issues/1333#issuecomment-998115794](https://github.com//github.com/netlify/netlify-cms/issues/1333/issues/issuecomment-998115794) - - -### Features - -* **backend-gitlab:** initial GraphQL support ([#6059](https://github.com/netlify/netlify-cms/issues/6059)) ([1523a41](https://github.com/netlify/netlify-cms/commit/1523a4140a3d2f4cc01a1548514ae17bc1ad504e)) -* disable 'Save' button when there are no changes ([#5595](https://github.com/netlify/netlify-cms/issues/5595)) ([4b566a7](https://github.com/netlify/netlify-cms/commit/4b566a78f4282a6f04caf3deafaaac4d74acfd63)) - - - - - -## [2.12.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.12.1...netlify-cms-backend-git-gateway@2.12.2) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.12.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.12.0...netlify-cms-backend-git-gateway@2.12.1) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.11...netlify-cms-backend-git-gateway@2.12.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.11.11](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.10...netlify-cms-backend-git-gateway@2.11.11) (2021-02-25) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.11.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.9...netlify-cms-backend-git-gateway@2.11.10) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.11.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.8...netlify-cms-backend-git-gateway@2.11.9) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.11.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.7...netlify-cms-backend-git-gateway@2.11.8) (2020-12-15) - - -### Bug Fixes - -* **deps:** update dependency ini to v2 ([#4722](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/4722)) ([e14ace3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/e14ace373b11510159a9b4d3f977d27ed886b288)) - - - - - -## [2.11.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.6...netlify-cms-backend-git-gateway@2.11.7) (2020-12-06) - - -### Bug Fixes - -* **large-media:** mark pointer files as binary ([#4678](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/4678)) ([7697b90](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/7697b907d7bae750f4ec041a184188aa46995320)) - - - - - -## [2.11.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.5...netlify-cms-backend-git-gateway@2.11.6) (2020-10-12) - - -### Bug Fixes - -* **deps:** update dependency jwt-decode to v3 ([#4408](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/4408)) ([03492e4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/03492e4e684ffce3a541ef15edb591d1fd5b5854)) - - - - - -## [2.11.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.4...netlify-cms-backend-git-gateway@2.11.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.11.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.11.3...netlify-cms-backend-git-gateway@2.11.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## 2.11.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.11.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.11.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.5...netlify-cms-backend-git-gateway@2.11.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) -* **backend-gitgateway:** improve deploy preview visibility ([#3882](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3882)) ([afc9bf4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/afc9bf4f3fe14ccb60851fc24e68922a6e4a85a9)) - - - - - -## [2.10.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.4...netlify-cms-backend-git-gateway@2.10.5) (2020-05-19) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.10.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.3...netlify-cms-backend-git-gateway@2.10.4) (2020-05-04) - - -### Bug Fixes - -* **git-gateway:** wait for identity widget to initialize ([#3660](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3660)) ([6c229c5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/6c229c5149e3beff05bcfb42ca286d3e9170e54e)) - - - - - -## [2.10.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.2...netlify-cms-backend-git-gateway@2.10.3) (2020-04-21) - - -### Bug Fixes - -* **large-media:** match netlify.app as lfs host ([#3642](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3642)) ([9b79623](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/9b79623bc8b8fe212fb2d15dec8a75328cde9c64)) - - - - - -## [2.10.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.1...netlify-cms-backend-git-gateway@2.10.2) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.10.0...netlify-cms-backend-git-gateway@2.10.1) (2020-03-30) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.9.1...netlify-cms-backend-git-gateway@2.10.0) (2020-03-12) - - -### Features - -* add media lib virtualization ([#3381](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3381)) ([92e7601](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/92e76011e7a9e8b5370088b0a2c065df66b5f7fb)) -* **backend-github:** add pagination ([#3379](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3379)) ([39f1307](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/39f1307e3a36447da8c9b3ca79b1d7db52ea1a19)) - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.9.0...netlify-cms-backend-git-gateway@2.9.1) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.8.1...netlify-cms-backend-git-gateway@2.9.0) (2020-02-25) - - -### Features - -* **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3316)) ([7e0a8ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3292) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.8.0...netlify-cms-backend-git-gateway@2.8.1) (2020-02-22) - - -### Reverts - -* Revert "feat(core): Align GitHub metadata handling with other backends (#3292)" ([5bdd3df](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3292) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.7.2...netlify-cms-backend-git-gateway@2.8.0) (2020-02-22) - - -### Features - -* **core:** Align GitHub metadata handling with other backends ([#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3292)) ([8193b5a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/8193b5ace89d6f14a6c756235a50b186a763b6b1)) - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.7.1...netlify-cms-backend-git-gateway@2.7.2) (2020-02-11) - - -### Bug Fixes - -* stringify error message ([#3233](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3233)) ([249bd7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/249bd7ec1ed2197106cbb01f8c05e1b8830aa5bc)) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.7.0...netlify-cms-backend-git-gateway@2.7.1) (2020-01-24) - - -### Bug Fixes - -* **backend-git-gateway:** re-write GitHub pagination links ([#3135](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3135)) ([834f6b9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/834f6b9e457f3738ce0f240ddd4cc160aff9e2f5)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.6.2...netlify-cms-backend-git-gateway@2.7.0) (2020-01-21) - - -### Bug Fixes - -* **git-gateway-gitlab:** fix large media support for editorial workflow ([#3105](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3105)) ([038803c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/038803c9f249de386812652372c35c4c53935295)) - - -### Features - -* **backend-bitbucket:** Add Git-LFS support ([#3118](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3118)) ([a48c02d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/a48c02d852ca5e11055da3a14cefae8d17a68498)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.6.1...netlify-cms-backend-git-gateway@2.6.2) (2020-01-16) - - -### Bug Fixes - -* don't fail on malformed pointer files ([#3095](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3095)) ([9210843](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/92108431f0c3df3e99b5aa7f462006ec3fa7777e)) - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.6.0...netlify-cms-backend-git-gateway@2.6.1) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.6.0-beta.0...netlify-cms-backend-git-gateway@2.6.0) (2020-01-07) - - -### Bug Fixes - -* rebase open authoring branches ([#2975](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2975)) ([8c175f6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/8c175f6132fa18a13763cc563f7d3201c1e3580e)) - - -### Features - -* **backend-git-gateway:** handle identity disabled error message ([#3002](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/3002)) ([b5ffccd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/b5ffccdac506db416c09aaebb38611783487c52a)) - - - - - -# [2.6.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.5.1...netlify-cms-backend-git-gateway@2.6.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.5.0...netlify-cms-backend-git-gateway@2.5.1) (2019-11-18) - - -### Bug Fixes - -* **git-gateway:** unpublished entries not loaded for git-gateway(GitHub) ([#2856](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2856)) ([4a2328b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/4a2328b2f10ea678184391e4caf235b41323cd3e)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.6...netlify-cms-backend-git-gateway@2.5.0) (2019-11-07) - - -### Bug Fixes - -* **backend-git-gateway:** omit /repos/ when no repo ([#2846](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2846)) ([da2dab3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/da2dab305ab7f0655791ef0fb5376e3d5e72897c)) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) -* enable specifying custom open authoring commit message ([#2810](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2810)) ([2841ff9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/2841ff9ffe58afcf4dba45514a84a262ad370f1d)) - - - - - -## [2.4.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.5...netlify-cms-backend-git-gateway@2.4.6) (2019-09-26) - - -### Bug Fixes - -* **git-gateway:** pass api URL instead of constructing it from repo value ([#2631](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2631)) ([922c0f3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/922c0f3)) - - - - - -## [2.4.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.4...netlify-cms-backend-git-gateway@2.4.5) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.4.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.3...netlify-cms-backend-git-gateway@2.4.4) (2019-06-26) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.4.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.2...netlify-cms-backend-git-gateway@2.4.3) (2019-06-18) - - -### Bug Fixes - -* **core:** address new entries error for non-github backends ([#2390](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2390)) ([a5bd6b3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/a5bd6b3)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.2-beta.0...netlify-cms-backend-git-gateway@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.1...netlify-cms-backend-git-gateway@2.4.2-beta.0) (2019-04-05) - - -### Bug Fixes - -* **backend-git-gateway:** fix image display w/o large media ([#2271](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2271)) ([6c3506b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/6c3506b)) - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.1-beta.1...netlify-cms-backend-git-gateway@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.1-beta.0...netlify-cms-backend-git-gateway@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.4.0...netlify-cms-backend-git-gateway@2.4.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/7987091)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.3.1-beta.0...netlify-cms-backend-git-gateway@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/d142b32)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.3.0...netlify-cms-backend-git-gateway@2.3.1-beta.0) (2019-03-22) - - -### Bug Fixes - -* **editorial-workflow:** fix LM pointers changing to binary files ([#2228](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2228)) ([d39a361](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/d39a361)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.3.0-beta.0...netlify-cms-backend-git-gateway@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.5-beta.0...netlify-cms-backend-git-gateway@2.3.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/82cc794)) - - - - - -## [2.2.5-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.4...netlify-cms-backend-git-gateway@2.2.5-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/ccef446)) - - - - - -## [2.2.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.3...netlify-cms-backend-git-gateway@2.2.4) (2019-03-11) - - -### Bug Fixes - -* **backend-github:** make non-Large Media previews work with Git Gateway+Github ([#2151](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2151)) ([63582dc](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/63582dc)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.2...netlify-cms-backend-git-gateway@2.2.3) (2019-03-08) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.1...netlify-cms-backend-git-gateway@2.2.2) (2019-02-28) - - -### Bug Fixes - -* **git-gateway:** fix previews for GitHub images not in Large Media ([#2125](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2125)) ([d17f896](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/d17f896)) - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.2.0...netlify-cms-backend-git-gateway@2.2.1) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.1.2...netlify-cms-backend-git-gateway@2.2.0) (2019-02-08) - - -### Features - -* **workflow:** add deploy preview links ([#2028](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/2028)) ([15d221d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/15d221d)) - - - - - -## [2.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.1.1...netlify-cms-backend-git-gateway@2.1.2) (2018-12-11) - - -### Bug Fixes - -* **netlify-cms-backend-git-gateway:** content-type may have charset ([#1951](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1951)) ([c74dbae](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/c74dbae)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.1.0...netlify-cms-backend-git-gateway@2.1.1) (2018-11-29) - - -### Bug Fixes - -* **backend-git-gateway:** double slashes when gateway_url contained a backend ([#1712](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1712)) ([6de47cd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/6de47cd)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.8...netlify-cms-backend-git-gateway@2.1.0) (2018-11-12) - - -### Bug Fixes - -* **identity:** switch user name reference to full_name ([#1809](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1809)) ([55d45a8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/55d45a8)) - - -### Features - -* allow custom logo on auth page ([#1818](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1818)) ([c6ae1e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/c6ae1e8)) - - - - - - -## [2.0.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.7...netlify-cms-backend-git-gateway@2.0.8) (2018-09-06) - - - - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.6...netlify-cms-backend-git-gateway@2.0.7) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.5...netlify-cms-backend-git-gateway@2.0.6) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.4...netlify-cms-backend-git-gateway@2.0.5) (2018-08-07) - - -### Bug Fixes - -* **workflow:** fix workflow entries not appearing ([#1581](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1581)) ([95c8de0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/95c8de0)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.3...netlify-cms-backend-git-gateway@2.0.4) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-backend-git-gateway - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/compare/netlify-cms-backend-git-gateway@2.0.2...netlify-cms-backend-git-gateway@2.0.3) (2018-07-28) - - -### Bug Fixes - -* **git-gateway:** correct `proxied` value for proxied backends ([#1540](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/issues/1540)) ([f7dba87](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway/commit/f7dba87)) - - - - - -## 2.0.2 (2018-07-27) - - -### Bug Fixes - -* **git-gateway:** pass options through git-gateway backend ([#1532](https://github.com/netlify/netlify-cms/issues/1532)) ([4c5436a](https://github.com/netlify/netlify-cms/commit/4c5436a)) - - - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - -### Bug Fixes - -* **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/netlify/netlify-cms/issues/1522)) ([bdfd944](https://github.com/netlify/netlify-cms/commit/bdfd944)) diff --git a/packages/netlify-cms-backend-git-gateway/README.md b/packages/netlify-cms-backend-git-gateway/README.md deleted file mode 100644 index 2b0c9172..00000000 --- a/packages/netlify-cms-backend-git-gateway/README.md +++ /dev/null @@ -1,26 +0,0 @@ -# Git Gateway - -Netlify's [gateway](https://github.com/netlify/git-gateway) to hosted git APIs. - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on `Api`. - -`Api` and `Implementation` from backend-[github](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/README.md)/[gitlab](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/README.md)/[bitbacket](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-bitbacket/README.md) extended with Netlify-specific `LargeMedia(LFS)` and `JWT` auth. - -`AuthenticationPage` - uses [lib-auth](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/README.md) and implements Netlify Identity authentication flow. - -Look at tests or types for more info. - -## Debugging - -When debugging the CMS with Git Gateway you must: - -1. Have a Netlify site with [Git Gateway](https://docs.netlify.com/visitor-access/git-gateway/) and [Netlify Identity](https://docs.netlify.com/visitor-access/identity/) enabled. An easy way to create such a site is to use a [template](https://www.netlifycms.org/docs/start-with-a-template/), for example the [Gatsby template](https://app.netlify.com/start/deploy?repository=https://github.com/AustinGreen/gatsby-starter-netlify-cms&stack=cms) -2. Tell the CMS the URL of your Netlify site using a local storage item. To do so: - - 1. Open `http://localhost:8080/` in the browser - 2. Write the below command and press enter: `localStorage.setItem('netlifySiteURL', 'https://yourwebsiteurl.netlify.app/')` - 3. To be sure, you can run this command as well: `localStorage.getItem('netlifySiteURL')` - 4. Refresh the page - 5. You should be able to log in via your Netlify Identity email/password diff --git a/packages/netlify-cms-backend-git-gateway/package.json b/packages/netlify-cms-backend-git-gateway/package.json deleted file mode 100644 index 0ab1e76e..00000000 --- a/packages/netlify-cms-backend-git-gateway/package.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "name": "netlify-cms-backend-git-gateway", - "description": "Git Gateway backend for Netlify CMS", - "version": "2.13.4", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-git-gateway", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-git-gateway.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "backend", - "git-gateway", - "gateway" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "dependencies": { - "gotrue-js": "^0.9.24", - "ini": "^2.0.0", - "jwt-decode": "^3.0.0", - "minimatch": "^3.0.4" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "lodash": "^4.17.11", - "netlify-cms-backend-bitbucket": "^2.12.8", - "netlify-cms-backend-github": "^2.11.9", - "netlify-cms-backend-gitlab": "^2.9.9", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-git-gateway/src/__tests__/AuthenticationPage.spec.js b/packages/netlify-cms-backend-git-gateway/src/__tests__/AuthenticationPage.spec.js deleted file mode 100644 index f392c816..00000000 --- a/packages/netlify-cms-backend-git-gateway/src/__tests__/AuthenticationPage.spec.js +++ /dev/null @@ -1,41 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; - -window.netlifyIdentity = { - currentUser: jest.fn(), - on: jest.fn(), - close: jest.fn(), -}; - -describe('GitGatewayAuthenticationPage', () => { - const props = { - config: { logo_url: 'logo_url' }, - t: jest.fn(key => key), - onLogin: jest.fn(), - inProgress: false, - }; - - beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - }); - - it('should render with identity error', () => { - const { default: GitGatewayAuthenticationPage } = require('../AuthenticationPage'); - const { asFragment } = render(); - - const errorCallback = window.netlifyIdentity.on.mock.calls.find(call => call[0] === 'error')[1]; - - errorCallback( - new Error('Failed to load settings from https://site.netlify.com/.netlify/identity'), - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render with no identity error', () => { - const { default: GitGatewayAuthenticationPage } = require('../AuthenticationPage'); - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-backend-git-gateway/src/__tests__/GitHubAPI.spec.js b/packages/netlify-cms-backend-git-gateway/src/__tests__/GitHubAPI.spec.js deleted file mode 100644 index d5d048b5..00000000 --- a/packages/netlify-cms-backend-git-gateway/src/__tests__/GitHubAPI.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import API from '../GitHubAPI'; - -describe('github API', () => { - describe('request', () => { - beforeEach(() => { - const fetch = jest.fn(); - global.fetch = fetch; - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('should fetch url with authorization header', async () => { - const api = new API({ - apiRoot: 'https://site.netlify.com/.netlify/git/github', - tokenPromise: () => Promise.resolve('token'), - }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue('some response'), - ok: true, - status: 200, - headers: { get: () => '' }, - }); - const result = await api.request('/some-path'); - expect(result).toEqual('some response'); - expect(fetch).toHaveBeenCalledTimes(1); - expect(fetch).toHaveBeenCalledWith('https://site.netlify.com/.netlify/git/github/some-path', { - cache: 'no-cache', - headers: { - Authorization: 'Bearer token', - 'Content-Type': 'application/json; charset=utf-8', - }, - signal: expect.any(AbortSignal), - }); - }); - - it('should throw error on not ok response with message property', async () => { - const api = new API({ - apiRoot: 'https://site.netlify.com/.netlify/git/github', - tokenPromise: () => Promise.resolve('token'), - }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue({ message: 'some error' }), - ok: false, - status: 404, - headers: { get: () => '' }, - }); - - await expect(api.request('some-path')).rejects.toThrow( - expect.objectContaining({ - message: 'some error', - name: 'API_ERROR', - status: 404, - api: 'Git Gateway', - }), - ); - }); - - it('should throw error on not ok response with msg property', async () => { - const api = new API({ - apiRoot: 'https://site.netlify.com/.netlify/git/github', - tokenPromise: () => Promise.resolve('token'), - }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue({ msg: 'some error' }), - ok: false, - status: 404, - headers: { get: () => '' }, - }); - - await expect(api.request('some-path')).rejects.toThrow( - expect.objectContaining({ - message: 'some error', - name: 'API_ERROR', - status: 404, - api: 'Git Gateway', - }), - ); - }); - }); - - describe('nextUrlProcessor', () => { - it('should re-write github url', () => { - const api = new API({ - apiRoot: 'https://site.netlify.com/.netlify/git/github', - }); - - expect(api.nextUrlProcessor()('https://api.github.com/repositories/10000/pulls')).toEqual( - 'https://site.netlify.com/.netlify/git/github/pulls', - ); - }); - }); -}); diff --git a/packages/netlify-cms-backend-git-gateway/src/__tests__/__snapshots__/AuthenticationPage.spec.js.snap b/packages/netlify-cms-backend-git-gateway/src/__tests__/__snapshots__/AuthenticationPage.spec.js.snap deleted file mode 100644 index 24b47d5e..00000000 --- a/packages/netlify-cms-backend-git-gateway/src/__tests__/__snapshots__/AuthenticationPage.spec.js.snap +++ /dev/null @@ -1,333 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`GitGatewayAuthenticationPage should render with identity error 1`] = ` - - .emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: column nowrap; - -ms-flex-flow: column nowrap; - flex-flow: column nowrap; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100vh; -} - -.emotion-0 { - width: 300px; - height: 200px; - margin-top: -150px; -} - -.emotion-3 { - display: inline-block; - line-height: 0; - width: 100px; - height: 100px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); - color: #c4c6d2; - position: absolute; - bottom: 10px; -} - -.emotion-3 path:not(.no-fill), -.emotion-3 circle:not(.no-fill), -.emotion-3 polygon:not(.no-fill), -.emotion-3 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-3 path.clipped { - fill: transparent; -} - -.emotion-3 svg { - width: 100%; - height: 100%; -} - -
- - Logo - - - auth.errors.identitySettings - - - - - - - - - - - -
-
-`; - -exports[`GitGatewayAuthenticationPage should render with no identity error 1`] = ` - - .emotion-7 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: column nowrap; - -ms-flex-flow: column nowrap; - flex-flow: column nowrap; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100vh; -} - -.emotion-0 { - width: 300px; - height: 200px; - margin-top: -150px; -} - -.emotion-2 { - border: 0; - border-radius: 5px; - cursor: pointer; - box-shadow: 0 4px 12px 0 rgba(68,74,87,0.15),0 1px 3px 0 rgba(68,74,87,0.25); - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - background-color: #313d3e; - color: #fff; - padding: 0 12px; - margin-top: -40px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; -} - -.emotion-2:focus, -.emotion-2:hover { - color: #fff; - background-color: #555a65; -} - -.emotion-2[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-5 { - display: inline-block; - line-height: 0; - width: 100px; - height: 100px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); - color: #c4c6d2; - position: absolute; - bottom: 10px; -} - -.emotion-5 path:not(.no-fill), -.emotion-5 circle:not(.no-fill), -.emotion-5 polygon:not(.no-fill), -.emotion-5 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-5 path.clipped { - fill: transparent; -} - -.emotion-5 svg { - width: 100%; - height: 100%; -} - -.emotion-7 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: column nowrap; - -ms-flex-flow: column nowrap; - flex-flow: column nowrap; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - height: 100vh; -} - -.emotion-0 { - width: 300px; - height: 200px; - margin-top: -150px; -} - -.emotion-2 { - border: 0; - border-radius: 5px; - cursor: pointer; - box-shadow: 0 4px 12px 0 rgba(68,74,87,0.15),0 1px 3px 0 rgba(68,74,87,0.25); - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - background-color: #313d3e; - color: #fff; - padding: 0 12px; - margin-top: -40px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - position: relative; -} - -.emotion-2:focus, -.emotion-2:hover { - color: #fff; - background-color: #555a65; -} - -.emotion-2[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-5 { - display: inline-block; - line-height: 0; - width: 100px; - height: 100px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); - color: #c4c6d2; - position: absolute; - bottom: 10px; -} - -.emotion-5 path:not(.no-fill), -.emotion-5 circle:not(.no-fill), -.emotion-5 polygon:not(.no-fill), -.emotion-5 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-5 path.clipped { - fill: transparent; -} - -.emotion-5 svg { - width: 100%; - height: 100%; -} - -
- - Logo - - - - - - - - - - - - -
-
-`; diff --git a/packages/netlify-cms-backend-git-gateway/webpack.config.js b/packages/netlify-cms-backend-git-gateway/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-git-gateway/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-github/CHANGELOG.md b/packages/netlify-cms-backend-github/CHANGELOG.md deleted file mode 100644 index dc370caa..00000000 --- a/packages/netlify-cms-backend-github/CHANGELOG.md +++ /dev/null @@ -1,814 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.14.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.14.2...netlify-cms-backend-github@2.14.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.14.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.14.1...netlify-cms-backend-github@2.14.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.14.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.14.0...netlify-cms-backend-github@2.14.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.14.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.13.5...netlify-cms-backend-github@2.14.0) (2021-10-18) - - -### Features - -* display author of changes in workflow tab ([#5780](https://github.com/netlify/netlify-cms/issues/5780)) ([3f607e4](https://github.com/netlify/netlify-cms/commit/3f607e41d9c4d8fe5329a9ab6841cada7742825e)) - - - - - -## [2.13.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.13.4...netlify-cms-backend-github@2.13.5) (2021-10-15) - - -### Bug Fixes - -* remove "Don't fork the repo"-Button - fixes [#5723](https://github.com/netlify/netlify-cms/issues/5723) ([#5872](https://github.com/netlify/netlify-cms/issues/5872)) ([05d8923](https://github.com/netlify/netlify-cms/commit/05d89230dca315ddcc734b1dc6223df1d8dc1ede)) - - - - - -## [2.13.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-github@2.13.3...netlify-cms-backend-github@2.13.4) (2021-07-20) - - -### Bug Fixes - -* add updated_at to graphql query ([#5611](https://github.com/netlify/netlify-cms/issues/5611)) ([8989550](https://github.com/netlify/netlify-cms/commit/89895508b2ccc8f07019abb6bc2d0162c0d86266)) - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.13.2...netlify-cms-backend-github@2.13.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.13.1...netlify-cms-backend-github@2.13.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.13.0...netlify-cms-backend-github@2.13.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.12.0...netlify-cms-backend-github@2.13.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.9...netlify-cms-backend-github@2.12.0) (2021-04-04) - - -### Features - -* **open-authoring:** add alwaysFork option ([#5204](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/5204)) ([7b19e30](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7b19e30dd2a310dbc20ccb6fcca45d5cbde1014b)) - - - - - -## [2.11.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.8...netlify-cms-backend-github@2.11.9) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.11.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.7...netlify-cms-backend-github@2.11.8) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.11.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.6...netlify-cms-backend-github@2.11.7) (2020-12-06) - - -### Bug Fixes - -* **large-media:** mark pointer files as binary ([#4678](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/4678)) ([7697b90](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7697b907d7bae750f4ec041a184188aa46995320)) - - - - - -## [2.11.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.5...netlify-cms-backend-github@2.11.6) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.11.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.4...netlify-cms-backend-github@2.11.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## 2.11.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.11.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.11.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.11.0...netlify-cms-backend-github@2.11.1) (2020-07-14) - - -### Bug Fixes - -* **backend-github:** use workflow branch when listing files to move ([#4019](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/4019)) ([8720a42](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/8720a4233db16d91d6b86ee8653d05f8953cb430)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.6...netlify-cms-backend-github@2.11.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) -* **backend-gitgateway:** improve deploy preview visibility ([#3882](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3882)) ([afc9bf4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/afc9bf4f3fe14ccb60851fc24e68922a6e4a85a9)) - - - - - -## [2.10.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.5...netlify-cms-backend-github@2.10.6) (2020-05-19) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.10.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.4...netlify-cms-backend-github@2.10.5) (2020-04-21) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.10.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.3...netlify-cms-backend-github@2.10.4) (2020-04-07) - - -### Bug Fixes - -* **backend-github:** add fallback for diff errors/warnings ([#3558](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3558)) ([1705c79](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/1705c79a9297d844d5421d685a7785e1e210e39e)) - - - - - -## [2.10.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.2...netlify-cms-backend-github@2.10.3) (2020-04-01) - - -### Bug Fixes - -* **open-authoring:** properly delete open authoring branches ([#3512](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3512)) ([cc89aa5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/cc89aa5c430a6bee51483cda91d0f92e7437f29e)) - - - - - -## [2.10.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.1...netlify-cms-backend-github@2.10.2) (2020-04-01) - - -### Bug Fixes - -* **open-authoring:** prevent workflow view from breaking on entry error ([#3508](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3508)) ([cbb3927](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/cbb39271012fc3beecfdf180e573e343ee48fe26)) - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.10.0...netlify-cms-backend-github@2.10.1) (2020-03-20) - - -### Bug Fixes - -* missing workflow timestamp ([#3445](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3445)) ([9616cdb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/9616cdb8bb0a564771e5755bcd3718a07f2e2072)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.9.3...netlify-cms-backend-github@2.10.0) (2020-03-12) - - -### Bug Fixes - -* **backend-github:** don't create new commits on empty diff when rebasing ([#3411](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3411)) ([70de9f6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/70de9f6b4b89dd8e23205929033745572562e8fc)) -* update repo owner from GitHub API to match casing ([#3410](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3410)) ([c2e7a24](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/c2e7a24dc20dfea5b1289c5705095d2cf8b04c54)) - - -### Features - -* **backend-github:** add pagination ([#3379](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3379)) ([39f1307](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/39f1307e3a36447da8c9b3ca79b1d7db52ea1a19)) - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.9.2...netlify-cms-backend-github@2.9.3) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7c45a3cda983be427864a56e58791565eb9232e2)) -* **open-authoring:** use origin repo when calling compare API ([#3363](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3363)) ([e40b81a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/e40b81a5647d45487d6ddf17245beddd354e0f39)) - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.9.1...netlify-cms-backend-github@2.9.2) (2020-02-27) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.9.0...netlify-cms-backend-github@2.9.1) (2020-02-25) - - -### Bug Fixes - -* **backend-github:** fail workflow migrations gracefully ([#3325](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3325)) ([83e0383](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/83e0383b690fb452ea40cb165a56f65a695dc83c)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.8.1...netlify-cms-backend-github@2.9.0) (2020-02-25) - - -### Bug Fixes - -* **backend-github:** improve workflow migration edge cases/messaging ([#3319](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3319)) ([684b79e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/684b79e43bebb63ce1e844eae5c8c0e76087687b)) - - -### Features - -* **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3316)) ([7e0a8ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3292) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.8.0...netlify-cms-backend-github@2.8.1) (2020-02-22) - - -### Reverts - -* Revert "feat(core): Align GitHub metadata handling with other backends (#3292)" ([5bdd3df](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3292) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.7.1...netlify-cms-backend-github@2.8.0) (2020-02-22) - - -### Features - -* **core:** Align GitHub metadata handling with other backends ([#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3292)) ([8193b5a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/8193b5ace89d6f14a6c756235a50b186a763b6b1)) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.7.0...netlify-cms-backend-github@2.7.1) (2020-02-17) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.6...netlify-cms-backend-github@2.7.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.6.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.5...netlify-cms-backend-github@2.6.6) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## [2.6.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.4...netlify-cms-backend-github@2.6.5) (2020-01-24) - - -### Bug Fixes - -* **backend-git-gateway:** re-write GitHub pagination links ([#3135](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3135)) ([834f6b9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/834f6b9e457f3738ce0f240ddd4cc160aff9e2f5)) - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.3...netlify-cms-backend-github@2.6.4) (2020-01-16) - - -### Bug Fixes - -* **backend-github-graphql:** handle trailing paths in collection folder ([#3099](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3099)) ([bc80804](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/bc808040661d345e65d49d64693cd6da3b6816fb)) - - - - - -## [2.6.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.2...netlify-cms-backend-github@2.6.3) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.1...netlify-cms-backend-github@2.6.2) (2020-01-14) - - -### Bug Fixes - -* **backend-github-graphql:** return empty array on non existent folder ([#3079](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3079)) ([69b130a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/69b130a3f239590f828f0e4f6f6c0a872b17548b)) - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.0...netlify-cms-backend-github@2.6.1) (2020-01-09) - - -### Bug Fixes - -* trim '/' from folder ([#3052](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/3052)) ([4b6c8de](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/4b6c8de6b2e3de28f0989b9a012cb302d4de4358)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.6.0-beta.0...netlify-cms-backend-github@2.6.0) (2020-01-07) - - -### Bug Fixes - -* rebase open authoring branches ([#2975](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2975)) ([8c175f6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/8c175f6132fa18a13763cc563f7d3201c1e3580e)) - - - - - -# [2.6.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0...netlify-cms-backend-github@2.6.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.8...netlify-cms-backend-github@2.5.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.5.0-beta.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.7...netlify-cms-backend-github@2.5.0-beta.8) (2019-12-16) - - -### Bug Fixes - -* don't fail on deleting non existent branch ([1e77d4b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/1e77d4b7688de795ab1b01c6ce2483a0383bbfb6)) - - - - - -# [2.5.0-beta.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.6...netlify-cms-backend-github@2.5.0-beta.7) (2019-12-02) - - -### Features - -* content in sub folders ([#2897](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2897)) ([afcfe5b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/afcfe5b6d5f32669e9061ec596bd35ad545d61a3)) - - - - - -# [2.5.0-beta.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.5...netlify-cms-backend-github@2.5.0-beta.6) (2019-11-26) - - -### Bug Fixes - -* **backend-github:** prepend collection name ([#2878](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2878)) ([465f463](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/465f4639597f258d5aa2c1b65e9d2c16023ee7ae)) - - -### Features - -* workflow unpublished entry ([#2914](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2914)) ([41bb9aa](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/41bb9aac0dd6fd9f8ff157bb0b29c85aa87fe04d)) - - - - - -# [2.5.0-beta.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.4...netlify-cms-backend-github@2.5.0-beta.5) (2019-11-18) - - -### Bug Fixes - -* **backend-github:** editorial workflow commits ([#2867](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2867)) ([86adca3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/86adca3a18f25ab74d1c6702bafab250f005ceec)) -* make forkExists name matching case-insensitive ([#2869](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2869)) ([9978769](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/9978769ece9262265d3efa77357f9e8b46ad9a1e)) -* **backend-github:** loaded entries limit ([#2873](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2873)) ([68a8c8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/68a8c8a693646ebd33fae791aaaec47b050e0186)) -* **git-gateway:** unpublished entries not loaded for git-gateway(GitHub) ([#2856](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2856)) ([4a2328b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/4a2328b2f10ea678184391e4caf235b41323cd3e)) - - -### Features - -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -# [2.5.0-beta.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.3...netlify-cms-backend-github@2.5.0-beta.4) (2019-11-07) - - -### Bug Fixes - -* **github-backend:** load media URLs via API ([#2817](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2817)) ([eaeaf44](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/eaeaf4483287a1f724ee60ef321ff749f1c20acf)) -* change default open authoring scope, make it configurable ([#2821](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2821)) ([002cdd7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/002cdd77a856bde3672e75dde6d3a2b246e1035f)) -* display UI to fork a repo only when fork doesn't exist ([#2802](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2802)) ([7f90d0e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7f90d0e065315b9073d21fd733f42f3838ecfe09)) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) - - - - - -# [2.5.0-beta.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.2...netlify-cms-backend-github@2.5.0-beta.3) (2019-09-26) - - -### Bug Fixes - -* **backend-github:** update Open Authoring branches with no PR ([#2618](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2618)) ([6817033](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/6817033)) -* **git-gateway:** pass api URL instead of constructing it from repo value ([#2631](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2631)) ([922c0f3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/922c0f3)) -* **github-backend:** handle race condition in editorial workflow ([#2658](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2658)) ([97f1f84](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/97f1f84)) - - - - - -# [2.5.0-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.1...netlify-cms-backend-github@2.5.0-beta.2) (2019-09-04) - - -### Bug Fixes - -* **github-graphql:** use getMediaDisplayURL to load media with auth header ([#2652](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2652)) ([e674e43](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/e674e43)) - - -### Features - -* **backend-github:** GitHub GraphQL API support ([#2456](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2456)) ([ece136c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/ece136c)) - - - - - -# [2.5.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.5.0-beta.0...netlify-cms-backend-github@2.5.0-beta.1) (2019-08-24) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.2...netlify-cms-backend-github@2.5.0-beta.0) (2019-07-24) - - -### Features - -* **backend-github:** Open Authoring ([#2430](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2430)) ([edf0a3a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/edf0a3a)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.2-beta.0...netlify-cms-backend-github@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.1...netlify-cms-backend-github@2.4.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.1-beta.1...netlify-cms-backend-github@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.1-beta.0...netlify-cms-backend-github@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.4.0...netlify-cms-backend-github@2.4.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/7987091)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.3.0...netlify-cms-backend-github@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/d142b32)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.3.0-beta.0...netlify-cms-backend-github@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.2.3-beta.0...netlify-cms-backend-github@2.3.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/82cc794)) - - - - - -## [2.2.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.2.2...netlify-cms-backend-github@2.2.3-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/ccef446)) - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.2.1...netlify-cms-backend-github@2.2.2) (2019-03-08) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.2.0...netlify-cms-backend-github@2.2.1) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-backend-github - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.1.0...netlify-cms-backend-github@2.2.0) (2019-02-08) - - -### Features - -* **workflow:** add deploy preview links ([#2028](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/2028)) ([15d221d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/15d221d)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.9...netlify-cms-backend-github@2.1.0) (2018-11-12) - - -### Features - -* allow custom logo on auth page ([#1818](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/1818)) ([c6ae1e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/c6ae1e8)) - - - - - - -## [2.0.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.8...netlify-cms-backend-github@2.0.9) (2018-09-17) - - - - -**Note:** Version bump only for package netlify-cms-backend-github - - -## [2.0.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.7...netlify-cms-backend-github@2.0.8) (2018-09-06) - - - - -**Note:** Version bump only for package netlify-cms-backend-github - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.6...netlify-cms-backend-github@2.0.7) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-backend-github - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.5...netlify-cms-backend-github@2.0.6) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-backend-github - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.4...netlify-cms-backend-github@2.0.5) (2018-08-07) - - -### Bug Fixes - -* **backends:** fix commit message handling ([#1568](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/1568)) ([f7e7120](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/f7e7120)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.3...netlify-cms-backend-github@2.0.4) (2018-08-01) - - -### Bug Fixes - -* **workflow:** enable workflow per method ([#1569](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/1569)) ([90b8156](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/90b8156)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.2...netlify-cms-backend-github@2.0.3) (2018-08-01) - - -### Bug Fixes - -* **github:** fix image uploading ([#1561](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/1561)) ([ddc8f04](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/ddc8f04)) -* **workflow:** fix status not set on new workflow entries ([#1558](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/issues/1558)) ([0aa085f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/commit/0aa085f)) - - - - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github/compare/netlify-cms-backend-github@2.0.1...netlify-cms-backend-github@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-backend-github - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-backend-github diff --git a/packages/netlify-cms-backend-github/README.md b/packages/netlify-cms-backend-github/README.md deleted file mode 100644 index f36a0d48..00000000 --- a/packages/netlify-cms-backend-github/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# GitHub backend - -An abstraction layer between the CMS and [Github](https://docs.github.com/en/rest) - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on `Api`. - -`Api` - A wrapper for GitHub REST API. - -`GraphQLApi` - `Api` with `ApolloClient`. [Api docs](https://docs.github.com/en/graphql) and [netlify docs](https://www.netlifycms.org/docs/beta-features/#github-graphql-api). - -`AuthenticationPage` - uses [lib-auth](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/README.md) to facilitate OAuth and implicit authentication. - -`scripts` - use `createFragmentTypes.js` to create GitHub GraphQL API fragment types. - -Look at tests or types for more info. diff --git a/packages/netlify-cms-backend-github/package.json b/packages/netlify-cms-backend-github/package.json deleted file mode 100644 index 1c5eeee6..00000000 --- a/packages/netlify-cms-backend-github/package.json +++ /dev/null @@ -1,44 +0,0 @@ -{ - "name": "netlify-cms-backend-github", - "description": "GitHub backend for Netlify CMS", - "version": "2.14.3", - "license": "MIT", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-github.js", - "keywords": [ - "netlify", - "netlify-cms", - "backend", - "github" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"", - "createFragmentTypes": "node scripts/createFragmentTypes.js" - }, - "dependencies": { - "apollo-cache-inmemory": "^1.6.2", - "apollo-client": "^2.6.3", - "apollo-link-context": "^1.0.18", - "apollo-link-http": "^1.5.15", - "common-tags": "^1.8.0", - "graphql": "^15.0.0", - "graphql-tag": "^2.10.1", - "js-base64": "^3.0.0", - "semaphore": "^1.1.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "lodash": "^4.17.11", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-github/src/__tests__/API.spec.js b/packages/netlify-cms-backend-github/src/__tests__/API.spec.js deleted file mode 100644 index 49db20a6..00000000 --- a/packages/netlify-cms-backend-github/src/__tests__/API.spec.js +++ /dev/null @@ -1,833 +0,0 @@ -import { Base64 } from 'js-base64'; - -import API from '../API'; - -global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests')); - -describe('github API', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - function mockAPI(api, responses) { - api.request = jest.fn().mockImplementation((path, options = {}) => { - const normalizedPath = path.indexOf('?') !== -1 ? path.slice(0, path.indexOf('?')) : path; - const response = responses[normalizedPath]; - return typeof response === 'function' - ? Promise.resolve(response(options)) - : Promise.reject(new Error(`No response for path '${normalizedPath}'`)); - }); - } - - describe('editorialWorkflowGit', () => { - it('should create PR with correct base branch name when publishing with editorial workflow', () => { - let prBaseBranch = null; - let labels = null; - const api = new API({ - branch: 'gh-pages', - repo: 'owner/my-repo', - initialWorkflowStatus: 'draft', - }); - const responses = { - '/repos/owner/my-repo/branches/gh-pages': () => ({ commit: { sha: 'def' } }), - '/repos/owner/my-repo/git/trees/def': () => ({ tree: [] }), - '/repos/owner/my-repo/git/trees': () => ({}), - '/repos/owner/my-repo/git/commits': () => ({}), - '/repos/owner/my-repo/git/refs': () => ({}), - '/repos/owner/my-repo/pulls': req => { - prBaseBranch = JSON.parse(req.body).base; - return { head: { sha: 'cbd' }, labels: [], number: 1 }; - }, - '/repos/owner/my-repo/issues/1/labels': req => { - labels = JSON.parse(req.body).labels; - return {}; - }, - }; - mockAPI(api, responses); - - return expect( - api.editorialWorkflowGit([], { slug: 'entry', sha: 'abc' }, null, {}).then(() => ({ - prBaseBranch, - labels, - })), - ).resolves.toEqual({ prBaseBranch: 'gh-pages', labels: ['netlify-cms/draft'] }); - }); - - it('should create PR with correct base branch name with custom prefix when publishing with editorial workflow', () => { - let prBaseBranch = null; - let labels = null; - const api = new API({ - branch: 'gh-pages', - repo: 'owner/my-repo', - initialWorkflowStatus: 'draft', - cmsLabelPrefix: 'other/', - }); - const responses = { - '/repos/owner/my-repo/branches/gh-pages': () => ({ commit: { sha: 'def' } }), - '/repos/owner/my-repo/git/trees/def': () => ({ tree: [] }), - '/repos/owner/my-repo/git/trees': () => ({}), - '/repos/owner/my-repo/git/commits': () => ({}), - '/repos/owner/my-repo/git/refs': () => ({}), - '/repos/owner/my-repo/pulls': req => { - prBaseBranch = JSON.parse(req.body).base; - return { head: { sha: 'cbd' }, labels: [], number: 1 }; - }, - '/repos/owner/my-repo/issues/1/labels': req => { - labels = JSON.parse(req.body).labels; - return {}; - }, - }; - mockAPI(api, responses); - - return expect( - api.editorialWorkflowGit([], { slug: 'entry', sha: 'abc' }, null, {}).then(() => ({ - prBaseBranch, - labels, - })), - ).resolves.toEqual({ prBaseBranch: 'gh-pages', labels: ['other/draft'] }); - }); - }); - - describe('updateTree', () => { - it('should create tree with nested paths', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - api.createTree = jest.fn().mockImplementation(() => Promise.resolve({ sha: 'newTreeSha' })); - - const files = [ - { path: '/static/media/new-image.jpeg', sha: null }, - { path: 'content/posts/new-post.md', sha: 'new-post.md' }, - ]; - - const baseTreeSha = 'baseTreeSha'; - - await expect(api.updateTree(baseTreeSha, files)).resolves.toEqual({ - sha: 'newTreeSha', - parentSha: baseTreeSha, - }); - - expect(api.createTree).toHaveBeenCalledTimes(1); - expect(api.createTree).toHaveBeenCalledWith(baseTreeSha, [ - { - path: 'static/media/new-image.jpeg', - mode: '100644', - type: 'blob', - sha: null, - }, - { - path: 'content/posts/new-post.md', - mode: '100644', - type: 'blob', - sha: 'new-post.md', - }, - ]); - }); - }); - - describe('request', () => { - beforeEach(() => { - const fetch = jest.fn(); - global.fetch = fetch; - }); - - afterEach(() => { - jest.resetAllMocks(); - }); - - it('should fetch url with authorization header', async () => { - const api = new API({ branch: 'gh-pages', repo: 'my-repo', token: 'token' }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue('some response'), - ok: true, - status: 200, - headers: { get: () => '' }, - }); - const result = await api.request('/some-path'); - expect(result).toEqual('some response'); - expect(fetch).toHaveBeenCalledTimes(1); - expect(fetch).toHaveBeenCalledWith('https://api.github.com/some-path', { - cache: 'no-cache', - headers: { - Authorization: 'token token', - 'Content-Type': 'application/json; charset=utf-8', - }, - signal: expect.any(AbortSignal), - }); - }); - - it('should throw error on not ok response', async () => { - const api = new API({ branch: 'gh-pages', repo: 'my-repo', token: 'token' }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue({ message: 'some error' }), - ok: false, - status: 404, - headers: { get: () => '' }, - }); - - await expect(api.request('some-path')).rejects.toThrow( - expect.objectContaining({ - message: 'some error', - name: 'API_ERROR', - status: 404, - api: 'GitHub', - }), - ); - }); - - it('should allow overriding requestHeaders to return a promise ', async () => { - const api = new API({ branch: 'gh-pages', repo: 'my-repo', token: 'token' }); - - api.requestHeaders = jest.fn().mockResolvedValue({ - Authorization: 'promise-token', - 'Content-Type': 'application/json; charset=utf-8', - }); - - fetch.mockResolvedValue({ - text: jest.fn().mockResolvedValue('some response'), - ok: true, - status: 200, - headers: { get: () => '' }, - }); - const result = await api.request('/some-path'); - expect(result).toEqual('some response'); - expect(fetch).toHaveBeenCalledTimes(1); - expect(fetch).toHaveBeenCalledWith('https://api.github.com/some-path', { - cache: 'no-cache', - headers: { - Authorization: 'promise-token', - 'Content-Type': 'application/json; charset=utf-8', - }, - signal: expect.any(AbortSignal), - }); - }); - }); - - describe('persistFiles', () => { - it('should update tree, commit and patch branch when useWorkflow is false', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const responses = { - // upload the file - '/repos/owner/repo/git/blobs': () => ({ sha: 'new-file-sha' }), - - // get the branch - '/repos/owner/repo/branches/master': () => ({ commit: { sha: 'root' } }), - - // create new tree - '/repos/owner/repo/git/trees': options => { - const data = JSON.parse(options.body); - return { sha: data.base_tree }; - }, - - // update the commit with the tree - '/repos/owner/repo/git/commits': () => ({ sha: 'commit-sha' }), - - // patch the branch - '/repos/owner/repo/git/refs/heads/master': () => ({}), - }; - mockAPI(api, responses); - - const entry = { - dataFiles: [ - { - slug: 'entry', - sha: 'abc', - path: 'content/posts/new-post.md', - raw: 'content', - }, - ], - assets: [], - }; - await api.persistFiles(entry.dataFiles, entry.assets, { commitMessage: 'commitMessage' }); - - expect(api.request).toHaveBeenCalledTimes(5); - - expect(api.request.mock.calls[0]).toEqual([ - '/repos/owner/repo/git/blobs', - { - method: 'POST', - body: JSON.stringify({ - content: Base64.encode(entry.dataFiles[0].raw), - encoding: 'base64', - }), - }, - ]); - - expect(api.request.mock.calls[1]).toEqual(['/repos/owner/repo/branches/master']); - - expect(api.request.mock.calls[2]).toEqual([ - '/repos/owner/repo/git/trees', - { - body: JSON.stringify({ - base_tree: 'root', - tree: [ - { - path: 'content/posts/new-post.md', - mode: '100644', - type: 'blob', - sha: 'new-file-sha', - }, - ], - }), - method: 'POST', - }, - ]); - - expect(api.request.mock.calls[3]).toEqual([ - '/repos/owner/repo/git/commits', - { - body: JSON.stringify({ - message: 'commitMessage', - tree: 'root', - parents: ['root'], - }), - method: 'POST', - }, - ]); - - expect(api.request.mock.calls[4]).toEqual([ - '/repos/owner/repo/git/refs/heads/master', - { - body: JSON.stringify({ - sha: 'commit-sha', - force: false, - }), - method: 'PATCH', - }, - ]); - }); - - it('should call editorialWorkflowGit when useWorkflow is true', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - api.uploadBlob = jest.fn(); - api.editorialWorkflowGit = jest.fn(); - - const entry = { - dataFiles: [ - { - slug: 'entry', - sha: 'abc', - path: 'content/posts/new-post.md', - raw: 'content', - }, - ], - assets: [ - { - path: '/static/media/image-1.png', - sha: 'image-1.png', - }, - { - path: '/static/media/image-2.png', - sha: 'image-2.png', - }, - ], - }; - - await api.persistFiles(entry.dataFiles, entry.assets, { useWorkflow: true }); - - expect(api.uploadBlob).toHaveBeenCalledTimes(3); - expect(api.uploadBlob).toHaveBeenCalledWith(entry.dataFiles[0]); - expect(api.uploadBlob).toHaveBeenCalledWith(entry.assets[0]); - expect(api.uploadBlob).toHaveBeenCalledWith(entry.assets[1]); - - expect(api.editorialWorkflowGit).toHaveBeenCalledTimes(1); - - expect(api.editorialWorkflowGit).toHaveBeenCalledWith( - entry.assets.concat(entry.dataFiles), - entry.dataFiles[0].slug, - [ - { path: 'static/media/image-1.png', sha: 'image-1.png' }, - { path: 'static/media/image-2.png', sha: 'image-2.png' }, - ], - { useWorkflow: true }, - ); - }); - }); - - describe('migratePullRequest', () => { - it('should migrate to pull request labels when no version', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const pr = { - head: { ref: 'cms/2019-11-11-post-title' }, - title: 'pr title', - number: 1, - labels: [], - }; - const metadata = { type: 'PR' }; - api.retrieveMetadataOld = jest.fn().mockResolvedValue(metadata); - const newBranch = 'cms/posts/2019-11-11-post-title'; - const migrateToVersion1Result = { - metadata: { ...metadata, branch: newBranch, version: '1' }, - pullRequest: { ...pr, number: 2 }, - }; - api.migrateToVersion1 = jest.fn().mockResolvedValue(migrateToVersion1Result); - api.migrateToPullRequestLabels = jest.fn(); - - await api.migratePullRequest(pr); - - expect(api.migrateToVersion1).toHaveBeenCalledTimes(1); - expect(api.migrateToVersion1).toHaveBeenCalledWith(pr, metadata); - - expect(api.migrateToPullRequestLabels).toHaveBeenCalledTimes(1); - expect(api.migrateToPullRequestLabels).toHaveBeenCalledWith( - migrateToVersion1Result.pullRequest, - migrateToVersion1Result.metadata, - ); - - expect(api.retrieveMetadataOld).toHaveBeenCalledTimes(1); - expect(api.retrieveMetadataOld).toHaveBeenCalledWith('2019-11-11-post-title'); - }); - - it('should migrate to pull request labels when version is 1', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - api.migrateToVersion1 = jest.fn(); - const pr = { - head: { ref: 'cms/posts/2019-11-11-post-title' }, - title: 'pr title', - number: 1, - labels: [], - }; - const metadata = { type: 'PR', version: '1' }; - api.retrieveMetadataOld = jest.fn().mockResolvedValue(metadata); - api.migrateToPullRequestLabels = jest.fn().mockResolvedValue(pr, metadata); - - await api.migratePullRequest(pr); - - expect(api.migrateToVersion1).toHaveBeenCalledTimes(0); - - expect(api.migrateToPullRequestLabels).toHaveBeenCalledTimes(1); - expect(api.migrateToPullRequestLabels).toHaveBeenCalledWith(pr, metadata); - - expect(api.retrieveMetadataOld).toHaveBeenCalledTimes(1); - expect(api.retrieveMetadataOld).toHaveBeenCalledWith('posts/2019-11-11-post-title'); - }); - }); - - describe('migrateToVersion1', () => { - it('should migrate to version 1', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const pr = { - head: { ref: 'cms/2019-11-11-post-title', sha: 'pr_head' }, - title: 'pr title', - number: 1, - labels: [], - }; - - const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' }; - api.createBranch = jest.fn().mockResolvedValue(newBranch); - api.getBranch = jest.fn().mockRejectedValue(new Error('Branch not found')); - - const newPr = { ...pr, number: 2 }; - api.createPR = jest.fn().mockResolvedValue(newPr); - api.getPullRequests = jest.fn().mockResolvedValue([]); - - api.storeMetadata = jest.fn(); - api.closePR = jest.fn(); - api.deleteBranch = jest.fn(); - api.deleteMetadata = jest.fn(); - - const branch = 'cms/2019-11-11-post-title'; - const metadata = { - branch, - type: 'PR', - pr: { head: pr.head.sha }, - commitMessage: 'commitMessage', - collection: 'posts', - }; - - const expectedMetadata = { - type: 'PR', - pr: { head: newPr.head.sha, number: 2 }, - commitMessage: 'commitMessage', - collection: 'posts', - branch: 'cms/posts/2019-11-11-post-title', - version: '1', - }; - await expect(api.migrateToVersion1(pr, metadata)).resolves.toEqual({ - metadata: expectedMetadata, - pullRequest: newPr, - }); - - expect(api.getBranch).toHaveBeenCalledTimes(1); - expect(api.getBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title'); - expect(api.createBranch).toHaveBeenCalledTimes(1); - expect(api.createBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title', 'pr_head'); - - expect(api.getPullRequests).toHaveBeenCalledTimes(1); - expect(api.getPullRequests).toHaveBeenCalledWith( - 'cms/posts/2019-11-11-post-title', - 'all', - expect.any(Function), - ); - expect(api.createPR).toHaveBeenCalledTimes(1); - expect(api.createPR).toHaveBeenCalledWith('pr title', 'cms/posts/2019-11-11-post-title'); - - expect(api.storeMetadata).toHaveBeenCalledTimes(1); - expect(api.storeMetadata).toHaveBeenCalledWith( - 'posts/2019-11-11-post-title', - expectedMetadata, - ); - - expect(api.closePR).toHaveBeenCalledTimes(1); - expect(api.closePR).toHaveBeenCalledWith(pr.number); - - expect(api.deleteBranch).toHaveBeenCalledTimes(1); - expect(api.deleteBranch).toHaveBeenCalledWith('cms/2019-11-11-post-title'); - - expect(api.deleteMetadata).toHaveBeenCalledTimes(1); - expect(api.deleteMetadata).toHaveBeenCalledWith('2019-11-11-post-title'); - }); - - it('should not create new branch if exists', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const pr = { - head: { ref: 'cms/2019-11-11-post-title', sha: 'pr_head' }, - title: 'pr title', - number: 1, - labels: [], - }; - - const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' }; - api.createBranch = jest.fn(); - api.getBranch = jest.fn().mockResolvedValue(newBranch); - - const newPr = { ...pr, number: 2 }; - api.createPR = jest.fn().mockResolvedValue(newPr); - api.getPullRequests = jest.fn().mockResolvedValue([]); - - api.storeMetadata = jest.fn(); - api.closePR = jest.fn(); - api.deleteBranch = jest.fn(); - api.deleteMetadata = jest.fn(); - - const branch = 'cms/2019-11-11-post-title'; - const metadata = { - branch, - type: 'PR', - pr: { head: pr.head.sha }, - commitMessage: 'commitMessage', - collection: 'posts', - }; - - const expectedMetadata = { - type: 'PR', - pr: { head: newPr.head.sha, number: 2 }, - commitMessage: 'commitMessage', - collection: 'posts', - branch: 'cms/posts/2019-11-11-post-title', - version: '1', - }; - await expect(api.migrateToVersion1(pr, metadata)).resolves.toEqual({ - metadata: expectedMetadata, - pullRequest: newPr, - }); - - expect(api.getBranch).toHaveBeenCalledTimes(1); - expect(api.getBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title'); - expect(api.createBranch).toHaveBeenCalledTimes(0); - - expect(api.getPullRequests).toHaveBeenCalledTimes(1); - expect(api.getPullRequests).toHaveBeenCalledWith( - 'cms/posts/2019-11-11-post-title', - 'all', - expect.any(Function), - ); - expect(api.createPR).toHaveBeenCalledTimes(1); - expect(api.createPR).toHaveBeenCalledWith('pr title', 'cms/posts/2019-11-11-post-title'); - - expect(api.storeMetadata).toHaveBeenCalledTimes(1); - expect(api.storeMetadata).toHaveBeenCalledWith( - 'posts/2019-11-11-post-title', - expectedMetadata, - ); - - expect(api.closePR).toHaveBeenCalledTimes(1); - expect(api.closePR).toHaveBeenCalledWith(pr.number); - - expect(api.deleteBranch).toHaveBeenCalledTimes(1); - expect(api.deleteBranch).toHaveBeenCalledWith('cms/2019-11-11-post-title'); - - expect(api.deleteMetadata).toHaveBeenCalledTimes(1); - expect(api.deleteMetadata).toHaveBeenCalledWith('2019-11-11-post-title'); - }); - - it('should not create new pr if exists', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const pr = { - head: { ref: 'cms/2019-11-11-post-title', sha: 'pr_head' }, - title: 'pr title', - number: 1, - labels: [], - }; - - const newBranch = { ref: 'refs/heads/cms/posts/2019-11-11-post-title' }; - api.createBranch = jest.fn(); - api.getBranch = jest.fn().mockResolvedValue(newBranch); - - const newPr = { ...pr, number: 2 }; - api.createPR = jest.fn(); - api.getPullRequests = jest.fn().mockResolvedValue([newPr]); - - api.storeMetadata = jest.fn(); - api.closePR = jest.fn(); - api.deleteBranch = jest.fn(); - api.deleteMetadata = jest.fn(); - - const branch = 'cms/2019-11-11-post-title'; - const metadata = { - branch, - type: 'PR', - pr: { head: pr.head.sha }, - commitMessage: 'commitMessage', - collection: 'posts', - }; - - const expectedMetadata = { - type: 'PR', - pr: { head: newPr.head.sha, number: 2 }, - commitMessage: 'commitMessage', - collection: 'posts', - branch: 'cms/posts/2019-11-11-post-title', - version: '1', - }; - await expect(api.migrateToVersion1(pr, metadata)).resolves.toEqual({ - metadata: expectedMetadata, - pullRequest: newPr, - }); - - expect(api.getBranch).toHaveBeenCalledTimes(1); - expect(api.getBranch).toHaveBeenCalledWith('cms/posts/2019-11-11-post-title'); - expect(api.createBranch).toHaveBeenCalledTimes(0); - - expect(api.getPullRequests).toHaveBeenCalledTimes(1); - expect(api.getPullRequests).toHaveBeenCalledWith( - 'cms/posts/2019-11-11-post-title', - 'all', - expect.any(Function), - ); - expect(api.createPR).toHaveBeenCalledTimes(0); - - expect(api.storeMetadata).toHaveBeenCalledTimes(1); - expect(api.storeMetadata).toHaveBeenCalledWith( - 'posts/2019-11-11-post-title', - expectedMetadata, - ); - - expect(api.closePR).toHaveBeenCalledTimes(1); - expect(api.closePR).toHaveBeenCalledWith(pr.number); - - expect(api.deleteBranch).toHaveBeenCalledTimes(1); - expect(api.deleteBranch).toHaveBeenCalledWith('cms/2019-11-11-post-title'); - - expect(api.deleteMetadata).toHaveBeenCalledTimes(1); - expect(api.deleteMetadata).toHaveBeenCalledWith('2019-11-11-post-title'); - }); - }); - - describe('migrateToPullRequestLabels', () => { - it('should migrate to pull request labels', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const pr = { - head: { ref: 'cms/posts/2019-11-11-post-title', sha: 'pr_head' }, - title: 'pr title', - number: 1, - labels: [], - }; - - api.setPullRequestStatus = jest.fn(); - api.deleteMetadata = jest.fn(); - - const metadata = { - branch: pr.head.ref, - type: 'PR', - pr: { head: pr.head.sha }, - commitMessage: 'commitMessage', - collection: 'posts', - status: 'pending_review', - }; - - await api.migrateToPullRequestLabels(pr, metadata); - - expect(api.setPullRequestStatus).toHaveBeenCalledTimes(1); - expect(api.setPullRequestStatus).toHaveBeenCalledWith(pr, 'pending_review'); - - expect(api.deleteMetadata).toHaveBeenCalledTimes(1); - expect(api.deleteMetadata).toHaveBeenCalledWith('posts/2019-11-11-post-title'); - }); - }); - - describe('rebaseSingleCommit', () => { - it('should create updated tree and commit', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - api.getDifferences = jest.fn().mockResolvedValueOnce({ - files: [ - { filename: 'removed.md', status: 'removed', sha: 'removed_sha' }, - { - filename: 'renamed.md', - status: 'renamed', - previous_filename: 'previous_filename.md', - sha: 'renamed_sha', - }, - { filename: 'added.md', status: 'added', sha: 'added_sha' }, - ], - }); - - const newTree = { sha: 'new_tree_sha' }; - api.updateTree = jest.fn().mockResolvedValueOnce(newTree); - - const newCommit = { sha: 'newCommit' }; - api.createCommit = jest.fn().mockResolvedValueOnce(newCommit); - - const baseCommit = { sha: 'base_commit_sha' }; - const commit = { - sha: 'sha', - parents: [{ sha: 'parent_sha' }], - commit: { - message: 'message', - author: { name: 'author' }, - committer: { name: 'committer' }, - }, - }; - - await expect(api.rebaseSingleCommit(baseCommit, commit)).resolves.toBe(newCommit); - - expect(api.getDifferences).toHaveBeenCalledTimes(1); - expect(api.getDifferences).toHaveBeenCalledWith('parent_sha', 'sha'); - - expect(api.updateTree).toHaveBeenCalledTimes(1); - expect(api.updateTree).toHaveBeenCalledWith('base_commit_sha', [ - { path: 'removed.md', sha: null }, - { path: 'previous_filename.md', sha: null }, - { path: 'renamed.md', sha: 'renamed_sha' }, - { path: 'added.md', sha: 'added_sha' }, - ]); - - expect(api.createCommit).toHaveBeenCalledTimes(1); - expect(api.createCommit).toHaveBeenCalledWith( - 'message', - newTree.sha, - [baseCommit.sha], - { name: 'author' }, - { name: 'committer' }, - ); - }); - }); - - describe('listFiles', () => { - it('should get files by depth', async () => { - const api = new API({ branch: 'master', repo: 'owner/repo' }); - - const tree = [ - { - path: 'post.md', - type: 'blob', - }, - { - path: 'dir1', - type: 'tree', - }, - { - path: 'dir1/nested-post.md', - type: 'blob', - }, - { - path: 'dir1/dir2', - type: 'tree', - }, - { - path: 'dir1/dir2/nested-post.md', - type: 'blob', - }, - ]; - api.request = jest.fn().mockResolvedValue({ tree }); - - await expect(api.listFiles('posts', { depth: 1 })).resolves.toEqual([ - { - path: 'posts/post.md', - type: 'blob', - name: 'post.md', - }, - ]); - expect(api.request).toHaveBeenCalledTimes(1); - expect(api.request).toHaveBeenCalledWith('/repos/owner/repo/git/trees/master:posts', { - params: {}, - }); - - jest.clearAllMocks(); - await expect(api.listFiles('posts', { depth: 2 })).resolves.toEqual([ - { - path: 'posts/post.md', - type: 'blob', - name: 'post.md', - }, - { - path: 'posts/dir1/nested-post.md', - type: 'blob', - name: 'nested-post.md', - }, - ]); - expect(api.request).toHaveBeenCalledTimes(1); - expect(api.request).toHaveBeenCalledWith('/repos/owner/repo/git/trees/master:posts', { - params: { recursive: 1 }, - }); - - jest.clearAllMocks(); - await expect(api.listFiles('posts', { depth: 3 })).resolves.toEqual([ - { - path: 'posts/post.md', - type: 'blob', - name: 'post.md', - }, - { - path: 'posts/dir1/nested-post.md', - type: 'blob', - name: 'nested-post.md', - }, - { - path: 'posts/dir1/dir2/nested-post.md', - type: 'blob', - name: 'nested-post.md', - }, - ]); - expect(api.request).toHaveBeenCalledTimes(1); - expect(api.request).toHaveBeenCalledWith('/repos/owner/repo/git/trees/master:posts', { - params: { recursive: 1 }, - }); - }); - }); - - test('should get preview statuses', async () => { - const api = new API({ repo: 'repo' }); - - const statuses = [ - { context: 'deploy', state: 'success', target_url: 'deploy-url' }, - { context: 'build', state: 'error' }, - ]; - - api.request = jest.fn(() => Promise.resolve({ statuses })); - const sha = 'sha'; - api.getBranchPullRequest = jest.fn(() => Promise.resolve({ head: { sha } })); - - const collection = 'collection'; - const slug = 'slug'; - await expect(api.getStatuses(collection, slug)).resolves.toEqual([ - { context: 'deploy', state: 'success', target_url: 'deploy-url' }, - { context: 'build', state: 'other' }, - ]); - - expect(api.getBranchPullRequest).toHaveBeenCalledTimes(1); - expect(api.getBranchPullRequest).toHaveBeenCalledWith('cms/collection/slug'); - expect(api.request).toHaveBeenCalledTimes(1); - expect(api.request).toHaveBeenCalledWith(`/repos/repo/commits/${sha}/status`); - }); -}); diff --git a/packages/netlify-cms-backend-github/src/__tests__/GraphQLAPI.spec.js b/packages/netlify-cms-backend-github/src/__tests__/GraphQLAPI.spec.js deleted file mode 100644 index bb1e77ae..00000000 --- a/packages/netlify-cms-backend-github/src/__tests__/GraphQLAPI.spec.js +++ /dev/null @@ -1,69 +0,0 @@ -import GraphQLAPI from '../GraphQLAPI'; - -global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests')); - -describe('github GraphQL API', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('editorialWorkflowGit', () => { - it('should should flatten nested tree into a list of files', () => { - const api = new GraphQLAPI({ branch: 'gh-pages', repo: 'owner/my-repo' }); - const entries = [ - { - name: 'post-1.md', - sha: 'sha-1', - type: 'blob', - blob: { size: 1 }, - }, - { - name: 'post-2.md', - sha: 'sha-2', - type: 'blob', - blob: { size: 2 }, - }, - { - name: '2019', - sha: 'dir-sha', - type: 'tree', - object: { - entries: [ - { - name: 'nested-post.md', - sha: 'nested-post-sha', - type: 'blob', - blob: { size: 3 }, - }, - ], - }, - }, - ]; - const path = 'posts'; - - expect(api.getAllFiles(entries, path)).toEqual([ - { - name: 'post-1.md', - id: 'sha-1', - type: 'blob', - size: 1, - path: 'posts/post-1.md', - }, - { - name: 'post-2.md', - id: 'sha-2', - type: 'blob', - size: 2, - path: 'posts/post-2.md', - }, - { - name: 'nested-post.md', - id: 'nested-post-sha', - type: 'blob', - size: 3, - path: 'posts/2019/nested-post.md', - }, - ]); - }); - }); -}); diff --git a/packages/netlify-cms-backend-github/src/__tests__/implementation.spec.js b/packages/netlify-cms-backend-github/src/__tests__/implementation.spec.js deleted file mode 100644 index 6c7f3fd7..00000000 --- a/packages/netlify-cms-backend-github/src/__tests__/implementation.spec.js +++ /dev/null @@ -1,361 +0,0 @@ -import { Cursor, CURSOR_COMPATIBILITY_SYMBOL } from 'netlify-cms-lib-util'; - -import GitHubImplementation from '../implementation'; - -jest.spyOn(console, 'error').mockImplementation(() => {}); - -describe('github backend implementation', () => { - const config = { - backend: { - repo: 'owner/repo', - open_authoring: false, - api_root: 'https://api.github.com', - }, - }; - - const createObjectURL = jest.fn(); - global.URL = { - createObjectURL, - }; - - createObjectURL.mockReturnValue('displayURL'); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('forkExists', () => { - it('should return true when repo is fork and parent matches originRepo', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' }); - - global.fetch = jest.fn().mockResolvedValue({ - // matching should be case-insensitive - json: () => ({ fork: true, parent: { full_name: 'OWNER/REPO' } }), - }); - - await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(true); - - expect(gitHubImplementation.currentUser).toHaveBeenCalledTimes(1); - expect(gitHubImplementation.currentUser).toHaveBeenCalledWith({ token: 'token' }); - expect(global.fetch).toHaveBeenCalledTimes(1); - expect(global.fetch).toHaveBeenCalledWith('https://api.github.com/repos/login/repo', { - method: 'GET', - headers: { - Authorization: 'token token', - }, - signal: expect.any(AbortSignal), - }); - }); - - it('should return false when repo is not a fork', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' }); - - global.fetch = jest.fn().mockResolvedValue({ - // matching should be case-insensitive - json: () => ({ fork: false }), - }); - - expect.assertions(1); - await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(false); - }); - - it("should return false when parent doesn't match originRepo", async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.currentUser = jest.fn().mockResolvedValue({ login: 'login' }); - - global.fetch = jest.fn().mockResolvedValue({ - json: () => ({ fork: true, parent: { full_name: 'owner/other_repo' } }), - }); - - expect.assertions(1); - await expect(gitHubImplementation.forkExists({ token: 'token' })).resolves.toBe(false); - }); - }); - - describe('persistMedia', () => { - const persistFiles = jest.fn(); - const mockAPI = { - persistFiles, - }; - - persistFiles.mockImplementation((_, files) => { - files.forEach((file, index) => { - file.sha = index; - }); - }); - - it('should persist media file', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const mediaFile = { - fileObj: { size: 100, name: 'image.png' }, - path: '/media/image.png', - }; - - expect.assertions(5); - await expect(gitHubImplementation.persistMedia(mediaFile, {})).resolves.toEqual({ - id: 0, - name: 'image.png', - size: 100, - displayURL: 'displayURL', - path: 'media/image.png', - }); - - expect(persistFiles).toHaveBeenCalledTimes(1); - expect(persistFiles).toHaveBeenCalledWith([], [mediaFile], {}); - expect(createObjectURL).toHaveBeenCalledTimes(1); - expect(createObjectURL).toHaveBeenCalledWith(mediaFile.fileObj); - }); - - it('should log and throw error on "persistFiles" error', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const error = new Error('failed to persist files'); - persistFiles.mockRejectedValue(error); - - const mediaFile = { - value: 'image.png', - fileObj: { size: 100 }, - path: '/media/image.png', - }; - - expect.assertions(5); - await expect(gitHubImplementation.persistMedia(mediaFile)).rejects.toThrowError(error); - - expect(persistFiles).toHaveBeenCalledTimes(1); - expect(createObjectURL).toHaveBeenCalledTimes(0); - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledWith(error); - }); - }); - - describe('unpublishedEntry', () => { - const generateContentKey = jest.fn(); - const retrieveUnpublishedEntryData = jest.fn(); - - const mockAPI = { - generateContentKey, - retrieveUnpublishedEntryData, - }; - - it('should return unpublished entry data', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - gitHubImplementation.loadEntryMediaFiles = jest - .fn() - .mockResolvedValue([{ path: 'image.png', id: 'sha' }]); - - generateContentKey.mockReturnValue('contentKey'); - - const data = { - collection: 'collection', - slug: 'slug', - status: 'draft', - diffs: [], - updatedAt: 'updatedAt', - }; - retrieveUnpublishedEntryData.mockResolvedValue(data); - - const collection = 'posts'; - const slug = 'slug'; - await expect(gitHubImplementation.unpublishedEntry({ collection, slug })).resolves.toEqual( - data, - ); - - expect(generateContentKey).toHaveBeenCalledTimes(1); - expect(generateContentKey).toHaveBeenCalledWith('posts', 'slug'); - - expect(retrieveUnpublishedEntryData).toHaveBeenCalledTimes(1); - expect(retrieveUnpublishedEntryData).toHaveBeenCalledWith('contentKey'); - }); - }); - - describe('entriesByFolder', () => { - const listFiles = jest.fn(); - const readFile = jest.fn(); - const readFileMetadata = jest.fn(() => Promise.resolve({ author: '', updatedOn: '' })); - - const mockAPI = { - listFiles, - readFile, - readFileMetadata, - originRepoURL: 'originRepoURL', - }; - - it('should return entries and cursor', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const files = []; - const count = 1501; - for (let i = 0; i < count; i++) { - const id = `${i}`.padStart(`${count}`.length, '0'); - files.push({ - id, - path: `posts/post-${id}.md`, - }); - } - - listFiles.mockResolvedValue(files); - readFile.mockImplementation((path, id) => Promise.resolve(`${id}`)); - - const expectedEntries = files - .slice(0, 20) - .map(({ id, path }) => ({ data: id, file: { path, id, author: '', updatedOn: '' } })); - - const expectedCursor = Cursor.create({ - actions: ['next', 'last'], - meta: { page: 1, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - expectedEntries[CURSOR_COMPATIBILITY_SYMBOL] = expectedCursor; - - const result = await gitHubImplementation.entriesByFolder('posts', 'md', 1); - - expect(result).toEqual(expectedEntries); - expect(listFiles).toHaveBeenCalledTimes(1); - expect(listFiles).toHaveBeenCalledWith('posts', { depth: 1, repoURL: 'originRepoURL' }); - expect(readFile).toHaveBeenCalledTimes(20); - }); - }); - - describe('traverseCursor', () => { - const listFiles = jest.fn(); - const readFile = jest.fn((path, id) => Promise.resolve(`${id}`)); - const readFileMetadata = jest.fn(() => Promise.resolve({})); - - const mockAPI = { - listFiles, - readFile, - originRepoURL: 'originRepoURL', - readFileMetadata, - }; - - const files = []; - const count = 1501; - for (let i = 0; i < count; i++) { - const id = `${i}`.padStart(`${count}`.length, '0'); - files.push({ - id, - path: `posts/post-${id}.md`, - }); - } - - it('should handle next action', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const cursor = Cursor.create({ - actions: ['next', 'last'], - meta: { page: 1, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const expectedEntries = files - .slice(20, 40) - .map(({ id, path }) => ({ data: id, file: { path, id } })); - - const expectedCursor = Cursor.create({ - actions: ['prev', 'first', 'next', 'last'], - meta: { page: 2, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const result = await gitHubImplementation.traverseCursor(cursor, 'next'); - - expect(result).toEqual({ - entries: expectedEntries, - cursor: expectedCursor, - }); - }); - - it('should handle prev action', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const cursor = Cursor.create({ - actions: ['prev', 'first', 'next', 'last'], - meta: { page: 2, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const expectedEntries = files - .slice(0, 20) - .map(({ id, path }) => ({ data: id, file: { path, id } })); - - const expectedCursor = Cursor.create({ - actions: ['next', 'last'], - meta: { page: 1, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const result = await gitHubImplementation.traverseCursor(cursor, 'prev'); - - expect(result).toEqual({ - entries: expectedEntries, - cursor: expectedCursor, - }); - }); - - it('should handle last action', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const cursor = Cursor.create({ - actions: ['next', 'last'], - meta: { page: 1, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const expectedEntries = files - .slice(1500) - .map(({ id, path }) => ({ data: id, file: { path, id } })); - - const expectedCursor = Cursor.create({ - actions: ['prev', 'first'], - meta: { page: 76, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const result = await gitHubImplementation.traverseCursor(cursor, 'last'); - - expect(result).toEqual({ - entries: expectedEntries, - cursor: expectedCursor, - }); - }); - - it('should handle first action', async () => { - const gitHubImplementation = new GitHubImplementation(config); - gitHubImplementation.api = mockAPI; - - const cursor = Cursor.create({ - actions: ['prev', 'first'], - meta: { page: 76, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const expectedEntries = files - .slice(0, 20) - .map(({ id, path }) => ({ data: id, file: { path, id } })); - - const expectedCursor = Cursor.create({ - actions: ['next', 'last'], - meta: { page: 1, count, pageSize: 20, pageCount: 76 }, - data: { files }, - }); - - const result = await gitHubImplementation.traverseCursor(cursor, 'first'); - - expect(result).toEqual({ - entries: expectedEntries, - cursor: expectedCursor, - }); - }); - }); -}); diff --git a/packages/netlify-cms-backend-github/src/fragmentTypes.js b/packages/netlify-cms-backend-github/src/fragmentTypes.js deleted file mode 100644 index 2a654d96..00000000 --- a/packages/netlify-cms-backend-github/src/fragmentTypes.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {"__schema":{"types":[{"kind":"INTERFACE","name":"Node","possibleTypes":[{"name":"AddedToProjectEvent"},{"name":"App"},{"name":"AssignedEvent"},{"name":"BaseRefChangedEvent"},{"name":"BaseRefForcePushedEvent"},{"name":"Blob"},{"name":"Bot"},{"name":"BranchProtectionRule"},{"name":"ClosedEvent"},{"name":"CodeOfConduct"},{"name":"CommentDeletedEvent"},{"name":"Commit"},{"name":"CommitComment"},{"name":"CommitCommentThread"},{"name":"ConvertedNoteToIssueEvent"},{"name":"CrossReferencedEvent"},{"name":"DemilestonedEvent"},{"name":"DeployKey"},{"name":"DeployedEvent"},{"name":"Deployment"},{"name":"DeploymentEnvironmentChangedEvent"},{"name":"DeploymentStatus"},{"name":"ExternalIdentity"},{"name":"Gist"},{"name":"GistComment"},{"name":"HeadRefDeletedEvent"},{"name":"HeadRefForcePushedEvent"},{"name":"HeadRefRestoredEvent"},{"name":"Issue"},{"name":"IssueComment"},{"name":"Label"},{"name":"LabeledEvent"},{"name":"Language"},{"name":"License"},{"name":"LockedEvent"},{"name":"Mannequin"},{"name":"MarketplaceCategory"},{"name":"MarketplaceListing"},{"name":"MentionedEvent"},{"name":"MergedEvent"},{"name":"Milestone"},{"name":"MilestonedEvent"},{"name":"MovedColumnsInProjectEvent"},{"name":"Organization"},{"name":"OrganizationIdentityProvider"},{"name":"OrganizationInvitation"},{"name":"PinnedEvent"},{"name":"Project"},{"name":"ProjectCard"},{"name":"ProjectColumn"},{"name":"PublicKey"},{"name":"PullRequest"},{"name":"PullRequestCommit"},{"name":"PullRequestCommitCommentThread"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"},{"name":"PullRequestReviewThread"},{"name":"PushAllowance"},{"name":"Reaction"},{"name":"ReadyForReviewEvent"},{"name":"Ref"},{"name":"ReferencedEvent"},{"name":"RegistryPackage"},{"name":"RegistryPackageDependency"},{"name":"RegistryPackageFile"},{"name":"RegistryPackageTag"},{"name":"RegistryPackageVersion"},{"name":"Release"},{"name":"ReleaseAsset"},{"name":"RemovedFromProjectEvent"},{"name":"RenamedTitleEvent"},{"name":"ReopenedEvent"},{"name":"Repository"},{"name":"RepositoryInvitation"},{"name":"RepositoryTopic"},{"name":"ReviewDismissalAllowance"},{"name":"ReviewDismissedEvent"},{"name":"ReviewRequest"},{"name":"ReviewRequestRemovedEvent"},{"name":"ReviewRequestedEvent"},{"name":"SavedReply"},{"name":"SecurityAdvisory"},{"name":"SponsorsListing"},{"name":"Sponsorship"},{"name":"Status"},{"name":"StatusContext"},{"name":"SubscribedEvent"},{"name":"Tag"},{"name":"Team"},{"name":"Topic"},{"name":"TransferredEvent"},{"name":"Tree"},{"name":"UnassignedEvent"},{"name":"UnlabeledEvent"},{"name":"UnlockedEvent"},{"name":"UnpinnedEvent"},{"name":"UnsubscribedEvent"},{"name":"User"},{"name":"UserBlockedEvent"},{"name":"UserContentEdit"},{"name":"UserStatus"}]},{"kind":"INTERFACE","name":"UniformResourceLocatable","possibleTypes":[{"name":"Bot"},{"name":"ClosedEvent"},{"name":"Commit"},{"name":"CrossReferencedEvent"},{"name":"Gist"},{"name":"Issue"},{"name":"Mannequin"},{"name":"MergedEvent"},{"name":"Milestone"},{"name":"Organization"},{"name":"PullRequest"},{"name":"PullRequestCommit"},{"name":"ReadyForReviewEvent"},{"name":"Release"},{"name":"Repository"},{"name":"RepositoryTopic"},{"name":"ReviewDismissedEvent"},{"name":"User"}]},{"kind":"INTERFACE","name":"Actor","possibleTypes":[{"name":"Bot"},{"name":"Mannequin"},{"name":"Organization"},{"name":"User"}]},{"kind":"INTERFACE","name":"RegistryPackageOwner","possibleTypes":[{"name":"Organization"},{"name":"Repository"},{"name":"User"}]},{"kind":"INTERFACE","name":"ProjectOwner","possibleTypes":[{"name":"Organization"},{"name":"Repository"},{"name":"User"}]},{"kind":"INTERFACE","name":"Closable","possibleTypes":[{"name":"Issue"},{"name":"Milestone"},{"name":"Project"},{"name":"PullRequest"}]},{"kind":"INTERFACE","name":"Updatable","possibleTypes":[{"name":"CommitComment"},{"name":"GistComment"},{"name":"Issue"},{"name":"IssueComment"},{"name":"Project"},{"name":"PullRequest"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"UNION","name":"ProjectCardItem","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"INTERFACE","name":"Assignable","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"INTERFACE","name":"Comment","possibleTypes":[{"name":"CommitComment"},{"name":"GistComment"},{"name":"Issue"},{"name":"IssueComment"},{"name":"PullRequest"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"INTERFACE","name":"UpdatableComment","possibleTypes":[{"name":"CommitComment"},{"name":"GistComment"},{"name":"Issue"},{"name":"IssueComment"},{"name":"PullRequest"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"INTERFACE","name":"Labelable","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"INTERFACE","name":"Lockable","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"INTERFACE","name":"RegistryPackageSearch","possibleTypes":[{"name":"Organization"},{"name":"User"}]},{"kind":"INTERFACE","name":"RepositoryOwner","possibleTypes":[{"name":"Organization"},{"name":"User"}]},{"kind":"INTERFACE","name":"MemberStatusable","possibleTypes":[{"name":"Organization"},{"name":"Team"}]},{"kind":"INTERFACE","name":"ProfileOwner","possibleTypes":[{"name":"Organization"},{"name":"User"}]},{"kind":"UNION","name":"PinnableItem","possibleTypes":[{"name":"Gist"},{"name":"Repository"}]},{"kind":"INTERFACE","name":"Starrable","possibleTypes":[{"name":"Gist"},{"name":"Repository"},{"name":"Topic"}]},{"kind":"INTERFACE","name":"RepositoryInfo","possibleTypes":[{"name":"Repository"}]},{"kind":"INTERFACE","name":"GitObject","possibleTypes":[{"name":"Blob"},{"name":"Commit"},{"name":"Tag"},{"name":"Tree"}]},{"kind":"INTERFACE","name":"RepositoryNode","possibleTypes":[{"name":"CommitComment"},{"name":"CommitCommentThread"},{"name":"Issue"},{"name":"IssueComment"},{"name":"PullRequest"},{"name":"PullRequestCommitCommentThread"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"INTERFACE","name":"Subscribable","possibleTypes":[{"name":"Commit"},{"name":"Issue"},{"name":"PullRequest"},{"name":"Repository"},{"name":"Team"}]},{"kind":"INTERFACE","name":"Deletable","possibleTypes":[{"name":"CommitComment"},{"name":"GistComment"},{"name":"IssueComment"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"INTERFACE","name":"Reactable","possibleTypes":[{"name":"CommitComment"},{"name":"Issue"},{"name":"IssueComment"},{"name":"PullRequest"},{"name":"PullRequestReview"},{"name":"PullRequestReviewComment"}]},{"kind":"INTERFACE","name":"GitSignature","possibleTypes":[{"name":"GpgSignature"},{"name":"SmimeSignature"},{"name":"UnknownSignature"}]},{"kind":"UNION","name":"RequestedReviewer","possibleTypes":[{"name":"User"},{"name":"Team"},{"name":"Mannequin"}]},{"kind":"UNION","name":"PullRequestTimelineItem","possibleTypes":[{"name":"Commit"},{"name":"CommitCommentThread"},{"name":"PullRequestReview"},{"name":"PullRequestReviewThread"},{"name":"PullRequestReviewComment"},{"name":"IssueComment"},{"name":"ClosedEvent"},{"name":"ReopenedEvent"},{"name":"SubscribedEvent"},{"name":"UnsubscribedEvent"},{"name":"MergedEvent"},{"name":"ReferencedEvent"},{"name":"CrossReferencedEvent"},{"name":"AssignedEvent"},{"name":"UnassignedEvent"},{"name":"LabeledEvent"},{"name":"UnlabeledEvent"},{"name":"MilestonedEvent"},{"name":"DemilestonedEvent"},{"name":"RenamedTitleEvent"},{"name":"LockedEvent"},{"name":"UnlockedEvent"},{"name":"DeployedEvent"},{"name":"DeploymentEnvironmentChangedEvent"},{"name":"HeadRefDeletedEvent"},{"name":"HeadRefRestoredEvent"},{"name":"HeadRefForcePushedEvent"},{"name":"BaseRefForcePushedEvent"},{"name":"ReviewRequestedEvent"},{"name":"ReviewRequestRemovedEvent"},{"name":"ReviewDismissedEvent"},{"name":"UserBlockedEvent"}]},{"kind":"UNION","name":"Closer","possibleTypes":[{"name":"Commit"},{"name":"PullRequest"}]},{"kind":"UNION","name":"ReferencedSubject","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"UNION","name":"Assignee","possibleTypes":[{"name":"Bot"},{"name":"Mannequin"},{"name":"Organization"},{"name":"User"}]},{"kind":"UNION","name":"MilestoneItem","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"UNION","name":"RenamedTitleSubject","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"UNION","name":"PullRequestTimelineItems","possibleTypes":[{"name":"PullRequestCommit"},{"name":"PullRequestCommitCommentThread"},{"name":"PullRequestReview"},{"name":"PullRequestReviewThread"},{"name":"PullRequestRevisionMarker"},{"name":"BaseRefChangedEvent"},{"name":"BaseRefForcePushedEvent"},{"name":"DeployedEvent"},{"name":"DeploymentEnvironmentChangedEvent"},{"name":"HeadRefDeletedEvent"},{"name":"HeadRefForcePushedEvent"},{"name":"HeadRefRestoredEvent"},{"name":"MergedEvent"},{"name":"ReviewDismissedEvent"},{"name":"ReviewRequestedEvent"},{"name":"ReviewRequestRemovedEvent"},{"name":"ReadyForReviewEvent"},{"name":"IssueComment"},{"name":"CrossReferencedEvent"},{"name":"AddedToProjectEvent"},{"name":"AssignedEvent"},{"name":"ClosedEvent"},{"name":"CommentDeletedEvent"},{"name":"ConvertedNoteToIssueEvent"},{"name":"DemilestonedEvent"},{"name":"LabeledEvent"},{"name":"LockedEvent"},{"name":"MentionedEvent"},{"name":"MilestonedEvent"},{"name":"MovedColumnsInProjectEvent"},{"name":"PinnedEvent"},{"name":"ReferencedEvent"},{"name":"RemovedFromProjectEvent"},{"name":"RenamedTitleEvent"},{"name":"ReopenedEvent"},{"name":"SubscribedEvent"},{"name":"TransferredEvent"},{"name":"UnassignedEvent"},{"name":"UnlabeledEvent"},{"name":"UnlockedEvent"},{"name":"UserBlockedEvent"},{"name":"UnpinnedEvent"},{"name":"UnsubscribedEvent"}]},{"kind":"UNION","name":"IssueOrPullRequest","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"}]},{"kind":"UNION","name":"IssueTimelineItem","possibleTypes":[{"name":"Commit"},{"name":"IssueComment"},{"name":"CrossReferencedEvent"},{"name":"ClosedEvent"},{"name":"ReopenedEvent"},{"name":"SubscribedEvent"},{"name":"UnsubscribedEvent"},{"name":"ReferencedEvent"},{"name":"AssignedEvent"},{"name":"UnassignedEvent"},{"name":"LabeledEvent"},{"name":"UnlabeledEvent"},{"name":"UserBlockedEvent"},{"name":"MilestonedEvent"},{"name":"DemilestonedEvent"},{"name":"RenamedTitleEvent"},{"name":"LockedEvent"},{"name":"UnlockedEvent"},{"name":"TransferredEvent"}]},{"kind":"UNION","name":"IssueTimelineItems","possibleTypes":[{"name":"IssueComment"},{"name":"CrossReferencedEvent"},{"name":"AddedToProjectEvent"},{"name":"AssignedEvent"},{"name":"ClosedEvent"},{"name":"CommentDeletedEvent"},{"name":"ConvertedNoteToIssueEvent"},{"name":"DemilestonedEvent"},{"name":"LabeledEvent"},{"name":"LockedEvent"},{"name":"MentionedEvent"},{"name":"MilestonedEvent"},{"name":"MovedColumnsInProjectEvent"},{"name":"PinnedEvent"},{"name":"ReferencedEvent"},{"name":"RemovedFromProjectEvent"},{"name":"RenamedTitleEvent"},{"name":"ReopenedEvent"},{"name":"SubscribedEvent"},{"name":"TransferredEvent"},{"name":"UnassignedEvent"},{"name":"UnlabeledEvent"},{"name":"UnlockedEvent"},{"name":"UserBlockedEvent"},{"name":"UnpinnedEvent"},{"name":"UnsubscribedEvent"}]},{"kind":"UNION","name":"ReviewDismissalAllowanceActor","possibleTypes":[{"name":"User"},{"name":"Team"}]},{"kind":"UNION","name":"PushAllowanceActor","possibleTypes":[{"name":"User"},{"name":"Team"}]},{"kind":"UNION","name":"PermissionGranter","possibleTypes":[{"name":"Organization"},{"name":"Repository"},{"name":"Team"}]},{"kind":"INTERFACE","name":"Sponsorable","possibleTypes":[{"name":"User"}]},{"kind":"INTERFACE","name":"Contribution","possibleTypes":[{"name":"CreatedCommitContribution"},{"name":"CreatedIssueContribution"},{"name":"CreatedPullRequestContribution"},{"name":"CreatedPullRequestReviewContribution"},{"name":"CreatedRepositoryContribution"},{"name":"JoinedGitHubContribution"},{"name":"RestrictedContribution"}]},{"kind":"UNION","name":"CreatedRepositoryOrRestrictedContribution","possibleTypes":[{"name":"CreatedRepositoryContribution"},{"name":"RestrictedContribution"}]},{"kind":"UNION","name":"CreatedIssueOrRestrictedContribution","possibleTypes":[{"name":"CreatedIssueContribution"},{"name":"RestrictedContribution"}]},{"kind":"UNION","name":"CreatedPullRequestOrRestrictedContribution","possibleTypes":[{"name":"CreatedPullRequestContribution"},{"name":"RestrictedContribution"}]},{"kind":"UNION","name":"SearchResultItem","possibleTypes":[{"name":"Issue"},{"name":"PullRequest"},{"name":"Repository"},{"name":"User"},{"name":"Organization"},{"name":"MarketplaceListing"},{"name":"App"}]},{"kind":"UNION","name":"CollectionItemContent","possibleTypes":[{"name":"Repository"},{"name":"Organization"},{"name":"User"}]}]}} \ No newline at end of file diff --git a/packages/netlify-cms-backend-github/webpack.config.js b/packages/netlify-cms-backend-github/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-github/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-gitlab/CHANGELOG.md b/packages/netlify-cms-backend-gitlab/CHANGELOG.md deleted file mode 100644 index d2f771b4..00000000 --- a/packages/netlify-cms-backend-gitlab/CHANGELOG.md +++ /dev/null @@ -1,593 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.13.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-gitlab@2.13.1...netlify-cms-backend-gitlab@2.13.2) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-gitlab@2.13.0...netlify-cms-backend-gitlab@2.13.1) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-gitlab@2.12.0...netlify-cms-backend-gitlab@2.13.0) (2021-12-28) - - -### Features - -* **backend-gitlab:** initial GraphQL support ([#6059](https://github.com/netlify/netlify-cms/issues/6059)) ([1523a41](https://github.com/netlify/netlify-cms/commit/1523a4140a3d2f4cc01a1548514ae17bc1ad504e)) - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-gitlab@2.11.4...netlify-cms-backend-gitlab@2.12.0) (2021-10-18) - - -### Features - -* display author of changes in workflow tab ([#5780](https://github.com/netlify/netlify-cms/issues/5780)) ([3f607e4](https://github.com/netlify/netlify-cms/commit/3f607e41d9c4d8fe5329a9ab6841cada7742825e)) - - - - - -## [2.11.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.11.3...netlify-cms-backend-gitlab@2.11.4) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.11.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.11.2...netlify-cms-backend-gitlab@2.11.3) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.11.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.11.1...netlify-cms-backend-gitlab@2.11.2) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.11.0...netlify-cms-backend-gitlab@2.11.1) (2021-05-04) - - -### Bug Fixes - -* **backend-gitlab:** increase merge requests fetched to 100 ([#5320](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/5320)) ([0a1b00d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/0a1b00d8b29a065b7d72fbb1744eb787da3b916e)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.10.0...netlify-cms-backend-gitlab@2.11.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.9...netlify-cms-backend-gitlab@2.10.0) (2021-04-14) - - -### Features - -* Adds PKCE authentication for GitLab closes [#5236](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/5236) ([#5239](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/5239)) ([829409e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/829409e0bc03b4591ee6b59d9895adc4e7190037)) - - - - - -## [2.9.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.8...netlify-cms-backend-gitlab@2.9.9) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.9.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.7...netlify-cms-backend-gitlab@2.9.8) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.9.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.6...netlify-cms-backend-gitlab@2.9.7) (2021-02-01) - - -### Bug Fixes - -* **backend-gitlab:** increase rebase timeout ([#4905](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/4905)) ([d9d6860](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/d9d686025fe848fe460917cdef1934dea3295c9d)) - - - - - -## [2.9.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.5...netlify-cms-backend-gitlab@2.9.6) (2021-01-05) - - -### Bug Fixes - -* **backend-gitlab:** skip creating a CI pipeline when rebasing merge request ([#4802](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/4802)) ([ce11dd2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/ce11dd23753fd7bb502c299058b83701f20058b2)), closes [#4786](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/4786) - - - - - -## [2.9.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.4...netlify-cms-backend-gitlab@2.9.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.9.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.9.3...netlify-cms-backend-gitlab@2.9.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## 2.9.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.9.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.9.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.8.4...netlify-cms-backend-gitlab@2.9.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) -* **backend-gitgateway:** improve deploy preview visibility ([#3882](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3882)) ([afc9bf4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/afc9bf4f3fe14ccb60851fc24e68922a6e4a85a9)) - - - - - -## [2.8.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.8.3...netlify-cms-backend-gitlab@2.8.4) (2020-04-21) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.8.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.8.2...netlify-cms-backend-gitlab@2.8.3) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.8.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.8.1...netlify-cms-backend-gitlab@2.8.2) (2020-03-20) - - -### Bug Fixes - -* missing workflow timestamp ([#3445](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3445)) ([9616cdb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/9616cdb8bb0a564771e5755bcd3718a07f2e2072)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.8.0...netlify-cms-backend-gitlab@2.8.1) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.7.1...netlify-cms-backend-gitlab@2.8.0) (2020-02-25) - - -### Features - -* **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3316)) ([7e0a8ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3292) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.7.0...netlify-cms-backend-gitlab@2.7.1) (2020-02-22) - - -### Reverts - -* Revert "feat(core): Align GitHub metadata handling with other backends (#3292)" ([5bdd3df](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/5bdd3df9ccbb5149c22d79987ebdcd6cab4b261f)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3292) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.6.0...netlify-cms-backend-gitlab@2.7.0) (2020-02-22) - - -### Features - -* **core:** Align GitHub metadata handling with other backends ([#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3292)) ([8193b5a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/8193b5ace89d6f14a6c756235a50b186a763b6b1)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.5.3...netlify-cms-backend-gitlab@2.6.0) (2020-02-10) - - -### Bug Fixes - -* filter paginated results ([#3216](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3216)) ([0a482b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/0a482b10049bcfa022b81165cabf4512d77e0b88)) -* workflow file collection ([#3207](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3207)) ([d22f7e6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/d22f7e680e7064e8607cf8b420571fa40a6c314e)) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.5.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.5.2...netlify-cms-backend-gitlab@2.5.3) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## [2.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.5.1...netlify-cms-backend-gitlab@2.5.2) (2020-01-21) - - -### Bug Fixes - -* **backend-gitlab:** check for shared group permissions ([#3122](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3122)) ([f1739e9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/f1739e978f9dee1de42dd5479ec80a5d991a9bfe)) -* **git-gateway-gitlab:** fix large media support for editorial workflow ([#3105](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/3105)) ([038803c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/038803c9f249de386812652372c35c4c53935295)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.5.0...netlify-cms-backend-gitlab@2.5.1) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.5.0-beta.0...netlify-cms-backend-gitlab@2.5.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.4.0...netlify-cms-backend-gitlab@2.5.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.4.0-beta.1...netlify-cms-backend-gitlab@2.4.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -# [2.4.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.4.0-beta.0...netlify-cms-backend-gitlab@2.4.0-beta.1) (2019-12-02) - - -### Features - -* content in sub folders ([#2897](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2897)) ([afcfe5b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/afcfe5b6d5f32669e9061ec596bd35ad545d61a3)) - - - - - -# [2.4.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.3-beta.1...netlify-cms-backend-gitlab@2.4.0-beta.0) (2019-11-07) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) -* enable specifying custom open authoring commit message ([#2810](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2810)) ([2841ff9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/2841ff9ffe58afcf4dba45514a84a262ad370f1d)) - - - - - -## [2.3.3-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.3-beta.0...netlify-cms-backend-gitlab@2.3.3-beta.1) (2019-09-26) - - -### Bug Fixes - -* **backend-gitlab:** exclude directories in paginated results ([#2668](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2668)) ([3903acb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/3903acb)) - - - - - -## [2.3.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.2...netlify-cms-backend-gitlab@2.3.3-beta.0) (2019-08-24) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.2-beta.0...netlify-cms-backend-gitlab@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.1...netlify-cms-backend-gitlab@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.1-beta.1...netlify-cms-backend-gitlab@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.1-beta.0...netlify-cms-backend-gitlab@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.3.0...netlify-cms-backend-gitlab@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.2.0...netlify-cms-backend-gitlab@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.2.0-beta.0...netlify-cms-backend-gitlab@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.1.4-beta.0...netlify-cms-backend-gitlab@2.2.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/82cc794)) - - - - - -## [2.1.4-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.1.3...netlify-cms-backend-gitlab@2.1.4-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/ccef446)) - - - - - -## [2.1.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.1.2...netlify-cms-backend-gitlab@2.1.3) (2019-03-08) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.1.1...netlify-cms-backend-gitlab@2.1.2) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.1.0...netlify-cms-backend-gitlab@2.1.1) (2018-12-11) - - -### Bug Fixes - -* **backend-gitlab:** show svg previews ([#1946](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1946)) ([c3adebe](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/c3adebe)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.6...netlify-cms-backend-gitlab@2.1.0) (2018-11-12) - - -### Bug Fixes - -* **backend-gitlab:** support folder names with whitespace ([#1799](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1799)) ([a9f69f9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/a9f69f9)) - - -### Features - -* allow custom logo on auth page ([#1818](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1818)) ([c6ae1e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/c6ae1e8)) - - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.5...netlify-cms-backend-gitlab@2.0.6) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.4...netlify-cms-backend-gitlab@2.0.5) (2018-08-24) - - -### Bug Fixes - -* **gitlab:** fetch media library images through API ([#1433](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1433)) ([83d2adc](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/83d2adc)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.3...netlify-cms-backend-gitlab@2.0.4) (2018-08-07) - - -### Bug Fixes - -* **backends:** fix commit message handling ([#1568](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1568)) ([f7e7120](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/f7e7120)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.2...netlify-cms-backend-gitlab@2.0.3) (2018-08-01) - - -### Bug Fixes - -* **gitlab:** fix uploads ([#1566](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/issues/1566)) ([d59c990](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/commit/d59c990)) - - - - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab/compare/netlify-cms-backend-gitlab@2.0.1...netlify-cms-backend-gitlab@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-backend-gitlab - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-backend-gitlab diff --git a/packages/netlify-cms-backend-gitlab/README.md b/packages/netlify-cms-backend-gitlab/README.md deleted file mode 100644 index a7f03c88..00000000 --- a/packages/netlify-cms-backend-gitlab/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# GitLab backend - -An abstraction layer between the CMS and [GitLab](https://docs.gitlab.com/ee/api/README.html) - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on `Api`. With [Editorial Workflow](https://www.netlifycms.org/docs/beta-features/#gitlab-and-bitbucket-editorial-workflow-support) uses merge requests labels to track unpublished entries statuses. - -`Api` - A wrapper for GitLab REST API. - -`AuthenticationPage` - A component uses [lib-auth](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/README.md) to facilitate OAuth, PKCE and implicit authentication. - -Look at tests or types for more info. diff --git a/packages/netlify-cms-backend-gitlab/package.json b/packages/netlify-cms-backend-gitlab/package.json deleted file mode 100644 index f1b3bdcb..00000000 --- a/packages/netlify-cms-backend-gitlab/package.json +++ /dev/null @@ -1,41 +0,0 @@ -{ - "name": "netlify-cms-backend-gitlab", - "description": "GitLab backend for Netlify CMS", - "version": "2.13.2", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-gitlab", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-gitlab.js", - "keywords": [ - "netlify", - "netlify-cms", - "backend", - "gitlab" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "dependencies": { - "apollo-cache-inmemory": "^1.6.2", - "apollo-client": "^2.6.3", - "apollo-link-context": "^1.0.18", - "apollo-link-http": "^1.5.15", - "js-base64": "^3.0.0", - "semaphore": "^1.1.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-gitlab/src/__tests__/API.spec.js b/packages/netlify-cms-backend-gitlab/src/__tests__/API.spec.js deleted file mode 100644 index ea6c6d9a..00000000 --- a/packages/netlify-cms-backend-gitlab/src/__tests__/API.spec.js +++ /dev/null @@ -1,187 +0,0 @@ -import API, { getMaxAccess } from '../API'; - -global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests')); - -jest.spyOn(console, 'log').mockImplementation(() => undefined); - -describe('GitLab API', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - describe('hasWriteAccess', () => { - test('should return true on project access_level >= 30', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest - .fn() - .mockResolvedValueOnce({ permissions: { project_access: { access_level: 30 } } }); - - await expect(api.hasWriteAccess()).resolves.toBe(true); - }); - - test('should return false on project access_level < 30', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest - .fn() - .mockResolvedValueOnce({ permissions: { project_access: { access_level: 10 } } }); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - }); - - test('should return true on group access_level >= 30', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest - .fn() - .mockResolvedValueOnce({ permissions: { group_access: { access_level: 30 } } }); - - await expect(api.hasWriteAccess()).resolves.toBe(true); - }); - - test('should return false on group access_level < 30', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest - .fn() - .mockResolvedValueOnce({ permissions: { group_access: { access_level: 10 } } }); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - }); - - test('should return true on shared group access_level >= 40', async () => { - const api = new API({ repo: 'repo' }); - api.requestJSON = jest.fn().mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 40 }], - }); - - await expect(api.hasWriteAccess()).resolves.toBe(true); - - expect(api.requestJSON).toHaveBeenCalledTimes(1); - }); - - test('should return true on shared group access_level >= 30, developers can merge and push', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest.fn(); - api.requestJSON.mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }], - }); - api.requestJSON.mockResolvedValueOnce({ - developers_can_merge: true, - developers_can_push: true, - }); - - await expect(api.hasWriteAccess()).resolves.toBe(true); - }); - - test('should return false on shared group access_level < 30,', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest.fn(); - api.requestJSON.mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 20 }], - }); - api.requestJSON.mockResolvedValueOnce({ - developers_can_merge: true, - developers_can_push: true, - }); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - }); - - test("should return false on shared group access_level >= 30, developers can't merge", async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest.fn(); - api.requestJSON.mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }], - }); - api.requestJSON.mockResolvedValueOnce({ - developers_can_merge: false, - developers_can_push: true, - }); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - }); - - test("should return false on shared group access_level >= 30, developers can't push", async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest.fn(); - api.requestJSON.mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }], - }); - api.requestJSON.mockResolvedValueOnce({ - developers_can_merge: true, - developers_can_push: false, - }); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - }); - - test('should return false on shared group access_level >= 30, error getting branch', async () => { - const api = new API({ repo: 'repo' }); - - api.requestJSON = jest.fn(); - api.requestJSON.mockResolvedValueOnce({ - permissions: { project_access: null, group_access: null }, - shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }], - }); - - const error = new Error('Not Found'); - api.requestJSON.mockRejectedValue(error); - - await expect(api.hasWriteAccess()).resolves.toBe(false); - - expect(console.log).toHaveBeenCalledTimes(1); - expect(console.log).toHaveBeenCalledWith('Failed getting default branch', error); - }); - }); - - describe('getStatuses', () => { - test('should get preview statuses', async () => { - const api = new API({ repo: 'repo' }); - - const mr = { sha: 'sha' }; - const statuses = [ - { name: 'deploy', status: 'success', target_url: 'deploy-url' }, - { name: 'build', status: 'pending' }, - ]; - - api.getBranchMergeRequest = jest.fn(() => Promise.resolve(mr)); - api.getMergeRequestStatues = jest.fn(() => Promise.resolve(statuses)); - - const collectionName = 'posts'; - const slug = 'title'; - await expect(api.getStatuses(collectionName, slug)).resolves.toEqual([ - { context: 'deploy', state: 'success', target_url: 'deploy-url' }, - { context: 'build', state: 'other' }, - ]); - - expect(api.getBranchMergeRequest).toHaveBeenCalledTimes(1); - expect(api.getBranchMergeRequest).toHaveBeenCalledWith('cms/posts/title'); - - expect(api.getMergeRequestStatues).toHaveBeenCalledTimes(1); - expect(api.getMergeRequestStatues).toHaveBeenCalledWith(mr, 'cms/posts/title'); - }); - }); - - describe('getMaxAccess', () => { - it('should return group with max access level', () => { - const groups = [ - { group_access_level: 10 }, - { group_access_level: 5 }, - { group_access_level: 100 }, - { group_access_level: 1 }, - ]; - expect(getMaxAccess(groups)).toBe(groups[2]); - }); - }); -}); diff --git a/packages/netlify-cms-backend-gitlab/src/__tests__/gitlab.spec.js b/packages/netlify-cms-backend-gitlab/src/__tests__/gitlab.spec.js deleted file mode 100644 index f5c361d1..00000000 --- a/packages/netlify-cms-backend-gitlab/src/__tests__/gitlab.spec.js +++ /dev/null @@ -1,542 +0,0 @@ -jest.mock('netlify-cms-core/src/backend'); -import { fromJS } from 'immutable'; -import { oneLine, stripIndent } from 'common-tags'; -import nock from 'nock'; -import { Cursor } from 'netlify-cms-lib-util'; - -import Gitlab from '../implementation'; -import AuthenticationPage from '../AuthenticationPage'; - -const { Backend, LocalStorageAuthStore } = jest.requireActual('netlify-cms-core/src/backend'); - -function generateEntries(path, length) { - const entries = Array.from({ length }, (val, idx) => { - const count = idx + 1; - const id = `00${count}`.slice(-3); - const fileName = `test${id}.md`; - return { id, fileName, filePath: `${path}/${fileName}` }; - }); - - return { - tree: entries.map(({ id, fileName, filePath }) => ({ - id: `d8345753a1d935fa47a26317a503e73e1192d${id}`, - name: fileName, - type: 'blob', - path: filePath, - mode: '100644', - })), - files: entries.reduce( - (acc, { id, filePath }) => ({ - ...acc, - [filePath]: stripIndent` - --- - title: test ${id} - --- - # test ${id} - `, - }), - {}, - ), - }; -} - -const manyEntries = generateEntries('many-entries', 500); - -const mockRepo = { - tree: { - '/': [ - { - id: '5d0620ebdbc92068a3e866866e928cc373f18429', - name: 'content', - type: 'tree', - path: 'content', - mode: '040000', - }, - ], - content: [ - { - id: 'b1a200e48be54fde12b636f9563d659d44c206a5', - name: 'test1.md', - type: 'blob', - path: 'content/test1.md', - mode: '100644', - }, - { - id: 'd8345753a1d935fa47a26317a503e73e1192d623', - name: 'test2.md', - type: 'blob', - path: 'content/test2.md', - mode: '100644', - }, - ], - 'many-entries': manyEntries.tree, - }, - files: { - 'content/test1.md': stripIndent` - --- - title: test - --- - # test - `, - 'content/test2.md': stripIndent` - --- - title: test2 - --- - # test 2 - `, - ...manyEntries.files, - }, -}; - -const resp = { - user: { - success: { - id: 1, - }, - }, - branch: { - success: { - name: 'master', - commit: { - id: 1, - }, - }, - }, - project: { - success: { - permissions: { - project_access: { - access_level: 30, - }, - }, - }, - readOnly: { - permissions: { - project_access: { - access_level: 10, - }, - }, - }, - }, -}; - -describe('gitlab backend', () => { - let authStore; - let backend; - const repo = 'foo/bar'; - const defaultConfig = { - backend: { - name: 'gitlab', - repo, - }, - }; - const collectionContentConfig = { - name: 'foo', - folder: 'content', - fields: [{ name: 'title' }], - // TODO: folder_based_collection is an internal string, we should not - // be depending on it here - type: 'folder_based_collection', - }; - const collectionManyEntriesConfig = { - name: 'foo', - folder: 'many-entries', - fields: [{ name: 'title' }], - // TODO: folder_based_collection is an internal string, we should not - // be depending on it here - type: 'folder_based_collection', - }; - const collectionFilesConfig = { - name: 'foo', - files: [ - { - label: 'foo', - name: 'foo', - file: 'content/test1.md', - fields: [{ name: 'title' }], - }, - { - label: 'bar', - name: 'bar', - file: 'content/test2.md', - fields: [{ name: 'title' }], - }, - ], - type: 'file_based_collection', - }; - const mockCredentials = { token: 'MOCK_TOKEN' }; - const expectedRepo = encodeURIComponent(repo); - const expectedRepoUrl = `/projects/${expectedRepo}`; - - function resolveBackend(config = {}) { - authStore = new LocalStorageAuthStore(); - return new Backend( - { - init: (...args) => new Gitlab(...args), - }, - { - backendName: 'gitlab', - config, - authStore, - }, - ); - } - - function mockApi(backend) { - return nock(backend.implementation.apiRoot); - } - - function interceptAuth(backend, { userResponse, projectResponse } = {}) { - const api = mockApi(backend); - api - .get('/user') - .query(true) - .reply(200, userResponse || resp.user.success); - - api - .get(expectedRepoUrl) - .query(true) - .reply(200, projectResponse || resp.project.success); - } - - function interceptBranch(backend, { branch = 'master' } = {}) { - const api = mockApi(backend); - api - .get(`${expectedRepoUrl}/repository/branches/${encodeURIComponent(branch)}`) - .query(true) - .reply(200, resp.branch.success); - } - - function parseQuery(uri) { - const query = uri.split('?')[1]; - if (!query) { - return {}; - } - return query.split('&').reduce((acc, q) => { - const [key, value] = q.split('='); - acc[key] = value; - return acc; - }, {}); - } - - function createHeaders(backend, { basePath, path, page, perPage, pageCount, totalCount }) { - const pageNum = parseInt(page, 10); - const pageCountNum = parseInt(pageCount, 10); - const url = `${backend.implementation.apiRoot}${basePath}`; - - function link(linkPage) { - return `<${url}?id=${expectedRepo}&page=${linkPage}&path=${path}&per_page=${perPage}&recursive=false>`; - } - - const linkHeader = oneLine` - ${link(1)}; rel="first", - ${link(pageCount)}; rel="last", - ${pageNum === 1 ? '' : `${link(pageNum - 1)}; rel="prev",`} - ${pageNum === pageCountNum ? '' : `${link(pageNum + 1)}; rel="next",`} - `.slice(0, -1); - - return { - 'X-Page': page, - 'X-Total-Pages': pageCount, - 'X-Per-Page': perPage, - 'X-Total': totalCount, - Link: linkHeader, - }; - } - - function interceptCollection( - backend, - collection, - { verb = 'get', repeat = 1, page: expectedPage } = {}, - ) { - const api = mockApi(backend); - const url = `${expectedRepoUrl}/repository/tree`; - const { folder } = collection; - const tree = mockRepo.tree[folder]; - api[verb](url) - .query(({ path, page }) => { - if (path !== folder) { - return false; - } - if (expectedPage && page && parseInt(page, 10) !== parseInt(expectedPage, 10)) { - return false; - } - return true; - }) - .times(repeat) - .reply(uri => { - const { page = 1, per_page = 20 } = parseQuery(uri); - const pageCount = tree.length <= per_page ? 1 : Math.round(tree.length / per_page); - const pageLastIndex = page * per_page; - const pageFirstIndex = pageLastIndex - per_page; - const resp = tree.slice(pageFirstIndex, pageLastIndex); - return [ - 200, - verb === 'head' ? null : resp, - createHeaders(backend, { - basePath: url, - path: folder, - page, - perPage: per_page, - pageCount, - totalCount: tree.length, - }), - ]; - }); - } - - function interceptFiles(backend, path) { - const api = mockApi(backend); - const url = `${expectedRepoUrl}/repository/files/${encodeURIComponent(path)}/raw`; - api.get(url).query(true).reply(200, mockRepo.files[path]); - - api - .get(`${expectedRepoUrl}/repository/commits`) - .query(({ path }) => path === path) - .reply(200, [ - { - author_name: 'author_name', - author_email: 'author_email', - authored_date: 'authored_date', - }, - ]); - } - - function sharedSetup() { - beforeEach(async () => { - backend = resolveBackend(defaultConfig); - interceptAuth(backend); - await backend.authenticate(mockCredentials); - interceptCollection(backend, collectionManyEntriesConfig, { verb: 'head' }); - interceptCollection(backend, collectionContentConfig, { verb: 'head' }); - }); - } - - it('throws if configuration does not include repo', () => { - expect(() => resolveBackend({ backend: {} })).toThrowErrorMatchingInlineSnapshot( - `"The GitLab backend needs a \\"repo\\" in the backend configuration."`, - ); - }); - - describe('authComponent', () => { - it('returns authentication page component', () => { - backend = resolveBackend(defaultConfig); - expect(backend.authComponent()).toEqual(AuthenticationPage); - }); - }); - - describe('authenticate', () => { - it('throws if user does not have access to project', async () => { - backend = resolveBackend(defaultConfig); - interceptAuth(backend, { projectResponse: resp.project.readOnly }); - await expect( - backend.authenticate(mockCredentials), - ).rejects.toThrowErrorMatchingInlineSnapshot( - `"Your GitLab user account does not have access to this repo."`, - ); - }); - - it('stores and returns user object on success', async () => { - const backendName = defaultConfig.backend.name; - backend = resolveBackend(defaultConfig); - interceptAuth(backend); - const user = await backend.authenticate(mockCredentials); - expect(authStore.retrieve()).toEqual(user); - expect(user).toEqual({ ...resp.user.success, ...mockCredentials, backendName }); - }); - }); - - describe('currentUser', () => { - it('returns null if no user', async () => { - backend = resolveBackend(defaultConfig); - const user = await backend.currentUser(); - expect(user).toEqual(null); - }); - - it('returns the stored user if exists', async () => { - const backendName = defaultConfig.backend.name; - backend = resolveBackend(defaultConfig); - interceptAuth(backend); - await backend.authenticate(mockCredentials); - const user = await backend.currentUser(); - expect(user).toEqual({ ...resp.user.success, ...mockCredentials, backendName }); - }); - }); - - describe('getToken', () => { - it('returns the token for the current user', async () => { - backend = resolveBackend(defaultConfig); - interceptAuth(backend); - await backend.authenticate(mockCredentials); - const token = await backend.getToken(); - expect(token).toEqual(mockCredentials.token); - }); - }); - - describe('logout', () => { - it('sets token to null', async () => { - backend = resolveBackend(defaultConfig); - interceptAuth(backend); - await backend.authenticate(mockCredentials); - await backend.logout(); - const token = await backend.getToken(); - expect(token).toEqual(null); - }); - }); - - describe('getEntry', () => { - sharedSetup(); - - it('returns an entry from folder collection', async () => { - const entryTree = mockRepo.tree[collectionContentConfig.folder][0]; - const slug = entryTree.path.split('/').pop().replace('.md', ''); - - interceptFiles(backend, entryTree.path); - interceptCollection(backend, collectionContentConfig); - - const entry = await backend.getEntry( - { - config: {}, - integrations: fromJS([]), - entryDraft: fromJS({}), - mediaLibrary: fromJS({}), - }, - fromJS(collectionContentConfig), - slug, - ); - - expect(entry).toEqual(expect.objectContaining({ path: entryTree.path })); - }); - }); - - describe('listEntries', () => { - sharedSetup(); - - it('returns entries from folder collection', async () => { - const tree = mockRepo.tree[collectionContentConfig.folder]; - tree.forEach(file => interceptFiles(backend, file.path)); - - interceptCollection(backend, collectionContentConfig); - const entries = await backend.listEntries(fromJS(collectionContentConfig)); - - expect(entries).toEqual({ - cursor: expect.any(Cursor), - pagination: 1, - entries: expect.arrayContaining( - tree.map(file => expect.objectContaining({ path: file.path })), - ), - }); - expect(entries.entries).toHaveLength(2); - }); - - it('returns all entries from folder collection', async () => { - const tree = mockRepo.tree[collectionManyEntriesConfig.folder]; - interceptBranch(backend); - tree.forEach(file => interceptFiles(backend, file.path)); - - interceptCollection(backend, collectionManyEntriesConfig, { repeat: 5 }); - const entries = await backend.listAllEntries(fromJS(collectionManyEntriesConfig)); - - expect(entries).toEqual( - expect.arrayContaining(tree.map(file => expect.objectContaining({ path: file.path }))), - ); - expect(entries).toHaveLength(500); - }, 7000); - - it('returns entries from file collection', async () => { - const { files } = collectionFilesConfig; - files.forEach(file => interceptFiles(backend, file.file)); - const entries = await backend.listEntries(fromJS(collectionFilesConfig)); - - expect(entries).toEqual({ - cursor: expect.any(Cursor), - entries: expect.arrayContaining( - files.map(file => expect.objectContaining({ path: file.file })), - ), - }); - expect(entries.entries).toHaveLength(2); - }); - - it('returns first page from paginated folder collection tree', async () => { - const tree = mockRepo.tree[collectionManyEntriesConfig.folder]; - const pageTree = tree.slice(0, 20); - pageTree.forEach(file => interceptFiles(backend, file.path)); - interceptCollection(backend, collectionManyEntriesConfig, { page: 1 }); - const entries = await backend.listEntries(fromJS(collectionManyEntriesConfig)); - - expect(entries.entries).toEqual( - expect.arrayContaining(pageTree.map(file => expect.objectContaining({ path: file.path }))), - ); - expect(entries.entries).toHaveLength(20); - }); - }); - - describe('traverseCursor', () => { - sharedSetup(); - - it('returns complete last page of paginated tree', async () => { - const tree = mockRepo.tree[collectionManyEntriesConfig.folder]; - tree.slice(0, 20).forEach(file => interceptFiles(backend, file.path)); - interceptCollection(backend, collectionManyEntriesConfig, { page: 1 }); - const entries = await backend.listEntries(fromJS(collectionManyEntriesConfig)); - - const nextPageTree = tree.slice(20, 40); - nextPageTree.forEach(file => interceptFiles(backend, file.path)); - interceptCollection(backend, collectionManyEntriesConfig, { page: 2 }); - const nextPage = await backend.traverseCursor(entries.cursor, 'next'); - - expect(nextPage.entries).toEqual( - expect.arrayContaining( - nextPageTree.map(file => expect.objectContaining({ path: file.path })), - ), - ); - expect(nextPage.entries).toHaveLength(20); - - const lastPageTree = tree.slice(-20); - lastPageTree.forEach(file => interceptFiles(backend, file.path)); - interceptCollection(backend, collectionManyEntriesConfig, { page: 25 }); - const lastPage = await backend.traverseCursor(nextPage.cursor, 'last'); - expect(lastPage.entries).toEqual( - expect.arrayContaining( - lastPageTree.map(file => expect.objectContaining({ path: file.path })), - ), - ); - expect(lastPage.entries).toHaveLength(20); - }); - }); - - describe('filterFile', () => { - it('should return true for nested file with matching depth', () => { - backend = resolveBackend(defaultConfig); - - expect( - backend.implementation.filterFile( - 'content/posts', - { name: 'index.md', path: 'content/posts/dir1/dir2/index.md' }, - 'md', - 3, - ), - ).toBe(true); - }); - - it('should return false for nested file with non matching depth', () => { - backend = resolveBackend(defaultConfig); - - expect( - backend.implementation.filterFile( - 'content/posts', - { name: 'index.md', path: 'content/posts/dir1/dir2/index.md' }, - 'md', - 2, - ), - ).toBe(false); - }); - }); - - afterEach(() => { - nock.cleanAll(); - authStore.logout(); - backend = null; - expect(authStore.retrieve()).toEqual(null); - }); -}); diff --git a/packages/netlify-cms-backend-gitlab/webpack.config.js b/packages/netlify-cms-backend-gitlab/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-gitlab/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-proxy/CHANGELOG.md b/packages/netlify-cms-backend-proxy/CHANGELOG.md deleted file mode 100644 index cfb82f63..00000000 --- a/packages/netlify-cms-backend-proxy/CHANGELOG.md +++ /dev/null @@ -1,189 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.2.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-proxy@1.2.4...netlify-cms-backend-proxy@1.2.5) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.2.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-proxy@1.2.3...netlify-cms-backend-proxy@1.2.4) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.2.2...netlify-cms-backend-proxy@1.2.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.2.1...netlify-cms-backend-proxy@1.2.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.2.0...netlify-cms-backend-proxy@1.2.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.1.7...netlify-cms-backend-proxy@1.2.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [1.1.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.1.6...netlify-cms-backend-proxy@1.1.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.1.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.1.5...netlify-cms-backend-proxy@1.1.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.1.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.1.4...netlify-cms-backend-proxy@1.1.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.1.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.1.3...netlify-cms-backend-proxy@1.1.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## 1.1.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.1.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.1.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [1.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.7...netlify-cms-backend-proxy@1.1.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) - - - - - -## [1.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.6...netlify-cms-backend-proxy@1.0.7) (2020-05-19) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.5...netlify-cms-backend-proxy@1.0.6) (2020-04-06) - - -### Bug Fixes - -* **backend-proxy:** fix error reporting ([#3527](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/3527)) ([f94dea3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/f94dea386ce89f0f92744d0c4196416706999ea0)) - - - - - -## [1.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.4...netlify-cms-backend-proxy@1.0.5) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-backend-proxy - - - - - -## [1.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.3...netlify-cms-backend-proxy@1.0.4) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -## [1.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/compare/netlify-cms-backend-proxy@1.0.2...netlify-cms-backend-proxy@1.0.3) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## 1.0.2 (2020-01-22) - -**Note:** Version bump only for package netlify-cms-backend-proxy diff --git a/packages/netlify-cms-backend-proxy/README.md b/packages/netlify-cms-backend-proxy/README.md deleted file mode 100644 index 581d553e..00000000 --- a/packages/netlify-cms-backend-proxy/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Proxy backend - -Facilitates [local development](https://www.netlifycms.org/docs/beta-features/#working-with-a-local-git-repository). - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md). An `RPC` wrapper for `netlify-cms-proxy-server`. - -`AuthenticationPage` - a mock authentication page diff --git a/packages/netlify-cms-backend-proxy/package.json b/packages/netlify-cms-backend-proxy/package.json deleted file mode 100644 index 9b100cb5..00000000 --- a/packages/netlify-cms-backend-proxy/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "netlify-cms-backend-proxy", - "description": "Proxy backend for Netlify CMS", - "version": "1.2.5", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-proxy", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-proxy.js", - "keywords": [ - "netlify", - "netlify-cms", - "backend" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-backend-proxy/webpack.config.js b/packages/netlify-cms-backend-proxy/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-proxy/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-backend-test/CHANGELOG.md b/packages/netlify-cms-backend-test/CHANGELOG.md deleted file mode 100644 index 17c1b593..00000000 --- a/packages/netlify-cms-backend-test/CHANGELOG.md +++ /dev/null @@ -1,435 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.11.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-test@2.11.4...netlify-cms-backend-test@2.11.5) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.11.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-backend-test@2.11.3...netlify-cms-backend-test@2.11.4) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.11.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.11.2...netlify-cms-backend-test@2.11.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.11.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.11.1...netlify-cms-backend-test@2.11.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.11.0...netlify-cms-backend-test@2.11.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.10.7...netlify-cms-backend-test@2.11.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.10.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.10.6...netlify-cms-backend-test@2.10.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.10.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.10.5...netlify-cms-backend-test@2.10.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.10.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.10.4...netlify-cms-backend-test@2.10.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.10.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.10.3...netlify-cms-backend-test@2.10.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## 2.10.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.10.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.10.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.9.0...netlify-cms-backend-test@2.10.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.8.1...netlify-cms-backend-test@2.9.0) (2020-06-01) - - -### Features - -* add pre save/ post save hooks ([#3812](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3812)) ([812716e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/812716e18b09a716547f128b783c8e6f3d54cc5b)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.8.0...netlify-cms-backend-test@2.8.1) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.7.3...netlify-cms-backend-test@2.8.0) (2020-03-30) - - -### Features - -* add publish configuration option to collections ([#3467](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3467)) ([df33bc6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/df33bc64a996eedcb10835064a7cab8e7862e94d)) - - - - - -## [2.7.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.7.2...netlify-cms-backend-test@2.7.3) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.7.1...netlify-cms-backend-test@2.7.2) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.7.0...netlify-cms-backend-test@2.7.1) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.7.0-beta.0...netlify-cms-backend-test@2.7.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.7.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.6.0...netlify-cms-backend-test@2.7.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.6.0-beta.0...netlify-cms-backend-test@2.6.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.6.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.5.0...netlify-cms-backend-test@2.6.0-beta.0) (2019-12-02) - - -### Bug Fixes - -* **backend-test:** delete nested file path ([#2930](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2930)) ([b0fba6d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/b0fba6dc9ab89784e72d69a71752f68e0255a7e0)) -* keep editor slug path ([#2934](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2934)) ([3c4865f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/3c4865f2a76e6b0f156ab801081251eb620495b2)) - - -### Features - -* content in sub folders ([#2897](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2897)) ([afcfe5b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/afcfe5b6d5f32669e9061ec596bd35ad545d61a3)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.4.0...netlify-cms-backend-test@2.5.0) (2019-11-26) - - -### Features - -* workflow unpublished entry ([#2914](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2914)) ([41bb9aa](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/41bb9aac0dd6fd9f8ff157bb0b29c85aa87fe04d)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.3.0...netlify-cms-backend-test@2.4.0) (2019-11-18) - - -### Features - -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.3...netlify-cms-backend-test@2.3.0) (2019-11-07) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.2...netlify-cms-backend-test@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.2-beta.0...netlify-cms-backend-test@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.1...netlify-cms-backend-test@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.1-beta.1...netlify-cms-backend-test@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.1-beta.0...netlify-cms-backend-test@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.2.0...netlify-cms-backend-test@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.1.0...netlify-cms-backend-test@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.1.0-beta.0...netlify-cms-backend-test@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-backend-test - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.7-beta.0...netlify-cms-backend-test@2.1.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/82cc794)) - - - - - -## [2.0.7-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.6...netlify-cms-backend-test@2.0.7-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/ccef446)) - - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.5...netlify-cms-backend-test@2.0.6) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-backend-test - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.4...netlify-cms-backend-test@2.0.5) (2018-08-07) - - -### Bug Fixes - -* **backends:** fix commit message handling ([#1568](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/1568)) ([f7e7120](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/f7e7120)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.3...netlify-cms-backend-test@2.0.4) (2018-08-01) - - -### Bug Fixes - -* **workflow:** enable workflow per method ([#1569](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/1569)) ([90b8156](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/90b8156)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.2...netlify-cms-backend-test@2.0.3) (2018-08-01) - - -### Bug Fixes - -* **workflow:** fix status not set on new workflow entries ([#1558](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/issues/1558)) ([0aa085f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/commit/0aa085f)) - - - - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test/compare/netlify-cms-backend-test@2.0.1...netlify-cms-backend-test@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-backend-test - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-backend-test diff --git a/packages/netlify-cms-backend-test/README.md b/packages/netlify-cms-backend-test/README.md deleted file mode 100644 index 41333c51..00000000 --- a/packages/netlify-cms-backend-test/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Test backend - -The backend behind https://cms-demo.netlify.com/. -Used for demo purposes only. - -## Code structure - -`Implementation` for [File Management System API](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/README.md) based on simple JS objects: - -```js -window.repoFiles // json file-system tree -window.repoFilesUnpublished // flat file list -``` - -`AuthenticationPage` - A component which allow skip `login screen` for demo purposes. - -Look at tests or types for more info. diff --git a/packages/netlify-cms-backend-test/package.json b/packages/netlify-cms-backend-test/package.json deleted file mode 100644 index 964fa218..00000000 --- a/packages/netlify-cms-backend-test/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "netlify-cms-backend-test", - "description": "Development testing backend for Netlify CMS", - "version": "2.11.5", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-test", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-backend-test.js", - "keywords": [ - "netlify", - "netlify-cms", - "backend" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "lodash": "^4.17.11", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "uuid": "^3.3.2" - } -} diff --git a/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js b/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js deleted file mode 100644 index b4b1a592..00000000 --- a/packages/netlify-cms-backend-test/src/__tests__/implementation.spec.js +++ /dev/null @@ -1,266 +0,0 @@ -import TestBackend, { getFolderFiles } from '../implementation'; - -describe('test backend implementation', () => { - beforeEach(() => { - jest.resetModules(); - }); - - describe('getEntry', () => { - it('should get entry by path', async () => { - window.repoFiles = { - posts: { - 'some-post.md': { - content: 'post content', - }, - }, - }; - - const backend = new TestBackend({}); - - await expect(backend.getEntry('posts/some-post.md')).resolves.toEqual({ - file: { path: 'posts/some-post.md', id: null }, - data: 'post content', - }); - }); - - it('should get entry by nested path', async () => { - window.repoFiles = { - posts: { - dir1: { - dir2: { - 'some-post.md': { - content: 'post content', - }, - }, - }, - }, - }; - - const backend = new TestBackend({}); - - await expect(backend.getEntry('posts/dir1/dir2/some-post.md')).resolves.toEqual({ - file: { path: 'posts/dir1/dir2/some-post.md', id: null }, - data: 'post content', - }); - }); - }); - - describe('persistEntry', () => { - it('should persist entry', async () => { - window.repoFiles = {}; - - const backend = new TestBackend({}); - - const entry = { - dataFiles: [{ path: 'posts/some-post.md', raw: 'content', slug: 'some-post.md' }], - assets: [], - }; - await backend.persistEntry(entry, { newEntry: true }); - - expect(window.repoFiles).toEqual({ - posts: { - 'some-post.md': { - content: 'content', - path: 'posts/some-post.md', - }, - }, - }); - }); - - it('should persist entry and keep existing unrelated entries', async () => { - window.repoFiles = { - pages: { - 'other-page.md': { - content: 'content', - }, - }, - posts: { - 'other-post.md': { - content: 'content', - }, - }, - }; - - const backend = new TestBackend({}); - - const entry = { - dataFiles: [{ path: 'posts/new-post.md', raw: 'content', slug: 'new-post.md' }], - assets: [], - }; - await backend.persistEntry(entry, { newEntry: true }); - - expect(window.repoFiles).toEqual({ - pages: { - 'other-page.md': { - content: 'content', - }, - }, - posts: { - 'new-post.md': { - content: 'content', - path: 'posts/new-post.md', - }, - 'other-post.md': { - content: 'content', - }, - }, - }); - }); - - it('should persist nested entry', async () => { - window.repoFiles = {}; - - const backend = new TestBackend({}); - - const slug = 'dir1/dir2/some-post.md'; - const path = `posts/${slug}`; - const entry = { dataFiles: [{ path, raw: 'content', slug }], assets: [] }; - await backend.persistEntry(entry, { newEntry: true }); - - expect(window.repoFiles).toEqual({ - posts: { - dir1: { - dir2: { - 'some-post.md': { - content: 'content', - path: 'posts/dir1/dir2/some-post.md', - }, - }, - }, - }, - }); - }); - - it('should update existing nested entry', async () => { - window.repoFiles = { - posts: { - dir1: { - dir2: { - 'some-post.md': { - mediaFiles: ['file1'], - content: 'content', - }, - }, - }, - }, - }; - - const backend = new TestBackend({}); - - const slug = 'dir1/dir2/some-post.md'; - const path = `posts/${slug}`; - const entry = { dataFiles: [{ path, raw: 'new content', slug }], assets: [] }; - await backend.persistEntry(entry, { newEntry: false }); - - expect(window.repoFiles).toEqual({ - posts: { - dir1: { - dir2: { - 'some-post.md': { - path: 'posts/dir1/dir2/some-post.md', - content: 'new content', - }, - }, - }, - }, - }); - }); - }); - - describe('deleteFiles', () => { - it('should delete entry by path', async () => { - window.repoFiles = { - posts: { - 'some-post.md': { - content: 'post content', - }, - }, - }; - - const backend = new TestBackend({}); - - await backend.deleteFiles(['posts/some-post.md']); - expect(window.repoFiles).toEqual({ - posts: {}, - }); - }); - - it('should delete entry by nested path', async () => { - window.repoFiles = { - posts: { - dir1: { - dir2: { - 'some-post.md': { - content: 'post content', - }, - }, - }, - }, - }; - - const backend = new TestBackend({}); - - await backend.deleteFiles(['posts/dir1/dir2/some-post.md']); - expect(window.repoFiles).toEqual({ - posts: { - dir1: { - dir2: {}, - }, - }, - }); - }); - }); - - describe('getFolderFiles', () => { - it('should get files by depth', () => { - const tree = { - pages: { - 'root-page.md': { - content: 'root page content', - }, - dir1: { - 'nested-page-1.md': { - content: 'nested page 1 content', - }, - dir2: { - 'nested-page-2.md': { - content: 'nested page 2 content', - }, - }, - }, - }, - }; - - expect(getFolderFiles(tree, 'pages', 'md', 1)).toEqual([ - { - path: 'pages/root-page.md', - content: 'root page content', - }, - ]); - expect(getFolderFiles(tree, 'pages', 'md', 2)).toEqual([ - { - path: 'pages/dir1/nested-page-1.md', - content: 'nested page 1 content', - }, - { - path: 'pages/root-page.md', - content: 'root page content', - }, - ]); - expect(getFolderFiles(tree, 'pages', 'md', 3)).toEqual([ - { - path: 'pages/dir1/dir2/nested-page-2.md', - content: 'nested page 2 content', - }, - { - path: 'pages/dir1/nested-page-1.md', - content: 'nested page 1 content', - }, - { - path: 'pages/root-page.md', - content: 'root page content', - }, - ]); - }); - }); -}); diff --git a/packages/netlify-cms-backend-test/webpack.config.js b/packages/netlify-cms-backend-test/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-backend-test/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-core/CHANGELOG.md b/packages/netlify-cms-core/CHANGELOG.md index 33c721c6..41907be4 100644 --- a/packages/netlify-cms-core/CHANGELOG.md +++ b/packages/netlify-cms-core/CHANGELOG.md @@ -3,6 +3,198 @@ All notable changes to this project will be documented in this file. See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. +## [2.55.59](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.58...netlify-cms-core@2.55.59) (2022-09-29) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.58](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.57...netlify-cms-core@2.55.58) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.57](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.56...netlify-cms-core@2.55.57) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.56](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.55...netlify-cms-core@2.55.56) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.55](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.54...netlify-cms-core@2.55.55) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.54](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.53...netlify-cms-core@2.55.54) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.53](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.52...netlify-cms-core@2.55.53) (2022-09-28) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.52](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.51...netlify-cms-core@2.55.52) (2022-09-27) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.51](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.50...netlify-cms-core@2.55.51) (2022-09-27) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.50](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.49...netlify-cms-core@2.55.50) (2022-09-27) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.49](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.48...netlify-cms-core@2.55.49) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.48](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.47...netlify-cms-core@2.55.48) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.47](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.47...netlify-cms-core@2.55.47) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.47](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.46...netlify-cms-core@2.55.47) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.46](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.45...netlify-cms-core@2.55.46) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.45](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.44...netlify-cms-core@2.55.45) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.44](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.43...netlify-cms-core@2.55.44) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.43](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.42...netlify-cms-core@2.55.43) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.42](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.41...netlify-cms-core@2.55.42) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.41](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.40...netlify-cms-core@2.55.41) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.40](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.39...netlify-cms-core@2.55.40) (2022-09-26) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.39](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.38...netlify-cms-core@2.55.39) (2022-09-23) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.38](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.37...netlify-cms-core@2.55.38) (2022-09-23) + +**Note:** Version bump only for package netlify-cms-core + + + + + +## [2.55.37](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.36...netlify-cms-core@2.55.37) (2022-09-23) + +**Note:** Version bump only for package netlify-cms-core + + + + + ## [2.55.36](https://github.com/netlify/netlify-cms/compare/netlify-cms-core@2.55.35...netlify-cms-core@2.55.36) (2022-09-22) **Note:** Version bump only for package netlify-cms-core @@ -2229,7 +2421,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Features -* **netlify-cms-widget-relation:** use react-select and add support for multiple entries ([#1936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/1936)) ([518f6fb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/518f6fb)) +* **relation-widget:** use react-select and add support for multiple entries ([#1936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/1936)) ([518f6fb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/518f6fb)) @@ -2269,7 +2461,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline * **config:** allow config.yml file load to be skipped ([#2053](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2053)) ([14f94a0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/14f94a0)) * **netlify-cms-core:** expose loadEntry action to Widgets ([#2010](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2010)) ([5d8aef1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/5d8aef1)) -* **netlify-cms-widget-map:** add map widget ([#2051](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2051)) ([18f34d2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/18f34d2)) +* **map-widget:** add map widget ([#2051](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2051)) ([18f34d2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/18f34d2)) * **widget-number:** add range validation ([#2049](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2049)) ([dc44cac](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/dc44cac)) * **workflow:** add deploy preview links ([#2028](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/2028)) ([15d221d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/15d221d)) @@ -2333,7 +2525,7 @@ See [Conventional Commits](https://conventionalcommits.org) for commit guideline ### Features -* **netlify-cms-widget-select:** add support for multiple selection ([#1901](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/1901)) ([88bf287](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/88bf287)) +* **select-widget:** add support for multiple selection ([#1901](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/1901)) ([88bf287](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/88bf287)) * add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/commit/1fc2f50)) diff --git a/packages/netlify-cms-core/README.md b/packages/netlify-cms-core/README.md index fe9fafd0..9b2e5367 100644 --- a/packages/netlify-cms-core/README.md +++ b/packages/netlify-cms-core/README.md @@ -9,3 +9,76 @@ In the meantime, you can: site](https://www.netlifycms.org) for more info. 2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. 3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-core/README.md)! + +# Using Core + +```tsx +import React from 'react'; +import { + AzureBackend, + BitbucketBackend, + BooleanWidget, + CodeWidget, + ColorStringWidget, + DateTimeWidget, + FileWidget, + GitGatewayBackend, + GitHubBackend, + GitLabBackend, + imageEditorComponent, + ImageWidget, + ListWidget, + MapWidget, + MarkdownWidget, + NetlifyCmsCore as CMS, + NumberWidget, + ObjectWidget, + ProxyBackend, + RelationWidget, + SelectWidget, + StringWidget, + TestBackend, + TextWidget, + locales, + Icon, + images +} from 'netlify-cms-core'; + +// Register all the things +CMS.registerBackend('git-gateway', GitGatewayBackend); +CMS.registerBackend('azure', AzureBackend); +CMS.registerBackend('github', GitHubBackend); +CMS.registerBackend('gitlab', GitLabBackend); +CMS.registerBackend('bitbucket', BitbucketBackend); +CMS.registerBackend('test-repo', TestBackend); +CMS.registerBackend('proxy', ProxyBackend); +CMS.registerWidget([ + StringWidget.Widget(), + NumberWidget.Widget(), + TextWidget.Widget(), + ImageWidget.Widget(), + FileWidget.Widget(), + SelectWidget.Widget(), + MarkdownWidget.Widget(), + ListWidget.Widget(), + ObjectWidget.Widget(), + RelationWidget.Widget(), + BooleanWidget.Widget(), + MapWidget.Widget(), + DateTimeWidget.Widget(), + CodeWidget.Widget(), + ColorStringWidget.Widget(), +]); +CMS.registerEditorComponent(imageEditorComponent); +CMS.registerEditorComponent({ + id: 'code-block', + label: 'Code Block', + widget: 'code', + type: 'code-block', +}); +CMS.registerLocale('en', locales.en); + +Object.keys(images).forEach(iconName => { + CMS.registerIcon(iconName, ); +}); +``` \ No newline at end of file diff --git a/packages/netlify-cms-core/index.d.ts b/packages/netlify-cms-core/index.d.ts index 428f575a..cd5631e9 100644 --- a/packages/netlify-cms-core/index.d.ts +++ b/packages/netlify-cms-core/index.d.ts @@ -1,7 +1,8 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ declare module 'netlify-cms-core' { - import type { ComponentType, ReactNode } from 'react'; - import type { List, Map } from 'immutable'; + import type { Iterable as ImmutableIterable, List, Map } from 'immutable'; + import type { ComponentType, FocusEventHandler, ReactNode } from 'react'; + import type { t } from 'react-polyglot'; import type { Pluggable } from 'unified'; export type CmsBackendType = @@ -298,6 +299,19 @@ declare module 'netlify-cms-core' { pattern?: string; } + export type SortDirection = 'Ascending' | 'Descending' | 'None'; + + export interface CmsSortableFieldsDefault { + field: string; + direction: SortDirection; + } + + export interface CmsSortableFields { + default?: CmsSortableFieldsDefault; + fields: string[]; + } + + export interface CmsCollection { name: string; icon?: string; @@ -337,15 +351,10 @@ declare module 'netlify-cms-core' { path?: string; media_folder?: string; public_folder?: string; - sortable_fields?: string[]; + sortable_fields?: CmsSortableFields; view_filters?: ViewFilter[]; view_groups?: ViewGroup[]; i18n?: boolean | CmsI18nConfig; - - /** - * @deprecated Use sortable_fields instead - */ - sortableFields?: string[]; } export interface CmsBackend { @@ -425,7 +434,14 @@ declare module 'netlify-cms-core' { widget: string; } - export interface EditorComponentOptions { + export interface EditorComponentWidgetOptions { + id: string; + label: string; + widget: string; + type: string; + } + + export interface EditorComponentManualOptions { id: string; label: string; fields: EditorComponentField[]; @@ -436,6 +452,8 @@ declare module 'netlify-cms-core' { toPreview: (data: any) => string; } + export type EditorComponentOptions = EditorComponentManualOptions | EditorComponentWidgetOptions; + export interface PreviewStyleOptions { raw: boolean; } @@ -444,7 +462,7 @@ declare module 'netlify-cms-core' { value: string; } - export type CmsBackendClass = any; // TODO: type properly + export type CmsBackendClass = Implementation; export interface CmsRegistryBackend { init: (args: any) => CmsBackendClass; @@ -456,6 +474,9 @@ declare module 'netlify-cms-core' { onChange: (value: T) => void; forID: string; classNameWrapper: string; + setActiveStyle: FocusEventHandler; + setInactiveStyle: FocusEventHandler; + t: t; } export interface CmsWidgetPreviewProps { @@ -471,12 +492,17 @@ declare module 'netlify-cms-core' { name: string; controlComponent: CmsWidgetControlProps; previewComponent?: CmsWidgetPreviewProps; + validator?: (props: { + field: Map; + value: T | undefined | null; + t: t; + }) => boolean | { error: any } | Promise; globalStyles?: any; } export interface CmsWidget { - control: CmsWidgetControlProps; - preview?: CmsWidgetPreviewProps; + control: ComponentType>; + preview?: ComponentType>; globalStyles?: any; } @@ -547,7 +573,7 @@ declare module 'netlify-cms-core' { document: Document; }; - export interface CMS { + export interface CMSApi { getBackend: (name: string) => CmsRegistryBackend | undefined; getEditorComponents: () => Map>; getRemarkPlugins: () => Array; @@ -574,7 +600,7 @@ declare module 'netlify-cms-core' { component: ComponentType, ) => void; registerWidget: ( - widget: string | CmsWidgetParam, + widget: string | CmsWidgetParam | CmsWidgetParam[], control?: ComponentType | string, preview?: ComponentType, ) => void; @@ -584,11 +610,353 @@ declare module 'netlify-cms-core' { ) => void; registerIcon: (iconName: string, icon: ReactNode) => void; getIcon: (iconName: string) => ReactNode; - registerAdditionalLink: (id: string, title: string, link: string, iconName?: string) => void; - getAdditionalLinks: () => { title: string, link: string, iconName?: string }[]; + registerAdditionalLink: ( + id: string, + title: string, + data: string | ComponentType, + iconName?: string, + ) => void; + getAdditionalLinks: () => { title: string; data: string | ComponentType; iconName?: string }[]; + getAdditionalLink: ( + id: string, + ) => { title: string; data: string | ComponentType; iconName?: string } | undefined; } - export const NetlifyCmsCore: CMS; + export const CMS: CMSApi; - export default NetlifyCmsCore; + export default CMS; + + // Backends + export type DisplayURLObject = { id: string; path: string }; + + export type DisplayURL = DisplayURLObject | string; + + export type DataFile = { + path: string; + slug: string; + raw: string; + newPath?: string; + }; + + export type AssetProxy = { + path: string; + fileObj?: File; + toBase64?: () => Promise; + }; + + export type Entry = { + dataFiles: DataFile[]; + assets: AssetProxy[]; + }; + + export type PersistOptions = { + newEntry?: boolean; + commitMessage: string; + collectionName?: string; + useWorkflow?: boolean; + unpublished?: boolean; + status?: string; + }; + + export type DeleteOptions = {}; + + export type Credentials = { token: string | {}; refresh_token?: string }; + + export type User = Credentials & { + backendName?: string; + login?: string; + name: string; + useOpenAuthoring?: boolean; + }; + + export interface ImplementationEntry { + data: string; + file: { path: string; label?: string; id?: string | null; author?: string; updatedOn?: string }; + } + + export type ImplementationFile = { + id?: string | null | undefined; + label?: string; + path: string; + }; + export interface ImplementationMediaFile { + name: string; + id: string; + size?: number; + displayURL?: DisplayURL; + path: string; + draft?: boolean; + url?: string; + file?: File; + } + + export interface UnpublishedEntryMediaFile { + id: string; + path: string; + } + + export interface UnpublishedEntryDiff { + id: string; + path: string; + newFile: boolean; + } + + export interface UnpublishedEntry { + pullRequestAuthor?: string; + slug: string; + collection: string; + status: string; + diffs: UnpublishedEntryDiff[]; + updatedAt: string; + } + + export type CursorStoreObject = { + actions: Set; + data: Map; + meta: Map; + }; + + export type CursorStore = { + get( + key: K, + defaultValue?: CursorStoreObject[K], + ): CursorStoreObject[K]; + getIn(path: string[]): V; + set( + key: K, + value: V, + ): CursorStoreObject[K]; + setIn(path: string[], value: unknown): CursorStore; + hasIn(path: string[]): boolean; + mergeIn(path: string[], value: unknown): CursorStore; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + update: (...args: any[]) => CursorStore; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + updateIn: (...args: any[]) => CursorStore; + }; + + export type ActionHandler = (action: string) => unknown; + + export class Cursor { + static create(...args: {}[]): Cursor; + updateStore(...args: any[]): Cursor; + updateInStore(...args: any[]): Cursor; + hasAction(action: string): boolean; + addAction(action: string): Cursor; + removeAction(action: string): Cursor; + setActions(actions: Iterable): Cursor; + mergeActions(actions: Set): Cursor; + getActionHandlers(handler: ActionHandler): ImmutableIterable; + setData(data: {}): Cursor; + mergeData(data: {}): Cursor; + wrapData(data: {}): Cursor; + unwrapData(): [Map, Cursor]; + clearData(): Cursor; + setMeta(meta: {}): Cursor; + mergeMeta(meta: {}): Cursor; + } + + class Implementation { + authComponent: () => void; + restoreUser: (user: User) => Promise; + + authenticate: (credentials: Credentials) => Promise; + logout: () => Promise | void | null; + getToken: () => Promise; + + getEntry: (path: string) => Promise; + entriesByFolder: ( + folder: string, + extension: string, + depth: number, + ) => Promise; + entriesByFiles: (files: ImplementationFile[]) => Promise; + + getMediaDisplayURL?: (displayURL: DisplayURL) => Promise; + getMedia: (folder?: string) => Promise; + getMediaFile: (path: string) => Promise; + + persistEntry: (entry: Entry, opts: PersistOptions) => Promise; + persistMedia: (file: AssetProxy, opts: PersistOptions) => Promise; + deleteFiles: (paths: string[], commitMessage: string) => Promise; + + unpublishedEntries: () => Promise; + unpublishedEntry: (args: { + id?: string; + collection?: string; + slug?: string; + }) => Promise; + unpublishedEntryDataFile: ( + collection: string, + slug: string, + path: string, + id: string, + ) => Promise; + unpublishedEntryMediaFile: ( + collection: string, + slug: string, + path: string, + id: string, + ) => Promise; + updateUnpublishedEntryStatus: ( + collection: string, + slug: string, + newStatus: string, + ) => Promise; + publishUnpublishedEntry: (collection: string, slug: string) => Promise; + deleteUnpublishedEntry: (collection: string, slug: string) => Promise; + getDeployPreview: ( + collectionName: string, + slug: string, + ) => Promise<{ url: string; status: string } | null>; + + allEntriesByFolder?: ( + folder: string, + extension: string, + depth: number, + ) => Promise; + traverseCursor?: ( + cursor: Cursor, + action: string, + ) => Promise<{ entries: ImplementationEntry[]; cursor: Cursor }>; + + isGitBackend?: () => boolean; + status: () => Promise<{ + auth: { status: boolean }; + api: { status: boolean; statusPage: string }; + }>; + } + + export class AzureBackend extends Implementation {} + export class BitbucketBackend extends Implementation {} + export class GitGatewayBackend extends Implementation {} + export class GitHubBackend extends Implementation {} + export class GitLabBackend extends Implementation {} + export class ProxyBackend extends Implementation {} + export class TestBackend extends Implementation {} + + // Widgets + export const BooleanWidget: { + Widget: () => CmsWidgetParam; + }; + export const CodeWidget: { + Widget: () => CmsWidgetParam; + }; + export const ColorStringWidget: { + Widget: () => CmsWidgetParam; + }; + export const DateTimeWidget: { + Widget: () => CmsWidgetParam; + }; + export const FileWidget: { + Widget: () => CmsWidgetParam>; + }; + export const ImageWidget: { + Widget: () => CmsWidgetParam>; + }; + export const ListWidget: { + Widget: () => CmsWidgetParam>; + }; + export const MapWidget: { + Widget: () => CmsWidgetParam; + }; + export const MarkdownWidget: { + Widget: () => CmsWidgetParam; + }; + export const NumberWidget: { + Widget: () => CmsWidgetParam; + }; + export const ObjectWidget: { + Widget: () => CmsWidgetParam | Record>; + }; + export const RelationWidget: { + Widget: () => CmsWidgetParam; + }; + export const SelectWidget: { + Widget: () => CmsWidgetParam; + }; + export const StringWidget: { + Widget: () => CmsWidgetParam; + }; + export const TextWidget: { + Widget: () => CmsWidgetParam; + }; + + export const MediaLibraryCloudinary: { + name: string; + init: ({ + options, + handleInsert, + }?: { + options?: Record | undefined; + handleInsert: any; + }) => Promise<{ + show: ({ + config, + allowMultiple, + }?: { + config?: Record | undefined; + allowMultiple: boolean; + }) => any; + hide: () => any; + enableStandalone: () => boolean; + }>; + }; + + export const MediaLibraryUploadcare: { + name: string; + init: ({ + options, + handleInsert, + }?: { + options?: + | { + config: Record; + settings: Record; + } + | undefined; + handleInsert: any; + }) => Promise<{ + show: ({ + value, + config, + allowMultiple, + imagesOnly, + }?: { + value: any; + config?: Record | undefined; + allowMultiple: boolean; + imagesOnly?: boolean | undefined; + }) => any; + enableStandalone: () => boolean; + }>; + }; + + export const imageEditorComponent: EditorComponentManualOptions; + + export const locales: { + en: Record; + }; + + class NetlifyAuthenticator { + constructor(config: Record); + + refresh: (args: { + provider: string; + refresh_token: string; + }) => Promise<{ token: string; refresh_token: string }>; + } + export { NetlifyAuthenticator }; + + // Images + export interface IconProps { + type: string; + direction?: 'right' | 'down' | 'left' | 'up'; + size?: string; + className?: string; + } + + export const Icon: React.ComponentType; + + export const images: Record; } diff --git a/packages/netlify-cms-core/package.json b/packages/netlify-cms-core/package.json index 7a2334c1..1ea79f1d 100644 --- a/packages/netlify-cms-core/package.json +++ b/packages/netlify-cms-core/package.json @@ -1,7 +1,7 @@ { "name": "netlify-cms-core", "description": "Netlify CMS core application, see netlify-cms package for the main distribution.", - "version": "2.55.36", + "version": "2.55.59", "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core", "bugs": "https://github.com/netlify/netlify-cms/issues", "module": "dist/esm/index.js", @@ -13,10 +13,10 @@ ], "types": "index.d.ts", "scripts": { - "develop": "yarn build:esm --watch", + "develop": "webpack serve --hot", "webpack": "node --max_old_space_size=4096 ../../node_modules/webpack/bin/webpack.js", "build": "cross-env NODE_ENV=production run-s webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" + "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore **/__tests__ --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" }, "keywords": [ "netlify", @@ -25,78 +25,121 @@ ], "license": "MIT", "dependencies": { - "@iarna/toml": "2.2.5", - "ajv": "8.1.0", - "ajv-errors": "^3.0.0", - "ajv-keywords": "^5.0.0", - "clean-stack": "^4.1.0", - "copy-text-to-clipboard": "^3.0.0", - "deepmerge": "^4.2.2", - "diacritics": "^1.3.0", - "fuzzy": "^0.1.1", - "gotrue-js": "^0.9.24", - "gray-matter": "^4.0.2", - "history": "^4.7.2", - "immer": "^9.0.0", - "js-base64": "^3.0.0", - "jwt-decode": "^3.0.0", - "node-polyglot": "^2.3.0", - "prop-types": "^15.7.2", - "react": "^16.8.4", - "react-dnd": "^14.0.0", - "react-dnd-html5-backend": "^14.0.0", - "react-dom": "^16.8.4", - "react-frame-component": "^5.2.1", - "react-hot-loader": "^4.8.0", - "react-immutable-proptypes": "^2.1.0", - "react-is": "18.2.0", - "react-markdown": "^6.0.2", - "react-modal": "^3.8.1", - "react-polyglot": "^0.7.0", - "react-redux": "^7.2.0", - "react-router-dom": "^5.2.0", - "react-scroll-sync": "^0.9.0", - "react-sortable-hoc": "^2.0.0", - "react-split-pane": "^0.1.85", - "react-topbar-progress-indicator": "^4.0.0", - "react-virtualized-auto-sizer": "^1.0.2", - "react-waypoint": "^10.0.0", - "react-window": "^1.8.5", - "redux": "^4.0.5", - "redux-devtools-extension": "^2.13.8", - "redux-notifications": "^4.0.1", - "redux-thunk": "^2.3.0", - "remark-gfm": "3.0.1", - "sanitize-filename": "^1.6.1", - "semaphore": "^1.0.5", - "tomlify-j0.4": "^3.0.0-alpha.0", - "url": "^0.11.0", - "url-join": "^4.0.1", - "what-input": "^5.1.4", - "yaml": "^1.8.3" - }, - "peerDependencies": { + "@emotion/css": "11.10.0", "@emotion/react": "11.10.4", "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "netlify-cms-editor-component-image": "^2.6.7", - "netlify-cms-lib-auth": "^2.3.0", - "netlify-cms-lib-util": "^2.12.3", - "netlify-cms-lib-widgets": "^1.6.1", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" + "@hot-loader/react-dom": "17.0.2", + "@iarna/toml": "2.2.5", + "@mui/icons-material": "5.10.6", + "@mui/material": "5.10.6", + "@reduxjs/toolkit": "1.8.5", + "ajv": "6.12.6", + "ajv-errors": "1.0.1", + "ajv-keywords": "3.5.2", + "apollo-cache-inmemory": "1.6.6", + "apollo-client": "2.6.10", + "apollo-link-context": "1.0.20", + "apollo-link-http": "1.5.17", + "array-move": "4.0.0", + "clean-stack": "4.2.0", + "codemirror": "5.65.9", + "common-tags": "1.8.1", + "copy-text-to-clipboard": "3.0.1", + "create-react-class": "15.7.0", + "deepmerge": "4.2.2", + "diacritics": "1.3.0", + "dompurify": "2.4.0", + "fuzzy": "0.1.3", + "gotrue-js": "0.9.29", + "graphql": "15.8.0", + "graphql-tag": "2.12.6", + "gray-matter": "4.0.3", + "history": "4.10.1", + "immer": "9.0.15", + "immutable": "3.8.2", + "ini": "2.0.0", + "is-hotkey": "0.2.0", + "js-base64": "3.7.2", + "js-sha256": "0.9.0", + "jwt-decode": "3.1.2", + "localforage": "1.10.0", + "lodash": "4.17.21", + "mdast-util-definitions": "1.2.5", + "mdast-util-to-string": "1.1.0", + "minimatch": "3.0.4", + "moment": "2.29.4", + "node-polyglot": "2.4.2", + "ol": "6.15.1", + "prop-types": "15.8.1", + "react": "17.0.2", + "react-aria-menubutton": "7.0.3", + "react-codemirror2": "7.2.1", + "react-color": "2.19.3", + "react-datetime": "3.1.1", + "react-dnd": "14.0.5", + "react-dnd-html5-backend": "14.1.0", + "react-dom": "17.0.2", + "react-frame-component": "5.2.3", + "react-hot-loader": "4.13.0", + "react-immutable-proptypes": "2.2.0", + "react-is": "18.2.0", + "react-markdown": "6.0.3", + "react-modal": "3.15.1", + "react-polyglot": "0.7.2", + "react-redux": "8.0.4", + "react-router-dom": "5.3.3", + "react-scroll-sync": "0.9.0", + "react-select": "4.3.1", + "react-sortable-hoc": "2.0.0", + "react-split-pane": "0.1.92", + "react-textarea-autosize": "8.3.4", + "react-toggled": "1.2.7", + "react-topbar-progress-indicator": "4.1.1", + "react-transition-group": "4.4.5", + "react-virtualized-auto-sizer": "1.0.7", + "react-waypoint": "10.3.0", + "react-window": "1.8.7", + "rehype-parse": "6.0.2", + "rehype-remark": "8.1.1", + "rehype-stringify": "7.0.0", + "remark-gfm": "3.0.1", + "remark-parse": "6.0.3", + "remark-rehype": "4.0.1", + "remark-stringify": "6.0.4", + "sanitize-filename": "1.6.3", + "semaphore": "1.1.0", + "slate": "0.47.9", + "slate-base64-serializer": "0.2.115", + "slate-plain-serializer": "0.7.13", + "slate-react": "0.22.10", + "slate-soft-break": "0.9.0", + "tomlify-j0.4": "3.0.0", + "unified": "7.1.0", + "unist-builder": "1.0.4", + "unist-util-visit-parents": "2.1.2", + "uploadcare-widget": "3.19.0", + "uploadcare-widget-tab-effects": "1.5.0", + "url": "0.11.0", + "url-join": "4.0.1", + "uuid": "3.4.0", + "validate-color": "2.2.1", + "what-input": "5.2.12", + "what-the-diff": "0.6.0", + "yaml": "1.10.2" }, "devDependencies": { - "@types/history": "^4.7.8", - "@types/react": "18.0.20", + "@types/history": "4.7.11", + "@types/react": "17.0.50", + "@types/react-dom": "17.0.17", + "@types/react-router-dom": "5.3.3", "@types/react-scroll-sync": "0.8.4", - "@types/redux-mock-store": "^1.0.2", - "@types/url-join": "^4.0.0", - "redux-mock-store": "^1.5.3" + "@types/url-join": "4.0.1", + "commonmark": "0.30.0", + "commonmark-spec": "0.30.0", + "cross-env": "7.0.3", + "react-svg-loader": "3.0.3", + "slate-hyperscript": "0.13.9", + "webpack": "4.46.0", + "webpack-cli": "4.10.0" } } diff --git a/packages/netlify-cms-core/src/__tests__/backend.spec.js b/packages/netlify-cms-core/src/__tests__/backend.spec.js deleted file mode 100644 index 8b7766ec..00000000 --- a/packages/netlify-cms-core/src/__tests__/backend.spec.js +++ /dev/null @@ -1,934 +0,0 @@ -import { Map, List, fromJS } from 'immutable'; - -import { - resolveBackend, - Backend, - extractSearchFields, - expandSearchEntries, - mergeExpandedEntries, -} from '../backend'; -import { getBackend } from '../lib/registry'; -import { FOLDER, FILES } from '../constants/collectionTypes'; - -jest.mock('../lib/registry'); -jest.mock('netlify-cms-lib-util'); -jest.mock('../lib/urlHelper'); - -describe('Backend', () => { - describe('filterEntries', () => { - let backend; - - beforeEach(() => { - getBackend.mockReturnValue({ - init: jest.fn(), - }); - backend = resolveBackend({ - backend: { - name: 'git-gateway', - }, - }); - }); - - it('filters string values', () => { - const result = backend.filterEntries( - { - entries: [ - { - data: { - testField: 'testValue', - }, - }, - { - data: { - testField: 'testValue2', - }, - }, - ], - }, - Map({ field: 'testField', value: 'testValue' }), - ); - - expect(result.length).toBe(1); - }); - - it('filters number values', () => { - const result = backend.filterEntries( - { - entries: [ - { - data: { - testField: 42, - }, - }, - { - data: { - testField: 5, - }, - }, - ], - }, - Map({ field: 'testField', value: 42 }), - ); - - expect(result.length).toBe(1); - }); - - it('filters boolean values', () => { - const result = backend.filterEntries( - { - entries: [ - { - data: { - testField: false, - }, - }, - { - data: { - testField: true, - }, - }, - ], - }, - Map({ field: 'testField', value: false }), - ); - - expect(result.length).toBe(1); - }); - - it('filters list values', () => { - const result = backend.filterEntries( - { - entries: [ - { - data: { - testField: ['valueOne', 'valueTwo', 'testValue'], - }, - }, - { - data: { - testField: ['valueThree'], - }, - }, - ], - }, - Map({ field: 'testField', value: 'testValue' }), - ); - - expect(result.length).toBe(1); - }); - }); - - describe('getLocalDraftBackup', () => { - const { localForage, asyncLock } = require('netlify-cms-lib-util'); - - asyncLock.mockImplementation(() => ({ acquire: jest.fn(), release: jest.fn() })); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should return empty object on no item', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - const collection = Map({ - name: 'posts', - }); - const slug = 'slug'; - - localForage.getItem.mockReturnValue(); - - const result = await backend.getLocalDraftBackup(collection, slug); - - expect(result).toEqual({}); - expect(localForage.getItem).toHaveBeenCalledTimes(1); - expect(localForage.getItem).toHaveBeenCalledWith('backup.posts.slug'); - }); - - it('should return empty object on item with empty content', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - const collection = Map({ - name: 'posts', - }); - const slug = 'slug'; - - localForage.getItem.mockReturnValue({ raw: '' }); - - const result = await backend.getLocalDraftBackup(collection, slug); - - expect(result).toEqual({}); - expect(localForage.getItem).toHaveBeenCalledTimes(1); - expect(localForage.getItem).toHaveBeenCalledWith('backup.posts.slug'); - }); - - it('should return backup entry, empty media files and assets when only raw property was saved', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - const collection = Map({ - name: 'posts', - }); - const slug = 'slug'; - - localForage.getItem.mockReturnValue({ - raw: '---\ntitle: "Hello World"\n---\n', - }); - - const result = await backend.getLocalDraftBackup(collection, slug); - - expect(result).toEqual({ - entry: { - author: '', - mediaFiles: [], - collection: 'posts', - slug: 'slug', - path: '', - partial: false, - raw: '---\ntitle: "Hello World"\n---\n', - data: { title: 'Hello World' }, - meta: {}, - i18n: {}, - label: null, - isModification: null, - status: '', - updatedOn: '', - }, - }); - expect(localForage.getItem).toHaveBeenCalledTimes(1); - expect(localForage.getItem).toHaveBeenCalledWith('backup.posts.slug'); - }); - - it('should return backup entry, media files and assets when all were backed up', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - const collection = Map({ - name: 'posts', - }); - const slug = 'slug'; - - localForage.getItem.mockReturnValue({ - raw: '---\ntitle: "Hello World"\n---\n', - mediaFiles: [{ id: '1' }], - }); - - const result = await backend.getLocalDraftBackup(collection, slug); - - expect(result).toEqual({ - entry: { - author: '', - mediaFiles: [{ id: '1' }], - collection: 'posts', - slug: 'slug', - path: '', - partial: false, - raw: '---\ntitle: "Hello World"\n---\n', - data: { title: 'Hello World' }, - meta: {}, - i18n: {}, - label: null, - isModification: null, - status: '', - updatedOn: '', - }, - }); - expect(localForage.getItem).toHaveBeenCalledTimes(1); - expect(localForage.getItem).toHaveBeenCalledWith('backup.posts.slug'); - }); - }); - - describe('persistLocalDraftBackup', () => { - const { localForage } = require('netlify-cms-lib-util'); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should not persist empty entry', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - backend.entryToRaw = jest.fn().mockReturnValue(''); - - const collection = Map({ - name: 'posts', - }); - - const slug = 'slug'; - - const entry = Map({ - slug, - }); - - await backend.persistLocalDraftBackup(entry, collection); - - expect(backend.entryToRaw).toHaveBeenCalledTimes(1); - expect(backend.entryToRaw).toHaveBeenCalledWith(collection, entry); - expect(localForage.setItem).toHaveBeenCalledTimes(0); - }); - - it('should persist non empty entry', async () => { - const implementation = { - init: jest.fn(() => implementation), - }; - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - backend.entryToRaw = jest.fn().mockReturnValue('content'); - - const collection = Map({ - name: 'posts', - }); - - const slug = 'slug'; - - const entry = Map({ - slug, - path: 'content/posts/entry.md', - mediaFiles: List([{ id: '1' }]), - }); - - await backend.persistLocalDraftBackup(entry, collection); - - expect(backend.entryToRaw).toHaveBeenCalledTimes(1); - expect(backend.entryToRaw).toHaveBeenCalledWith(collection, entry); - expect(localForage.setItem).toHaveBeenCalledTimes(2); - expect(localForage.setItem).toHaveBeenCalledWith('backup.posts.slug', { - mediaFiles: [{ id: '1' }], - path: 'content/posts/entry.md', - raw: 'content', - }); - expect(localForage.setItem).toHaveBeenCalledWith('backup', 'content'); - }); - }); - - describe('persistMedia', () => { - it('should persist media', async () => { - const persistMediaResult = {}; - const implementation = { - init: jest.fn(() => implementation), - persistMedia: jest.fn().mockResolvedValue(persistMediaResult), - }; - const config = { backend: { name: 'github' } }; - - const backend = new Backend(implementation, { config, backendName: config.backend.name }); - const user = { login: 'login', name: 'name' }; - backend.currentUser = jest.fn().mockResolvedValue(user); - - const file = { path: 'static/media/image.png' }; - - const result = await backend.persistMedia(config, file); - expect(result).toBe(persistMediaResult); - expect(implementation.persistMedia).toHaveBeenCalledTimes(1); - expect(implementation.persistMedia).toHaveBeenCalledWith( - { path: 'static/media/image.png' }, - { commitMessage: 'Upload “static/media/image.png”' }, - ); - }); - }); - - describe('unpublishedEntry', () => { - it('should return unpublished entry', async () => { - const unpublishedEntryResult = { - diffs: [{ path: 'src/posts/index.md', newFile: false }, { path: 'netlify.png' }], - }; - const implementation = { - init: jest.fn(() => implementation), - unpublishedEntry: jest.fn().mockResolvedValue(unpublishedEntryResult), - unpublishedEntryDataFile: jest - .fn() - .mockResolvedValueOnce('---\ntitle: "Hello World"\n---\n'), - unpublishedEntryMediaFile: jest.fn().mockResolvedValueOnce({ id: '1' }), - }; - const config = { - media_folder: 'static/images', - }; - - const backend = new Backend(implementation, { config, backendName: 'github' }); - - const collection = fromJS({ - name: 'posts', - folder: 'src/posts', - fields: [], - }); - - const state = { - config, - integrations: Map({}), - mediaLibrary: Map({}), - }; - - const slug = 'slug'; - - const result = await backend.unpublishedEntry(state, collection, slug); - expect(result).toEqual({ - author: '', - collection: 'posts', - slug: '', - path: 'src/posts/index.md', - partial: false, - raw: '---\ntitle: "Hello World"\n---\n', - data: { title: 'Hello World' }, - meta: { path: 'src/posts/index.md' }, - i18n: {}, - label: null, - isModification: true, - mediaFiles: [{ id: '1', draft: true }], - status: '', - updatedOn: '', - }); - }); - }); - - describe('generateUniqueSlug', () => { - beforeEach(() => { - jest.resetAllMocks(); - }); - - it("should return unique slug when entry doesn't exist", async () => { - const { sanitizeSlug } = require('../lib/urlHelper'); - sanitizeSlug.mockReturnValue('some-post-title'); - - const implementation = { - init: jest.fn(() => implementation), - getEntry: jest.fn(() => Promise.resolve()), - }; - - const collection = fromJS({ - name: 'posts', - fields: [ - { - name: 'title', - }, - ], - type: FOLDER, - folder: 'posts', - slug: '{{slug}}', - path: 'sub_dir/{{slug}}', - }); - - const entry = Map({ - title: 'some post title', - }); - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - await expect(backend.generateUniqueSlug(collection, entry, Map({}), [])).resolves.toBe( - 'sub_dir/some-post-title', - ); - }); - - it('should return unique slug when entry exists', async () => { - const { sanitizeSlug, sanitizeChar } = require('../lib/urlHelper'); - sanitizeSlug.mockReturnValue('some-post-title'); - sanitizeChar.mockReturnValue('-'); - - const implementation = { - init: jest.fn(() => implementation), - getEntry: jest.fn(), - }; - - implementation.getEntry.mockResolvedValueOnce({ data: 'data' }); - implementation.getEntry.mockResolvedValueOnce(); - - const collection = fromJS({ - name: 'posts', - fields: [ - { - name: 'title', - }, - ], - type: FOLDER, - folder: 'posts', - slug: '{{slug}}', - path: 'sub_dir/{{slug}}', - }); - - const entry = Map({ - title: 'some post title', - }); - - const backend = new Backend(implementation, { config: {}, backendName: 'github' }); - - await expect(backend.generateUniqueSlug(collection, entry, Map({}), [])).resolves.toBe( - 'sub_dir/some-post-title-1', - ); - }); - }); - - describe('extractSearchFields', () => { - it('should extract slug', () => { - expect(extractSearchFields(['slug'])({ slug: 'entry-slug', data: {} })).toEqual( - ' entry-slug', - ); - }); - - it('should extract path', () => { - expect(extractSearchFields(['path'])({ path: 'entry-path', data: {} })).toEqual( - ' entry-path', - ); - }); - - it('should extract fields', () => { - expect( - extractSearchFields(['title', 'order'])({ data: { title: 'Entry Title', order: 5 } }), - ).toEqual(' Entry Title 5'); - }); - - it('should extract nested fields', () => { - expect( - extractSearchFields(['nested.title'])({ data: { nested: { title: 'nested title' } } }), - ).toEqual(' nested title'); - }); - }); - - describe('search/query', () => { - const collections = [ - fromJS({ - name: 'posts', - folder: 'posts', - fields: [ - { name: 'title', widget: 'string' }, - { name: 'short_title', widget: 'string' }, - { name: 'author', widget: 'string' }, - { name: 'description', widget: 'string' }, - { name: 'nested', widget: 'object', fields: { name: 'title', widget: 'string' } }, - ], - }), - fromJS({ - name: 'pages', - folder: 'pages', - fields: [ - { name: 'title', widget: 'string' }, - { name: 'short_title', widget: 'string' }, - { name: 'author', widget: 'string' }, - { name: 'description', widget: 'string' }, - { name: 'nested', widget: 'object', fields: { name: 'title', widget: 'string' } }, - ], - }), - ]; - - const posts = [ - { - path: 'posts/find-me.md', - slug: 'find-me', - data: { - title: 'find me by title', - short_title: 'find me by short title', - author: 'find me by author', - description: 'find me by description', - nested: { title: 'find me by nested title' }, - }, - }, - { path: 'posts/not-me.md', slug: 'not-me', data: { title: 'not me' } }, - ]; - - const pages = [ - { - path: 'pages/find-me.md', - slug: 'find-me', - data: { - title: 'find me by title', - short_title: 'find me by short title', - author: 'find me by author', - description: 'find me by description', - nested: { title: 'find me by nested title' }, - }, - }, - { path: 'pages/not-me.md', slug: 'not-me', data: { title: 'not me' } }, - ]; - - const files = [ - { - path: 'files/file1.md', - slug: 'file1', - data: { - author: 'find me by author', - }, - }, - { - path: 'files/file2.md', - slug: 'file2', - data: { - other: 'find me by other', - }, - }, - ]; - - const implementation = { - init: jest.fn(() => implementation), - }; - - let backend; - beforeEach(() => { - backend = new Backend(implementation, { config: {}, backendName: 'github' }); - backend.listAllEntries = jest.fn(collection => { - if (collection.get('name') === 'posts') { - return Promise.resolve(posts); - } - if (collection.get('name') === 'pages') { - return Promise.resolve(pages); - } - if (collection.get('name') === 'files') { - return Promise.resolve(files); - } - return Promise.resolve([]); - }); - }); - - it('should search collections by title', async () => { - const results = await backend.search(collections, 'find me by title'); - - expect(results).toEqual({ - entries: [posts[0], pages[0]], - }); - }); - - it('should search collections by short title', async () => { - const results = await backend.search(collections, 'find me by short title'); - - expect(results).toEqual({ - entries: [posts[0], pages[0]], - }); - }); - - it('should search collections by author', async () => { - const results = await backend.search(collections, 'find me by author'); - - expect(results).toEqual({ - entries: [posts[0], pages[0]], - }); - }); - - it('should search collections by summary description', async () => { - const results = await backend.search( - collections.map(c => c.set('summary', '{{description}}')), - 'find me by description', - ); - - expect(results).toEqual({ - entries: [posts[0], pages[0]], - }); - }); - - it('should search in file collection using top level fields', async () => { - const collections = [ - fromJS({ - name: 'files', - files: [ - { - name: 'file1', - fields: [{ name: 'author', widget: 'string' }], - }, - { - name: 'file2', - fields: [{ name: 'other', widget: 'string' }], - }, - ], - type: FILES, - }), - ]; - - expect(await backend.search(collections, 'find me by author')).toEqual({ - entries: [files[0]], - }); - expect(await backend.search(collections, 'find me by other')).toEqual({ - entries: [files[1]], - }); - }); - - it('should query collections by title', async () => { - const results = await backend.query(collections[0], ['title'], 'find me by title'); - - expect(results).toEqual({ - hits: [posts[0]], - query: 'find me by title', - }); - }); - - it('should query collections by slug', async () => { - const results = await backend.query(collections[0], ['slug'], 'find-me'); - - expect(results).toEqual({ - hits: [posts[0]], - query: 'find-me', - }); - }); - - it('should query collections by path', async () => { - const results = await backend.query(collections[0], ['path'], 'posts/find-me.md'); - - expect(results).toEqual({ - hits: [posts[0]], - query: 'posts/find-me.md', - }); - }); - - it('should query collections by nested field', async () => { - const results = await backend.query( - collections[0], - ['nested.title'], - 'find me by nested title', - ); - - expect(results).toEqual({ - hits: [posts[0]], - query: 'find me by nested title', - }); - }); - }); - - describe('expandSearchEntries', () => { - it('should expand entry with list to multiple entries', () => { - const entry = { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - ], - }, - }, - list: [1, 2], - }, - }; - - expect(expandSearchEntries([entry], ['list.*', 'field.nested.list.*.name'])).toEqual([ - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - ], - }, - }, - list: [1, 2], - }, - field: 'list.0', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - ], - }, - }, - list: [1, 2], - }, - field: 'list.1', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.0.name', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.1.name', - }, - ]); - }); - }); - - describe('mergeExpandedEntries', () => { - it('should merge entries and filter data', () => { - const expanded = [ - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.0.name', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.3.name', - }, - ]; - - expect(mergeExpandedEntries(expanded)).toEqual([ - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - }, - ]); - }); - - it('should merge entries and filter data based on different fields', () => { - const expanded = [ - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.0.name', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - field: 'field.nested.list.3.name', - }, - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 2, name: '2' }, - { id: 3, name: '3' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [1, 2], - }, - field: 'list.1', - }, - ]; - - expect(mergeExpandedEntries(expanded)).toEqual([ - { - data: { - field: { - nested: { - list: [ - { id: 1, name: '1' }, - { id: 4, name: '4' }, - ], - }, - }, - list: [2], - }, - }, - ]); - }); - - it('should merge entries and keep sort by entry index', () => { - const expanded = [ - { - data: { - list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], - }, - field: 'list.5', - }, - { - data: { - list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], - }, - field: 'list.0', - }, - { - data: { - list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], - }, - field: 'list.11', - }, - { - data: { - list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], - }, - field: 'list.1', - }, - ]; - - expect(mergeExpandedEntries(expanded)).toEqual([ - { - data: { - list: [5, 0, 11, 1], - }, - }, - ]); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/config.spec.js b/packages/netlify-cms-core/src/actions/__tests__/config.spec.js deleted file mode 100644 index 6ba8e59d..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/config.spec.js +++ /dev/null @@ -1,1009 +0,0 @@ -import { stripIndent } from 'common-tags'; -import yaml from 'js-yaml'; - -import { - loadConfig, - parseConfig, - normalizeConfig, - applyDefaults, - detectProxyServer, - handleLocalBackend, -} from '../config'; - -jest.spyOn(console, 'log').mockImplementation(() => {}); -jest.spyOn(console, 'warn').mockImplementation(() => {}); -jest.mock('../../backend', () => { - return { - resolveBackend: jest.fn(() => ({ isGitBackend: jest.fn(() => true) })), - }; -}); -jest.mock('../../constants/configSchema'); - -describe('config', () => { - describe('parseConfig', () => { - it('can parse simple yaml config', () => { - const file = stripIndent` - backend: - name: test-repo - media_folder: static/images - `; - - expect(parseConfig(file)).toEqual({ - backend: { name: 'test-repo' }, - media_folder: 'static/images', - }); - }); - - it('should merge yaml aliases', () => { - const file = stripIndent` - backend: - name: github - repo: netlify/netlify-cms - squash_merges: true - open_authoring: true - local_backend: true - site_url: https://www.netlifycms.org - publish_mode: editorial_workflow - media_folder: website/static/img - public_folder: img - docs_collection: &docs_collection - folder: website/content/docs - create: true - preview_path: 'docs/{{slug}}' - fields: - - { label: Title, name: title } - - { label: Body, name: body, widget: markdown } - collections: - - <<: *docs_collection - name: docs_start - label: 'Docs: Quick Start' - `; - - expect(parseConfig(file)).toEqual({ - backend: { - name: 'github', - repo: 'netlify/netlify-cms', - squash_merges: true, - open_authoring: true, - }, - local_backend: true, - site_url: 'https://www.netlifycms.org', - publish_mode: 'editorial_workflow', - media_folder: 'website/static/img', - public_folder: 'img', - docs_collection: { - folder: 'website/content/docs', - create: true, - preview_path: 'docs/{{slug}}', - fields: [ - { label: 'Title', name: 'title' }, - { label: 'Body', name: 'body', widget: 'markdown' }, - ], - }, - collections: [ - { - folder: 'website/content/docs', - create: true, - preview_path: 'docs/{{slug}}', - fields: [ - { label: 'Title', name: 'title' }, - { label: 'Body', name: 'body', widget: 'markdown' }, - ], - name: 'docs_start', - label: 'Docs: Quick Start', - }, - ], - }); - }); - }); - describe('applyDefaults', () => { - describe('publish_mode', () => { - it('should set publish_mode if not set', () => { - const config = { - foo: 'bar', - media_folder: 'path/to/media', - public_folder: '/path/to/media', - collections: [], - }; - expect(applyDefaults(config).publish_mode).toEqual('simple'); - }); - - it('should set publish_mode from config', () => { - const config = { - foo: 'bar', - publish_mode: 'complex', - media_folder: 'path/to/media', - public_folder: '/path/to/media', - collections: [], - }; - expect(applyDefaults(config).publish_mode).toEqual('complex'); - }); - }); - - describe('public_folder', () => { - it('should set public_folder based on media_folder if not set', () => { - expect( - applyDefaults({ - foo: 'bar', - media_folder: 'path/to/media', - collections: [], - }).public_folder, - ).toEqual('/path/to/media'); - }); - - it('should not overwrite public_folder if set', () => { - expect( - applyDefaults({ - foo: 'bar', - media_folder: 'path/to/media', - public_folder: '/publib/path', - collections: [], - }).public_folder, - ).toEqual('/publib/path'); - expect( - applyDefaults({ - foo: 'bar', - media_folder: 'path/to/media', - public_folder: '', - collections: [], - }).public_folder, - ).toEqual(''); - }); - }); - - describe('slug', () => { - it('should set default slug config if not set', () => { - expect(applyDefaults({ collections: [] }).slug).toEqual({ - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', - }); - }); - - it('should not overwrite slug encoding if set', () => { - expect( - applyDefaults({ collections: [], slug: { encoding: 'ascii' } }).slug.encoding, - ).toEqual('ascii'); - }); - - it('should not overwrite slug clean_accents if set', () => { - expect( - applyDefaults({ collections: [], slug: { clean_accents: true } }).slug.clean_accents, - ).toEqual(true); - }); - - it('should not overwrite slug sanitize_replacement if set', () => { - expect( - applyDefaults({ collections: [], slug: { sanitize_replacement: '_' } }).slug - .sanitize_replacement, - ).toEqual('_'); - }); - }); - - describe('collections', () => { - it('should strip leading slashes from collection folder', () => { - expect( - applyDefaults({ - collections: [{ folder: '/foo', fields: [{ name: 'title', widget: 'string' }] }], - }).collections[0].folder, - ).toEqual('foo'); - }); - - it('should strip leading slashes from collection files', () => { - expect( - applyDefaults({ - collections: [ - { files: [{ file: '/foo', fields: [{ name: 'title', widget: 'string' }] }] }, - ], - }).collections[0].files[0].file, - ).toEqual('foo'); - }); - - describe('public_folder and media_folder', () => { - it('should set collection public_folder based on media_folder if not set', () => { - expect( - applyDefaults({ - collections: [ - { - folder: 'foo', - media_folder: 'static/images/docs', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].public_folder, - ).toEqual('static/images/docs'); - }); - - it('should not overwrite collection public_folder if set to non empty string', () => { - expect( - applyDefaults({ - collections: [ - { - folder: 'foo', - media_folder: 'static/images/docs', - public_folder: 'images/docs', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].public_folder, - ).toEqual('images/docs'); - }); - - it('should not overwrite collection public_folder if set to empty string', () => { - expect( - applyDefaults({ - collections: [ - { - folder: 'foo', - media_folder: 'static/images/docs', - public_folder: '', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].public_folder, - ).toEqual(''); - }); - - it("should set collection media_folder and public_folder to an empty string when collection path exists, but collection media_folder doesn't", () => { - const result = applyDefaults({ - collections: [ - { - folder: 'foo', - path: '{{slug}}/index', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }); - expect(result.collections[0].media_folder).toEqual(''); - expect(result.collections[0].public_folder).toEqual(''); - }); - - it('should set file public_folder based on media_folder if not set', () => { - expect( - applyDefaults({ - collections: [ - { - files: [ - { - file: 'foo', - media_folder: 'static/images/docs', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }, - ], - }).collections[0].files[0].public_folder, - ).toEqual('static/images/docs'); - }); - - it('should not overwrite file public_folder if set', () => { - expect( - applyDefaults({ - collections: [ - { - files: [ - { - file: 'foo', - media_folder: 'static/images/docs', - public_folder: 'images/docs', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }, - ], - }).collections[0].files[0].public_folder, - ).toEqual('images/docs'); - }); - - it('should set nested field public_folder based on media_folder if not set', () => { - const config = applyDefaults({ - collections: [ - { - folder: 'foo', - path: '{{slug}}/index', - fields: [ - { - name: 'title', - widget: 'string', - media_folder: 'collection/static/images/docs', - }, - ], - }, - { - files: [ - { - file: 'foo', - fields: [ - { - name: 'title', - widget: 'string', - media_folder: 'file/static/images/docs', - }, - ], - }, - ], - }, - ], - }); - expect(config.collections[0].fields[0].public_folder).toEqual( - 'collection/static/images/docs', - ); - expect(config.collections[1].files[0].fields[0].public_folder).toEqual( - 'file/static/images/docs', - ); - }); - - it('should not overwrite nested field public_folder if set', () => { - const config = applyDefaults({ - collections: [ - { - folder: 'foo', - path: '{{slug}}/index', - fields: [ - { - name: 'title', - widget: 'string', - media_folder: 'collection/static/images/docs', - public_folder: 'collection/public_folder', - }, - ], - }, - { - files: [ - { - file: 'foo', - fields: [ - { - name: 'title', - widget: 'string', - public_folder: 'file/public_folder', - }, - ], - }, - ], - }, - ], - }); - expect(config.collections[0].fields[0].public_folder).toEqual('collection/public_folder'); - expect(config.collections[1].files[0].fields[0].public_folder).toEqual( - 'file/public_folder', - ); - }); - }); - - describe('publish', () => { - it('should set publish to true if not set', () => { - expect( - applyDefaults({ - collections: [ - { - folder: 'foo', - media_folder: 'static/images/docs', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].publish, - ).toEqual(true); - }); - - it('should not override existing publish config', () => { - expect( - applyDefaults({ - collections: [ - { - folder: 'foo', - media_folder: 'static/images/docs', - publish: false, - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].publish, - ).toEqual(false); - }); - }); - - describe('editor preview', () => { - it('should set editor preview honoring global config before and specific config after', () => { - const config = applyDefaults({ - editor: { - preview: false, - }, - collections: [ - { - fields: [{ name: 'title' }], - folder: 'foo', - }, - { - editor: { - preview: true, - }, - fields: [{ name: 'title' }], - folder: 'bar', - }, - ], - }); - - expect(config.collections[0].editor.preview).toEqual(false); - expect(config.collections[1].editor.preview).toEqual(true); - }); - }); - }); - - test('should convert camel case to snake case', () => { - expect( - applyDefaults( - normalizeConfig({ - collections: [ - { - sortableFields: ['title'], - folder: 'src', - identifier_field: 'datetime', - fields: [ - { - name: 'datetime', - widget: 'datetime', - dateFormat: 'YYYY/MM/DD', - timeFormat: 'HH:mm', - pickerUtc: true, - }, - { - widget: 'number', - valueType: 'float', - }, - ], - }, - { - sortableFields: [], - files: [ - { - name: 'file', - file: 'src/file.json', - fields: [ - { - widget: 'markdown', - editorComponents: ['code'], - }, - { - widget: 'relation', - valueField: 'title', - searchFields: ['title'], - displayFields: ['title'], - optionsLength: 5, - }, - ], - }, - ], - }, - ], - }), - ), - ).toEqual({ - collections: [ - { - sortable_fields: ['title'], - folder: 'src', - type: 'folder_based_collection', - view_filters: [], - view_groups: [], - identifier_field: 'datetime', - fields: [ - { - name: 'datetime', - widget: 'datetime', - date_format: 'YYYY/MM/DD', - dateFormat: 'YYYY/MM/DD', - time_format: 'HH:mm', - timeFormat: 'HH:mm', - picker_utc: true, - pickerUtc: true, - }, - { - widget: 'number', - value_type: 'float', - valueType: 'float', - }, - ], - publish: true, - }, - { - sortable_fields: [], - files: [ - { - name: 'file', - file: 'src/file.json', - fields: [ - { - widget: 'markdown', - editor_components: ['code'], - editorComponents: ['code'], - }, - { - widget: 'relation', - value_field: 'title', - valueField: 'title', - search_fields: ['title'], - searchFields: ['title'], - display_fields: ['title'], - displayFields: ['title'], - options_length: 5, - optionsLength: 5, - }, - ], - }, - ], - type: 'file_based_collection', - view_filters: [], - view_groups: [], - publish: true, - }, - ], - public_folder: '/', - publish_mode: 'simple', - slug: { clean_accents: false, encoding: 'unicode', sanitize_replacement: '-' }, - }); - }); - - describe('i18n', () => { - it('should set root i18n on collection when collection i18n is set to true', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { folder: 'foo', i18n: true, fields: [{ name: 'title', widget: 'string' }] }, - ], - }).collections[0].i18n, - ).toEqual({ structure: 'multiple_folders', locales: ['en', 'de'], default_locale: 'en' }); - }); - - it('should not set root i18n on collection when collection i18n is not set', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [{ folder: 'foo', fields: [{ name: 'title', widget: 'string' }] }], - }).collections[0].i18n, - ).toBeUndefined(); - }); - - it('should not set root i18n on collection when collection i18n is set to false', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { folder: 'foo', i18n: false, fields: [{ name: 'title', widget: 'string' }] }, - ], - }).collections[0].i18n, - ).toBeUndefined(); - }); - - it('should merge root i18n on collection when collection i18n is set to an object', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - default_locale: 'en', - }, - collections: [ - { - folder: 'foo', - i18n: { locales: ['en', 'fr'], default_locale: 'fr' }, - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }).collections[0].i18n, - ).toEqual({ structure: 'multiple_folders', locales: ['en', 'fr'], default_locale: 'fr' }); - }); - - it('should throw when i18n structure is not single_file on files collection', () => { - expect(() => - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - files: [ - { - name: 'file', - file: 'file', - i18n: true, - fields: [{ name: 'title', widget: 'string', i18n: true }], - }, - ], - i18n: true, - }, - ], - }), - ).toThrow('i18n configuration for files collections is limited to single_file structure'); - }); - - it('should throw when i18n structure is set to multiple_folders and contains a single file collection', () => { - expect(() => - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - files: [ - { name: 'file', file: 'file', fields: [{ name: 'title', widget: 'string' }] }, - ], - i18n: true, - }, - ], - }), - ).toThrow('i18n configuration for files collections is limited to single_file structure'); - }); - - it('should throw when i18n structure is set to multiple_files and contains a single file collection', () => { - expect(() => - applyDefaults({ - i18n: { - structure: 'multiple_files', - locales: ['en', 'de'], - }, - collections: [ - { - files: [ - { name: 'file', file: 'file', fields: [{ name: 'title', widget: 'string' }] }, - ], - i18n: true, - }, - ], - }), - ).toThrow('i18n configuration for files collections is limited to single_file structure'); - }); - - it('should set i18n value to translate on field when i18n=true for field in files collection', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - files: [ - { - name: 'file', - file: 'file', - i18n: true, - fields: [{ name: 'title', widget: 'string', i18n: true }], - }, - ], - i18n: { - structure: 'single_file', - }, - }, - ], - }).collections[0].files[0].fields[0].i18n, - ).toEqual('translate'); - }); - - it('should set i18n value to translate on field when i18n=true for field', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - folder: 'foo', - i18n: true, - fields: [{ name: 'title', widget: 'string', i18n: true }], - }, - ], - }).collections[0].fields[0].i18n, - ).toEqual('translate'); - }); - - it('should set i18n value to none on field when i18n=false for field', () => { - expect( - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - folder: 'foo', - i18n: true, - fields: [{ name: 'title', widget: 'string', i18n: false }], - }, - ], - }).collections[0].fields[0].i18n, - ).toEqual('none'); - }); - - it('should throw is default locale is missing from root i18n config', () => { - expect(() => - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - default_locale: 'fr', - }, - collections: [ - { - folder: 'foo', - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }), - ).toThrow("i18n locales 'en, de' are missing the default locale fr"); - }); - - it('should throw is default locale is missing from collection i18n config', () => { - expect(() => - applyDefaults({ - i18n: { - structure: 'multiple_folders', - locales: ['en', 'de'], - }, - collections: [ - { - folder: 'foo', - i18n: { - default_locale: 'fr', - }, - fields: [{ name: 'title', widget: 'string' }], - }, - ], - }), - ).toThrow("i18n locales 'en, de' are missing the default locale fr"); - }); - }); - }); - - describe('detectProxyServer', () => { - function assetFetchCalled(url = 'http://localhost:8081/api/v1') { - expect(global.fetch).toHaveBeenCalledTimes(1); - expect(global.fetch).toHaveBeenCalledWith(url, { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ action: 'info' }), - }); - } - - beforeEach(() => { - delete window.location; - }); - - it('should return empty object when not on localhost', async () => { - window.location = { hostname: 'www.netlify.com' }; - global.fetch = jest.fn(); - await expect(detectProxyServer()).resolves.toEqual({}); - - expect(global.fetch).toHaveBeenCalledTimes(0); - }); - - it('should return empty object when fetch returns an error', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockRejectedValue(new Error()); - await expect(detectProxyServer(true)).resolves.toEqual({}); - - assetFetchCalled(); - }); - - it('should return empty object when fetch returns an invalid response', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest - .fn() - .mockResolvedValue({ json: jest.fn().mockResolvedValue({ repo: [] }) }); - await expect(detectProxyServer(true)).resolves.toEqual({}); - - assetFetchCalled(); - }); - - it('should return result object when fetch returns a valid response', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockResolvedValue({ - json: jest.fn().mockResolvedValue({ - repo: 'test-repo', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }), - }); - await expect(detectProxyServer(true)).resolves.toEqual({ - proxyUrl: 'http://localhost:8081/api/v1', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }); - - assetFetchCalled(); - }); - - it('should use local_backend url', async () => { - const url = 'http://localhost:8082/api/v1'; - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockResolvedValue({ - json: jest.fn().mockResolvedValue({ - repo: 'test-repo', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }), - }); - await expect(detectProxyServer({ url })).resolves.toEqual({ - proxyUrl: url, - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }); - - assetFetchCalled(url); - }); - - it('should use local_backend allowed_hosts', async () => { - const allowed_hosts = ['192.168.0.1']; - window.location = { hostname: '192.168.0.1' }; - global.fetch = jest.fn().mockResolvedValue({ - json: jest.fn().mockResolvedValue({ - repo: 'test-repo', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }), - }); - await expect(detectProxyServer({ allowed_hosts })).resolves.toEqual({ - proxyUrl: 'http://192.168.0.1:8081/api/v1', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }); - - assetFetchCalled('http://192.168.0.1:8081/api/v1'); - }); - }); - - describe('handleLocalBackend', () => { - beforeEach(() => { - delete window.location; - }); - - it('should not replace backend config when proxy is not detected', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockRejectedValue(new Error()); - - const config = { local_backend: true, backend: { name: 'github' } }; - const actual = await handleLocalBackend(config); - - expect(actual).toEqual(config); - }); - - it('should replace backend config when proxy is detected', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockResolvedValue({ - json: jest.fn().mockResolvedValue({ - repo: 'test-repo', - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }), - }); - - const config = { local_backend: true, backend: { name: 'github' } }; - const actual = await handleLocalBackend(config); - - expect(actual).toEqual({ - local_backend: true, - backend: { name: 'proxy', proxy_url: 'http://localhost:8081/api/v1' }, - }); - }); - - it('should replace publish mode when not supported by proxy', async () => { - window.location = { hostname: 'localhost' }; - global.fetch = jest.fn().mockResolvedValue({ - json: jest.fn().mockResolvedValue({ - repo: 'test-repo', - publish_modes: ['simple'], - type: 'local_fs', - }), - }); - - const config = { - local_backend: true, - publish_mode: 'editorial_workflow', - backend: { name: 'github' }, - }; - const actual = await handleLocalBackend(config); - - expect(actual).toEqual({ - local_backend: true, - publish_mode: 'simple', - backend: { name: 'proxy', proxy_url: 'http://localhost:8081/api/v1' }, - }); - }); - }); - - describe('loadConfig', () => { - beforeEach(() => { - document.querySelector = jest.fn(); - global.fetch = jest.fn(); - }); - - test(`should fetch default 'config.yml'`, async () => { - const dispatch = jest.fn(); - - global.fetch.mockResolvedValue({ - status: 200, - text: () => Promise.resolve(yaml.dump({ backend: { repo: 'test-repo' } })), - headers: new Headers(), - }); - await loadConfig()(dispatch); - - expect(global.fetch).toHaveBeenCalledTimes(1); - expect(global.fetch).toHaveBeenCalledWith('config.yml', { credentials: 'same-origin' }); - - expect(dispatch).toHaveBeenCalledTimes(2); - expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' }); - expect(dispatch).toHaveBeenCalledWith({ - type: 'CONFIG_SUCCESS', - payload: { - backend: { repo: 'test-repo' }, - collections: [], - publish_mode: 'simple', - slug: { encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' }, - public_folder: '/', - }, - }); - }); - - test(`should fetch from custom 'config.yml'`, async () => { - const dispatch = jest.fn(); - - document.querySelector.mockReturnValue({ type: 'text/yaml', href: 'custom-config.yml' }); - global.fetch.mockResolvedValue({ - status: 200, - text: () => Promise.resolve(yaml.dump({ backend: { repo: 'github' } })), - headers: new Headers(), - }); - await loadConfig()(dispatch); - - expect(document.querySelector).toHaveBeenCalledTimes(1); - expect(document.querySelector).toHaveBeenCalledWith('link[rel="cms-config-url"]'); - - expect(global.fetch).toHaveBeenCalledTimes(1); - expect(global.fetch).toHaveBeenCalledWith('custom-config.yml', { - credentials: 'same-origin', - }); - - expect(dispatch).toHaveBeenCalledTimes(2); - expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' }); - expect(dispatch).toHaveBeenCalledWith({ - type: 'CONFIG_SUCCESS', - payload: { - backend: { repo: 'github' }, - collections: [], - publish_mode: 'simple', - slug: { encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' }, - public_folder: '/', - }, - }); - }); - - test(`should throw on failure to fetch 'config.yml'`, async () => { - const dispatch = jest.fn(); - - global.fetch.mockRejectedValue(new Error('Failed to fetch')); - await expect(() => loadConfig()(dispatch)).rejects.toEqual( - new Error('Failed to load config.yml (Failed to fetch)'), - ); - - expect(dispatch).toHaveBeenCalledTimes(2); - expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' }); - expect(dispatch).toHaveBeenCalledWith({ - type: 'CONFIG_FAILURE', - error: 'Error loading config', - payload: new Error('Failed to load config.yml (Failed to fetch)'), - }); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/editorialWorkflow.spec.js b/packages/netlify-cms-core/src/actions/__tests__/editorialWorkflow.spec.js deleted file mode 100644 index b3240908..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/editorialWorkflow.spec.js +++ /dev/null @@ -1,224 +0,0 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import { fromJS } from 'immutable'; - -import { addAssets } from '../media'; -import * as actions from '../editorialWorkflow'; - -jest.mock('../../backend'); -jest.mock('../../valueObjects/AssetProxy'); -jest.mock('netlify-cms-lib-util'); -jest.mock('uuid/v4', () => { - return jest.fn().mockReturnValue('000000000000000000000'); -}); -jest.mock('redux-notifications', () => { - const actual = jest.requireActual('redux-notifications'); - return { - ...actual, - actions: { - notifSend: jest.fn().mockImplementation(payload => ({ - type: 'NOTIF_SEND', - ...payload, - })), - }, - }; -}); - -const middlewares = [thunk]; -const mockStore = configureMockStore(middlewares); - -describe('editorialWorkflow actions', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('loadUnpublishedEntry', () => { - it('should load unpublished entry', () => { - const { currentBackend } = require('../../backend'); - const { createAssetProxy } = require('../../valueObjects/AssetProxy'); - - const assetProxy = { name: 'name', path: 'path' }; - const entry = { mediaFiles: [{ file: { name: 'name' }, id: '1', draft: true }] }; - const backend = { - unpublishedEntry: jest.fn().mockResolvedValue(entry), - }; - - const store = mockStore({ - config: fromJS({}), - collections: fromJS({ - posts: { name: 'posts' }, - }), - mediaLibrary: fromJS({ - isLoading: false, - }), - editorialWorkflow: fromJS({ - pages: { ids: [] }, - }), - }); - - currentBackend.mockReturnValue(backend); - createAssetProxy.mockResolvedValue(assetProxy); - - const slug = 'slug'; - const collection = store.getState().collections.get('posts'); - - return store.dispatch(actions.loadUnpublishedEntry(collection, slug)).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(4); - expect(actions[0]).toEqual({ - type: 'UNPUBLISHED_ENTRY_REQUEST', - payload: { - collection: 'posts', - slug, - }, - }); - expect(actions[1]).toEqual(addAssets([assetProxy])); - expect(actions[2]).toEqual({ - type: 'UNPUBLISHED_ENTRY_SUCCESS', - payload: { - collection: 'posts', - entry: { ...entry, mediaFiles: [{ file: { name: 'name' }, id: '1', draft: true }] }, - }, - }); - expect(actions[3]).toEqual({ - type: 'DRAFT_CREATE_FROM_ENTRY', - payload: { - entry, - }, - }); - }); - }); - }); - - describe('publishUnpublishedEntry', () => { - it('should publish unpublished entry and report success', () => { - const { currentBackend } = require('../../backend'); - - const entry = {}; - const backend = { - publishUnpublishedEntry: jest.fn().mockResolvedValue(), - getEntry: jest.fn().mockResolvedValue(entry), - getMedia: jest.fn().mockResolvedValue([]), - }; - - const store = mockStore({ - config: fromJS({}), - integrations: fromJS([]), - mediaLibrary: fromJS({ - isLoading: false, - }), - collections: fromJS({ - posts: { name: 'posts' }, - }), - }); - - currentBackend.mockReturnValue(backend); - - const slug = 'slug'; - - return store.dispatch(actions.publishUnpublishedEntry('posts', slug)).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(8); - - expect(actions[0]).toEqual({ - type: 'UNPUBLISHED_ENTRY_PUBLISH_REQUEST', - payload: { - collection: 'posts', - slug, - }, - }); - expect(actions[1]).toEqual({ - type: 'MEDIA_LOAD_REQUEST', - payload: { - page: 1, - }, - }); - expect(actions[2]).toEqual({ - type: 'NOTIF_SEND', - message: { key: 'ui.toast.entryPublished' }, - kind: 'success', - dismissAfter: 4000, - }); - expect(actions[3]).toEqual({ - type: 'UNPUBLISHED_ENTRY_PUBLISH_SUCCESS', - payload: { - collection: 'posts', - slug, - }, - }); - - expect(actions[4]).toEqual({ - type: 'MEDIA_LOAD_SUCCESS', - payload: { - files: [], - }, - }); - expect(actions[5]).toEqual({ - type: 'ENTRY_REQUEST', - payload: { - slug, - collection: 'posts', - }, - }); - expect(actions[6]).toEqual({ - type: 'ENTRY_SUCCESS', - payload: { - entry, - collection: 'posts', - }, - }); - expect(actions[7]).toEqual({ - type: 'DRAFT_CREATE_FROM_ENTRY', - payload: { - entry, - }, - }); - }); - }); - - it('should publish unpublished entry and report error', () => { - const { currentBackend } = require('../../backend'); - - const error = new Error('failed to publish entry'); - const backend = { - publishUnpublishedEntry: jest.fn().mockRejectedValue(error), - }; - - const store = mockStore({ - config: fromJS({}), - collections: fromJS({ - posts: { name: 'posts' }, - }), - }); - - currentBackend.mockReturnValue(backend); - - const slug = 'slug'; - - return store.dispatch(actions.publishUnpublishedEntry('posts', slug)).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(3); - expect(actions[0]).toEqual({ - type: 'UNPUBLISHED_ENTRY_PUBLISH_REQUEST', - payload: { - collection: 'posts', - slug, - }, - }); - expect(actions[1]).toEqual({ - type: 'NOTIF_SEND', - message: { key: 'ui.toast.onFailToPublishEntry', details: error }, - kind: 'danger', - dismissAfter: 8000, - }); - expect(actions[2]).toEqual({ - type: 'UNPUBLISHED_ENTRY_PUBLISH_FAILURE', - payload: { - collection: 'posts', - slug, - }, - }); - }); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/entries.spec.js b/packages/netlify-cms-core/src/actions/__tests__/entries.spec.js deleted file mode 100644 index a80aa2e8..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/entries.spec.js +++ /dev/null @@ -1,575 +0,0 @@ -import { fromJS, Map } from 'immutable'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; - -import { - createEmptyDraft, - createEmptyDraftData, - retrieveLocalBackup, - persistLocalBackup, - getMediaAssets, - validateMetaField, -} from '../entries'; -import AssetProxy from '../../valueObjects/AssetProxy'; - -jest.mock('../../backend'); -jest.mock('netlify-cms-lib-util'); -jest.mock('../mediaLibrary'); -jest.mock('../../reducers/entries'); -jest.mock('../../reducers/entryDraft'); - -const middlewares = [thunk]; -const mockStore = configureMockStore(middlewares); - -describe('entries', () => { - describe('createEmptyDraft', () => { - const { currentBackend } = require('../../backend'); - const backend = { - processEntry: jest.fn((_state, _collection, entry) => Promise.resolve(entry)), - }; - - currentBackend.mockReturnValue(backend); - - beforeEach(() => { - jest.clearAllMocks(); - }); - it('should dispatch draft created action', () => { - const store = mockStore({ mediaLibrary: fromJS({ files: [] }) }); - - const collection = fromJS({ - fields: [{ name: 'title' }], - }); - - return store.dispatch(createEmptyDraft(collection, '')).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(1); - - expect(actions[0]).toEqual({ - payload: { - author: '', - collection: undefined, - data: {}, - meta: {}, - i18n: {}, - isModification: null, - label: null, - mediaFiles: [], - partial: false, - path: '', - raw: '', - slug: '', - status: '', - updatedOn: '', - }, - type: 'DRAFT_CREATE_EMPTY', - }); - }); - }); - - it('should populate draft entry from URL param', () => { - const store = mockStore({ mediaLibrary: fromJS({ files: [] }) }); - - const collection = fromJS({ - fields: [{ name: 'title' }, { name: 'boolean' }], - }); - - return store.dispatch(createEmptyDraft(collection, '?title=title&boolean=True')).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(1); - - expect(actions[0]).toEqual({ - payload: { - author: '', - collection: undefined, - data: { title: 'title', boolean: true }, - meta: {}, - i18n: {}, - isModification: null, - label: null, - mediaFiles: [], - partial: false, - path: '', - raw: '', - slug: '', - status: '', - updatedOn: '', - }, - type: 'DRAFT_CREATE_EMPTY', - }); - }); - }); - - it('should html escape URL params', () => { - const store = mockStore({ mediaLibrary: fromJS({ files: [] }) }); - - const collection = fromJS({ - fields: [{ name: 'title' }], - }); - - return store - .dispatch(createEmptyDraft(collection, "?title=")) - .then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(1); - - expect(actions[0]).toEqual({ - payload: { - author: '', - collection: undefined, - data: { title: '<script>alert('hello')</script>' }, - meta: {}, - i18n: {}, - isModification: null, - label: null, - mediaFiles: [], - partial: false, - path: '', - raw: '', - slug: '', - status: '', - updatedOn: '', - }, - type: 'DRAFT_CREATE_EMPTY', - }); - }); - }); - }); - describe('createEmptyDraftData', () => { - it('should allow an empty array as list default for a single field list', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - default: [], - field: { name: 'url', widget: 'text' }, - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ images: fromJS([]) }); - }); - - it('should allow a complex array as list default for a single field list', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - default: [ - { - url: 'https://image.png', - }, - ], - field: { name: 'url', widget: 'text' }, - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ - images: fromJS([ - { - url: 'https://image.png', - }, - ]), - }); - }); - - it('should allow an empty array as list default for a fields list', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - default: [], - fields: [ - { name: 'title', widget: 'text' }, - { name: 'url', widget: 'text' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ images: fromJS([]) }); - }); - - it('should allow a complex array as list default for a fields list', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - default: [ - { - title: 'default image', - url: 'https://image.png', - }, - ], - fields: [ - { name: 'title', widget: 'text' }, - { name: 'url', widget: 'text' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ - images: fromJS([ - { - title: 'default image', - url: 'https://image.png', - }, - ]), - }); - }); - - it('should use field default when no list default is provided', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - field: { name: 'url', widget: 'text', default: 'https://image.png' }, - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ images: [{ url: 'https://image.png' }] }); - }); - - it('should use fields default when no list default is provided', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - fields: [ - { name: 'title', widget: 'text', default: 'default image' }, - { name: 'url', widget: 'text', default: 'https://image.png' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ - images: [{ title: 'default image', url: 'https://image.png' }], - }); - }); - - it('should not set empty value for list fields widget', () => { - const fields = fromJS([ - { - name: 'images', - widget: 'list', - fields: [ - { name: 'title', widget: 'text' }, - { name: 'url', widget: 'text' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({}); - }); - - it('should set default value for object field widget', () => { - const fields = fromJS([ - { - name: 'post', - widget: 'object', - field: { name: 'image', widget: 'text', default: 'https://image.png' }, - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ post: { image: 'https://image.png' } }); - }); - - it('should set default values for object fields widget', () => { - const fields = fromJS([ - { - name: 'post', - widget: 'object', - fields: [ - { name: 'title', widget: 'text', default: 'default title' }, - { name: 'url', widget: 'text', default: 'https://image.png' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ - post: { title: 'default title', url: 'https://image.png' }, - }); - }); - - it('should not set empty value for object fields widget', () => { - const fields = fromJS([ - { - name: 'post', - widget: 'object', - fields: [ - { name: 'title', widget: 'text' }, - { name: 'url', widget: 'text' }, - ], - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({}); - }); - - it('should populate nested fields', () => { - const fields = fromJS([ - { - name: 'names', - widget: 'list', - field: { - name: 'object', - widget: 'object', - fields: [ - { name: 'first', widget: 'string', default: 'first' }, - { name: 'second', widget: 'string', default: 'second' }, - ], - }, - }, - ]); - expect(createEmptyDraftData(fields)).toEqual({ - names: [{ object: { first: 'first', second: 'second' } }], - }); - }); - }); - - describe('persistLocalBackup', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should persist local backup with media files', () => { - const { currentBackend } = require('../../backend'); - - const backend = { - persistLocalDraftBackup: jest.fn(() => Promise.resolve()), - }; - - const store = mockStore({ - config: Map(), - }); - - currentBackend.mockReturnValue(backend); - - const collection = Map(); - const mediaFiles = [{ path: 'static/media/image.png' }]; - const entry = fromJS({ mediaFiles }); - - return store.dispatch(persistLocalBackup(entry, collection)).then(() => { - const actions = store.getActions(); - expect(actions).toHaveLength(0); - - expect(backend.persistLocalDraftBackup).toHaveBeenCalledTimes(1); - expect(backend.persistLocalDraftBackup).toHaveBeenCalledWith(entry, collection); - }); - }); - }); - - describe('retrieveLocalBackup', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should retrieve media files with local backup', () => { - const { currentBackend } = require('../../backend'); - const { createAssetProxy } = require('../../valueObjects/AssetProxy'); - - const backend = { - getLocalDraftBackup: jest.fn((...args) => args), - }; - - const store = mockStore({ - config: Map(), - }); - - currentBackend.mockReturnValue(backend); - - const collection = Map({ - name: 'collection', - }); - const slug = 'slug'; - - const file = new File([], 'image.png'); - const mediaFiles = [{ path: 'static/media/image.png', url: 'url', file }]; - const asset = createAssetProxy(mediaFiles[0]); - const entry = { mediaFiles }; - - backend.getLocalDraftBackup.mockReturnValue({ entry }); - - return store.dispatch(retrieveLocalBackup(collection, slug)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(2); - - expect(actions[0]).toEqual({ - type: 'ADD_ASSETS', - payload: [asset], - }); - expect(actions[1]).toEqual({ - type: 'DRAFT_LOCAL_BACKUP_RETRIEVED', - payload: { entry }, - }); - }); - }); - }); - - describe('getMediaAssets', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should map mediaFiles to assets', () => { - const mediaFiles = fromJS([{ path: 'path1' }, { path: 'path2', draft: true }]); - - const entry = Map({ mediaFiles }); - expect(getMediaAssets({ entry })).toEqual([new AssetProxy({ path: 'path2' })]); - }); - }); - - describe('validateMetaField', () => { - const state = { - config: { - slug: { - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', - }, - }, - entries: fromJS([]), - }; - const collection = fromJS({ - folder: 'folder', - type: 'folder_based_collection', - name: 'name', - }); - const t = jest.fn((key, args) => ({ key, args })); - - const { selectCustomPath } = require('../../reducers/entryDraft'); - const { selectEntryByPath } = require('../../reducers/entries'); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should not return error on non meta field', () => { - expect(validateMetaField(null, null, fromJS({}), null, t)).toEqual({ error: false }); - }); - - it('should not return error on meta path field', () => { - expect(validateMetaField(null, null, fromJS({ meta: true, name: 'other' }), null, t)).toEqual( - { error: false }, - ); - }); - - it('should return error on empty path', () => { - expect(validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), null, t)).toEqual({ - error: { - message: { - key: 'editor.editorControlPane.widget.invalidPath', - args: { path: null }, - }, - type: 'CUSTOM', - }, - }); - - expect( - validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), undefined, t), - ).toEqual({ - error: { - message: { - key: 'editor.editorControlPane.widget.invalidPath', - args: { path: undefined }, - }, - type: 'CUSTOM', - }, - }); - - expect(validateMetaField(null, null, fromJS({ meta: true, name: 'path' }), '', t)).toEqual({ - error: { - message: { - key: 'editor.editorControlPane.widget.invalidPath', - args: { path: '' }, - }, - type: 'CUSTOM', - }, - }); - }); - - it('should return error on invalid path', () => { - expect( - validateMetaField(state, null, fromJS({ meta: true, name: 'path' }), 'invalid path', t), - ).toEqual({ - error: { - message: { - key: 'editor.editorControlPane.widget.invalidPath', - args: { path: 'invalid path' }, - }, - type: 'CUSTOM', - }, - }); - }); - - it('should return error on existing path', () => { - selectCustomPath.mockReturnValue('existing-path'); - selectEntryByPath.mockReturnValue(fromJS({ path: 'existing-path' })); - expect( - validateMetaField( - { - ...state, - entryDraft: fromJS({ - entry: {}, - }), - }, - collection, - fromJS({ meta: true, name: 'path' }), - 'existing-path', - t, - ), - ).toEqual({ - error: { - message: { - key: 'editor.editorControlPane.widget.pathExists', - args: { path: 'existing-path' }, - }, - type: 'CUSTOM', - }, - }); - - expect(selectCustomPath).toHaveBeenCalledTimes(1); - expect(selectCustomPath).toHaveBeenCalledWith( - collection, - fromJS({ entry: { meta: { path: 'existing-path' } } }), - ); - - expect(selectEntryByPath).toHaveBeenCalledTimes(1); - expect(selectEntryByPath).toHaveBeenCalledWith( - state.entries, - collection.get('name'), - 'existing-path', - ); - }); - - it('should not return error on non existing path for new entry', () => { - selectCustomPath.mockReturnValue('non-existing-path'); - selectEntryByPath.mockReturnValue(undefined); - expect( - validateMetaField( - { - ...state, - entryDraft: fromJS({ - entry: {}, - }), - }, - collection, - fromJS({ meta: true, name: 'path' }), - 'non-existing-path', - t, - ), - ).toEqual({ - error: false, - }); - }); - - it('should not return error when for existing entry', () => { - selectCustomPath.mockReturnValue('existing-path'); - selectEntryByPath.mockReturnValue(fromJS({ path: 'existing-path' })); - expect( - validateMetaField( - { - ...state, - entryDraft: fromJS({ - entry: { path: 'existing-path' }, - }), - }, - collection, - fromJS({ meta: true, name: 'path' }), - 'existing-path', - t, - ), - ).toEqual({ - error: false, - }); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/media.spec.ts b/packages/netlify-cms-core/src/actions/__tests__/media.spec.ts deleted file mode 100644 index 726bf3f0..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/media.spec.ts +++ /dev/null @@ -1,171 +0,0 @@ -import { Map } from 'immutable'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import { mocked } from 'ts-jest/utils'; - -import { getAsset, ADD_ASSET, LOAD_ASSET_REQUEST } from '../media'; -import { selectMediaFilePath } from '../../reducers/entries'; -import AssetProxy from '../../valueObjects/AssetProxy'; - -import type { State } from '../../types/redux'; -import type { AnyAction } from 'redux'; -import type { ThunkDispatch } from 'redux-thunk'; - -const middlewares = [thunk]; -const mockStore = configureMockStore, ThunkDispatch>( - middlewares, -); -const mockedSelectMediaFilePath = mocked(selectMediaFilePath); - -jest.mock('../../reducers/entries'); -jest.mock('../mediaLibrary'); - -describe('media', () => { - const emptyAsset = new AssetProxy({ - path: 'empty.svg', - file: new File([``], 'empty.svg', { - type: 'image/svg+xml', - }), - }); - - describe('getAsset', () => { - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - global.URL = { createObjectURL: jest.fn() }; - - beforeEach(() => { - jest.resetAllMocks(); - }); - - it('should return empty asset for null path', () => { - const store = mockStore({}); - - const payload = { collection: null, entryPath: null, entry: null, path: null }; - - // TODO change to proper payload when immutable is removed - // from 'collections' and 'entries' state slices - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const result = store.dispatch(getAsset(payload)); - const actions = store.getActions(); - expect(actions).toHaveLength(0); - expect(result).toEqual(emptyAsset); - }); - - it('should return asset from medias state', () => { - const path = 'static/media/image.png'; - const asset = new AssetProxy({ file: new File([], 'empty'), path }); - const store = mockStore({ - // TODO change to proper store data when immutable is removed - // from 'config' state slice - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - config: Map(), - medias: { - [path]: { asset, isLoading: false, error: null }, - }, - }); - - mockedSelectMediaFilePath.mockReturnValue(path); - const payload = { collection: Map(), entry: Map({ path: 'entryPath' }), path }; - - // TODO change to proper payload when immutable is removed - // from 'collections' and 'entries' state slices - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const result = store.dispatch(getAsset(payload)); - const actions = store.getActions(); - expect(actions).toHaveLength(0); - - expect(result).toBe(asset); - expect(mockedSelectMediaFilePath).toHaveBeenCalledTimes(1); - expect(mockedSelectMediaFilePath).toHaveBeenCalledWith( - store.getState().config, - payload.collection, - payload.entry, - path, - undefined, - ); - }); - - it('should create asset for absolute path when not in medias state', () => { - const path = 'https://asset.netlify.com/image.png'; - - const asset = new AssetProxy({ url: path, path }); - const store = mockStore({ - medias: {}, - }); - - mockedSelectMediaFilePath.mockReturnValue(path); - const payload = { collection: null, entryPath: null, path }; - - // TODO change to proper payload when immutable is removed - // from 'collections' state slice - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const result = store.dispatch(getAsset(payload)); - const actions = store.getActions(); - expect(actions).toHaveLength(1); - expect(actions[0]).toEqual({ - type: ADD_ASSET, - payload: asset, - }); - expect(result).toEqual(asset); - }); - - it('should return empty asset and initiate load when not in medias state', () => { - const path = 'static/media/image.png'; - const store = mockStore({ - medias: {}, - }); - - mockedSelectMediaFilePath.mockReturnValue(path); - const payload = { path }; - - // TODO change to proper payload when immutable is removed - // from 'collections' and 'entries' state slices - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const result = store.dispatch(getAsset(payload)); - const actions = store.getActions(); - expect(actions).toHaveLength(1); - expect(actions[0]).toEqual({ - type: LOAD_ASSET_REQUEST, - payload: { path }, - }); - expect(result).toEqual(emptyAsset); - }); - - it('should return asset with original path on load error', () => { - const path = 'static/media/image.png'; - const resolvePath = 'resolvePath'; - const store = mockStore({ - medias: { - [resolvePath]: { - asset: undefined, - error: new Error('test'), - isLoading: false, - }, - }, - }); - - mockedSelectMediaFilePath.mockReturnValue(resolvePath); - const payload = { path }; - - // TODO change to proper payload when immutable is removed - // from 'collections' and 'entries' state slices - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const result = store.dispatch(getAsset(payload)); - const actions = store.getActions(); - - const asset = new AssetProxy({ url: path, path: resolvePath }); - expect(actions).toHaveLength(1); - expect(actions[0]).toEqual({ - type: ADD_ASSET, - payload: asset, - }); - expect(result).toEqual(asset); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/mediaLibrary.spec.js b/packages/netlify-cms-core/src/actions/__tests__/mediaLibrary.spec.js deleted file mode 100644 index 4106368c..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/mediaLibrary.spec.js +++ /dev/null @@ -1,327 +0,0 @@ -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; -import { List, Map } from 'immutable'; - -import { insertMedia, persistMedia, deleteMedia } from '../mediaLibrary'; - -jest.mock('../../backend'); -jest.mock('../waitUntil'); -jest.mock('netlify-cms-lib-util', () => { - const lib = jest.requireActual('netlify-cms-lib-util'); - return { - ...lib, - getBlobSHA: jest.fn(), - }; -}); - -const middlewares = [thunk]; -const mockStore = configureMockStore(middlewares); - -describe('mediaLibrary', () => { - describe('insertMedia', () => { - it('should return mediaPath as string when string is given', () => { - const store = mockStore({ - config: { - public_folder: '/media', - }, - collections: Map({ - posts: Map({ name: 'posts' }), - }), - entryDraft: Map({ - entry: Map({ isPersisting: false, collection: 'posts' }), - }), - }); - - store.dispatch(insertMedia('foo.png')); - expect(store.getActions()[0]).toEqual({ - type: 'MEDIA_INSERT', - payload: { mediaPath: '/media/foo.png' }, - }); - }); - - it('should return mediaPath as array of strings when array of strings is given', () => { - const store = mockStore({ - config: { - public_folder: '/media', - }, - collections: Map({ - posts: Map({ name: 'posts' }), - }), - entryDraft: Map({ - entry: Map({ isPersisting: false, collection: 'posts' }), - }), - }); - - store.dispatch(insertMedia(['foo.png'])); - expect(store.getActions()[0]).toEqual({ - type: 'MEDIA_INSERT', - payload: { mediaPath: ['/media/foo.png'] }, - }); - }); - }); - - const { currentBackend } = require('../../backend'); - - const backend = { - persistMedia: jest.fn(() => ({ id: 'id' })), - deleteMedia: jest.fn(), - }; - - currentBackend.mockReturnValue(backend); - - describe('persistMedia', () => { - global.URL = { createObjectURL: jest.fn().mockReturnValue('displayURL') }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should not persist media when editing draft', () => { - const { getBlobSHA } = require('netlify-cms-lib-util'); - - getBlobSHA.mockReturnValue('000000000000000'); - - const store = mockStore({ - config: { - media_folder: 'static/media', - slug: { - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', - }, - }, - collections: Map({ - posts: Map({ name: 'posts' }), - }), - integrations: Map(), - mediaLibrary: Map({ - files: List(), - }), - entryDraft: Map({ - entry: Map({ isPersisting: false, collection: 'posts' }), - }), - }); - - const file = new File([''], 'name.png'); - - return store.dispatch(persistMedia(file)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(2); - expect(actions[0].type).toEqual('ADD_ASSET'); - expect(actions[0].payload).toEqual( - expect.objectContaining({ - path: 'static/media/name.png', - }), - ); - expect(actions[1].type).toEqual('ADD_DRAFT_ENTRY_MEDIA_FILE'); - expect(actions[1].payload).toEqual( - expect.objectContaining({ - draft: true, - id: '000000000000000', - path: 'static/media/name.png', - size: file.size, - name: file.name, - }), - ); - - expect(getBlobSHA).toHaveBeenCalledTimes(1); - expect(getBlobSHA).toHaveBeenCalledWith(file); - expect(backend.persistMedia).toHaveBeenCalledTimes(0); - }); - }); - - it('should persist media when not editing draft', () => { - const store = mockStore({ - config: { - media_folder: 'static/media', - slug: { - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', - }, - }, - collections: Map({ - posts: Map({ name: 'posts' }), - }), - integrations: Map(), - mediaLibrary: Map({ - files: List(), - }), - entryDraft: Map({ - entry: Map(), - }), - }); - - const file = new File([''], 'name.png'); - - return store.dispatch(persistMedia(file)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(3); - - expect(actions).toHaveLength(3); - expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' }); - expect(actions[1].type).toEqual('ADD_ASSET'); - expect(actions[1].payload).toEqual( - expect.objectContaining({ - path: 'static/media/name.png', - }), - ); - expect(actions[2]).toEqual({ - type: 'MEDIA_PERSIST_SUCCESS', - payload: { - file: { id: 'id' }, - }, - }); - - expect(backend.persistMedia).toHaveBeenCalledTimes(1); - expect(backend.persistMedia).toHaveBeenCalledWith( - store.getState().config, - expect.objectContaining({ - path: 'static/media/name.png', - }), - ); - }); - }); - - it('should sanitize media name if needed when persisting', () => { - const store = mockStore({ - config: { - media_folder: 'static/media', - slug: { - encoding: 'ascii', - clean_accents: true, - sanitize_replacement: '_', - }, - }, - collections: Map({ - posts: Map({ name: 'posts' }), - }), - integrations: Map(), - mediaLibrary: Map({ - files: List(), - }), - entryDraft: Map({ - entry: Map(), - }), - }); - - const file = new File([''], 'abc DEF éâçÖ $;, .png'); - - return store.dispatch(persistMedia(file)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(3); - - expect(actions[0]).toEqual({ type: 'MEDIA_PERSIST_REQUEST' }); - - expect(actions[1].type).toEqual('ADD_ASSET'); - expect(actions[1].payload).toEqual( - expect.objectContaining({ - path: 'static/media/abc_def_eaco_.png', - }), - ); - - expect(actions[2]).toEqual({ - type: 'MEDIA_PERSIST_SUCCESS', - payload: { - file: { id: 'id' }, - }, - }); - - expect(backend.persistMedia).toHaveBeenCalledTimes(1); - expect(backend.persistMedia).toHaveBeenCalledWith( - store.getState().config, - expect.objectContaining({ - path: 'static/media/abc_def_eaco_.png', - }), - ); - }); - }); - }); - - describe('deleteMedia', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should delete non draft file', () => { - const store = mockStore({ - config: { - publish_mode: 'editorial_workflow', - }, - collections: Map(), - integrations: Map(), - mediaLibrary: Map({ - files: List(), - }), - entryDraft: Map({ - entry: Map({ isPersisting: false }), - }), - }); - - const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: false }; - - return store.dispatch(deleteMedia(file)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(4); - expect(actions[0]).toEqual({ type: 'MEDIA_DELETE_REQUEST' }); - expect(actions[1]).toEqual({ - type: 'REMOVE_ASSET', - payload: 'static/media/name.png', - }); - expect(actions[2]).toEqual({ - type: 'MEDIA_DELETE_SUCCESS', - payload: { file }, - }); - expect(actions[3]).toEqual({ - type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE', - payload: { id: 'id' }, - }); - - expect(backend.deleteMedia).toHaveBeenCalledTimes(1); - expect(backend.deleteMedia).toHaveBeenCalledWith( - store.getState().config, - 'static/media/name.png', - ); - }); - }); - - it('should not delete a draft file', () => { - const store = mockStore({ - config: { - publish_mode: 'editorial_workflow', - }, - collections: Map(), - integrations: Map(), - mediaLibrary: Map({ - files: List(), - }), - entryDraft: Map({ - entry: Map({ isPersisting: false }), - }), - }); - - const file = { name: 'name.png', id: 'id', path: 'static/media/name.png', draft: true }; - - return store.dispatch(deleteMedia(file)).then(() => { - const actions = store.getActions(); - - expect(actions).toHaveLength(2); - expect(actions[0]).toEqual({ - type: 'REMOVE_ASSET', - payload: 'static/media/name.png', - }); - - expect(actions[1]).toEqual({ - type: 'REMOVE_DRAFT_ENTRY_MEDIA_FILE', - payload: { id: 'id' }, - }); - - expect(backend.deleteMedia).toHaveBeenCalledTimes(0); - }); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/__tests__/search.spec.js b/packages/netlify-cms-core/src/actions/__tests__/search.spec.js deleted file mode 100644 index 6fa0989f..00000000 --- a/packages/netlify-cms-core/src/actions/__tests__/search.spec.js +++ /dev/null @@ -1,209 +0,0 @@ -import { fromJS } from 'immutable'; -import configureMockStore from 'redux-mock-store'; -import thunk from 'redux-thunk'; - -import { searchEntries } from '../search'; - -const middlewares = [thunk]; -const mockStore = configureMockStore(middlewares); - -jest.mock('../../reducers'); -jest.mock('../../backend'); -jest.mock('../../integrations'); - -describe('search', () => { - describe('searchEntries', () => { - const { currentBackend } = require('../../backend'); - const { selectIntegration } = require('../../reducers'); - const { getIntegrationProvider } = require('../../integrations'); - - beforeEach(() => { - jest.resetAllMocks(); - }); - it('should search entries in all collections using integration', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: {}, - }); - - selectIntegration.mockReturnValue('search_integration'); - currentBackend.mockReturnValue({}); - const response = { entries: [{ name: '1' }, { name: '' }], pagination: 1 }; - const integration = { search: jest.fn().mockResolvedValue(response) }; - getIntegrationProvider.mockReturnValue(integration); - - await store.dispatch(searchEntries('find me')); - const actions = store.getActions(); - expect(actions).toHaveLength(2); - - expect(actions[0]).toEqual({ - type: 'SEARCH_ENTRIES_REQUEST', - payload: { - searchTerm: 'find me', - searchCollections: ['posts', 'pages'], - page: 0, - }, - }); - expect(actions[1]).toEqual({ - type: 'SEARCH_ENTRIES_SUCCESS', - payload: { - entries: response.entries, - page: response.pagination, - }, - }); - - expect(integration.search).toHaveBeenCalledTimes(1); - expect(integration.search).toHaveBeenCalledWith(['posts', 'pages'], 'find me', 0); - }); - - it('should search entries in a subset of collections using integration', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: {}, - }); - - selectIntegration.mockReturnValue('search_integration'); - currentBackend.mockReturnValue({}); - const response = { entries: [{ name: '1' }, { name: '' }], pagination: 1 }; - const integration = { search: jest.fn().mockResolvedValue(response) }; - getIntegrationProvider.mockReturnValue(integration); - - await store.dispatch(searchEntries('find me', ['pages'])); - const actions = store.getActions(); - expect(actions).toHaveLength(2); - - expect(actions[0]).toEqual({ - type: 'SEARCH_ENTRIES_REQUEST', - payload: { - searchTerm: 'find me', - searchCollections: ['pages'], - page: 0, - }, - }); - expect(actions[1]).toEqual({ - type: 'SEARCH_ENTRIES_SUCCESS', - payload: { - entries: response.entries, - page: response.pagination, - }, - }); - - expect(integration.search).toHaveBeenCalledTimes(1); - expect(integration.search).toHaveBeenCalledWith(['pages'], 'find me', 0); - }); - - it('should search entries in all collections using backend', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: {}, - }); - - const response = { entries: [{ name: '1' }, { name: '' }], pagination: 1 }; - const backend = { search: jest.fn().mockResolvedValue(response) }; - currentBackend.mockReturnValue(backend); - - await store.dispatch(searchEntries('find me')); - - const actions = store.getActions(); - expect(actions).toHaveLength(2); - - expect(actions[0]).toEqual({ - type: 'SEARCH_ENTRIES_REQUEST', - payload: { - searchTerm: 'find me', - searchCollections: ['posts', 'pages'], - page: 0, - }, - }); - expect(actions[1]).toEqual({ - type: 'SEARCH_ENTRIES_SUCCESS', - payload: { - entries: response.entries, - page: response.pagination, - }, - }); - - expect(backend.search).toHaveBeenCalledTimes(1); - expect(backend.search).toHaveBeenCalledWith( - [fromJS({ name: 'posts' }), fromJS({ name: 'pages' })], - 'find me', - ); - }); - - it('should search entries in a subset of collections using backend', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: {}, - }); - - const response = { entries: [{ name: '1' }, { name: '' }], pagination: 1 }; - const backend = { search: jest.fn().mockResolvedValue(response) }; - currentBackend.mockReturnValue(backend); - - await store.dispatch(searchEntries('find me', ['pages'])); - - const actions = store.getActions(); - expect(actions).toHaveLength(2); - - expect(actions[0]).toEqual({ - type: 'SEARCH_ENTRIES_REQUEST', - payload: { - searchTerm: 'find me', - searchCollections: ['pages'], - page: 0, - }, - }); - expect(actions[1]).toEqual({ - type: 'SEARCH_ENTRIES_SUCCESS', - payload: { - entries: response.entries, - page: response.pagination, - }, - }); - - expect(backend.search).toHaveBeenCalledTimes(1); - expect(backend.search).toHaveBeenCalledWith([fromJS({ name: 'pages' })], 'find me'); - }); - - it('should ignore identical search in all collections', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: { isFetching: true, term: 'find me', collections: ['posts', 'pages'] }, - }); - - await store.dispatch(searchEntries('find me')); - - const actions = store.getActions(); - expect(actions).toHaveLength(0); - }); - - it('should ignore identical search in a subset of collections', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: { isFetching: true, term: 'find me', collections: ['pages'] }, - }); - - await store.dispatch(searchEntries('find me', ['pages'])); - - const actions = store.getActions(); - expect(actions).toHaveLength(0); - }); - - it('should not ignore same search term in different search collections', async () => { - const store = mockStore({ - collections: fromJS({ posts: { name: 'posts' }, pages: { name: 'pages' } }), - search: { isFetching: true, term: 'find me', collections: ['pages'] }, - }); - const backend = { search: jest.fn().mockResolvedValue({}) }; - currentBackend.mockReturnValue(backend); - - await store.dispatch(searchEntries('find me', ['posts', 'pages'])); - - expect(backend.search).toHaveBeenCalledTimes(1); - expect(backend.search).toHaveBeenCalledWith( - [fromJS({ name: 'posts' }), fromJS({ name: 'pages' })], - 'find me', - ); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/actions/auth.ts b/packages/netlify-cms-core/src/actions/auth.ts index 506fcd2c..dc711452 100644 --- a/packages/netlify-cms-core/src/actions/auth.ts +++ b/packages/netlify-cms-core/src/actions/auth.ts @@ -1,13 +1,11 @@ -import { actions as notifActions } from 'redux-notifications'; - import { currentBackend } from '../backend'; +import { addSnackbar } from '../store/slices/snackbars'; -import type { Credentials, User } from 'netlify-cms-lib-util'; +import type { Credentials, User } from '../lib/util'; import type { ThunkDispatch } from 'redux-thunk'; import type { AnyAction } from 'redux'; import type { State } from '../types/redux'; - -const { notifSend, notifClear } = notifActions; +import type { t } from 'react-polyglot'; export const AUTH_REQUEST = 'AUTH_REQUEST'; export const AUTH_SUCCESS = 'AUTH_SUCCESS'; @@ -96,13 +94,12 @@ export function loginUser(credentials: Credentials) { .catch((error: Error) => { console.error(error); dispatch( - notifSend({ + addSnackbar({ + type: 'warning', message: { - details: error.message, key: 'ui.toast.onFailToAuth', + message: error.message, }, - kind: 'warning', - dismissAfter: 8000, }), ); dispatch(authError(error)); @@ -116,7 +113,6 @@ export function logoutUser() { const backend = currentBackend(state.config); Promise.resolve(backend.logout()).then(() => { dispatch(logout()); - dispatch(notifClear()); }); }; } diff --git a/packages/netlify-cms-core/src/actions/config.ts b/packages/netlify-cms-core/src/actions/config.ts index 3bb3a1cb..9b96defb 100644 --- a/packages/netlify-cms-core/src/actions/config.ts +++ b/packages/netlify-cms-core/src/actions/config.ts @@ -14,8 +14,8 @@ import { FILES, FOLDER } from '../constants/collectionTypes'; import type { ThunkDispatch } from 'redux-thunk'; import type { AnyAction } from 'redux'; -import type { - CmsCollection, +import type { State } from '../types/redux'; +import { CmsConfig, CmsField, CmsFieldBase, @@ -24,8 +24,8 @@ import type { CmsI18nConfig, CmsPublishMode, CmsLocalBackend, - State, -} from '../types/redux'; + CmsCollection, +} from '../interface'; export const CONFIG_REQUEST = 'CONFIG_REQUEST'; export const CONFIG_SUCCESS = 'CONFIG_SUCCESS'; @@ -64,7 +64,7 @@ function getConfigUrl() { }; const configLinkEl = document.querySelector('link[rel="cms-config-url"]'); if (configLinkEl && validTypes[configLinkEl.type] && configLinkEl.href) { - console.log(`Using config file path: "${configLinkEl.href}"`); + console.info(`Using config file path: "${configLinkEl.href}"`); return configLinkEl.href; } return 'config.yml'; @@ -100,7 +100,7 @@ function setSnakeCaseConfig(field: T) { console.warn( `Field ${field.name} is using a deprecated configuration '${camel}'. Please use '${snake}'`, ); - return { [snake]: (field as Record)[camel] }; + return { [snake]: (field as unknown as Record)[camel] }; }); return Object.assign({}, field, ...snakeValues) as T; @@ -189,15 +189,6 @@ export function normalizeConfig(config: CmsConfig) { normalizedCollection = { ...normalizedCollection, files: normalizedFiles }; } - if (normalizedCollection.sortableFields) { - const { sortableFields, ...rest } = normalizedCollection; - normalizedCollection = { ...rest, sortable_fields: sortableFields }; - - console.warn( - `Collection ${collection.name} is using a deprecated configuration 'sortableFields'. Please use 'sortable_fields'`, - ); - } - return normalizedCollection; }); @@ -332,12 +323,14 @@ export function applyDefaults(originalConfig: CmsConfig) { } if (!collection.sortable_fields) { - collection.sortable_fields = selectDefaultSortableFields( - // TODO remove fromJS when Immutable is removed from the collections state slice - fromJS(collection), - backend, - hasIntegration(config, collection), - ); + collection.sortable_fields = { + fields: selectDefaultSortableFields( + // TODO remove fromJS when Immutable is removed from the collections state slice + fromJS(collection), + backend, + hasIntegration(config, collection), + ), + }; } collection.view_filters = (view_filters || []).map(filter => { @@ -388,7 +381,7 @@ async function getConfigYaml(file: string, hasManualConfig: boolean) { const contentType = response.headers.get('Content-Type') || 'Not-Found'; const isYaml = contentType.indexOf('yaml') !== -1; if (!isYaml) { - console.log(`Response for ${file} was not yaml. (Content-Type: ${contentType})`); + console.info(`Response for ${file} was not yaml. (Content-Type: ${contentType})`); if (hasManualConfig) { return {}; } @@ -435,7 +428,7 @@ export async function detectProxyServer(localBackend?: boolean | CmsLocalBackend : localBackend.url || defaultUrl.replace('localhost', location.hostname); try { - console.log(`Looking for Netlify CMS Proxy Server at '${proxyUrl}'`); + console.info(`Looking for Netlify CMS Proxy Server at '${proxyUrl}'`); const res = await fetch(`${proxyUrl}`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -447,14 +440,14 @@ export async function detectProxyServer(localBackend?: boolean | CmsLocalBackend type?: string; }; if (typeof repo === 'string' && Array.isArray(publish_modes) && typeof type === 'string') { - console.log(`Detected Netlify CMS Proxy Server at '${proxyUrl}' with repo: '${repo}'`); + console.info(`Detected Netlify CMS Proxy Server at '${proxyUrl}' with repo: '${repo}'`); return { proxyUrl, publish_modes, type }; } else { - console.log(`Netlify CMS Proxy Server not detected at '${proxyUrl}'`); + console.info(`Netlify CMS Proxy Server not detected at '${proxyUrl}'`); return {}; } } catch { - console.log(`Netlify CMS Proxy Server not detected at '${proxyUrl}'`); + console.info(`Netlify CMS Proxy Server not detected at '${proxyUrl}'`); return {}; } } @@ -462,7 +455,7 @@ export async function detectProxyServer(localBackend?: boolean | CmsLocalBackend function getPublishMode(config: CmsConfig, publishModes?: CmsPublishMode[], backendType?: string) { if (config.publish_mode && publishModes && !publishModes.includes(config.publish_mode)) { const newPublishMode = publishModes[0]; - console.log( + console.info( `'${config.publish_mode}' is not supported by '${backendType}' backend, switching to '${newPublishMode}'`, ); return newPublishMode; @@ -526,7 +519,7 @@ export function loadConfig(manualConfig: Partial = {}, onLoad: () => if (typeof onLoad === 'function') { onLoad(); } - } catch (err) { + } catch (err: any) { dispatch(configFailed(err)); throw err; } diff --git a/packages/netlify-cms-core/src/actions/deploys.ts b/packages/netlify-cms-core/src/actions/deploys.ts index b14ee35f..c32459ac 100644 --- a/packages/netlify-cms-core/src/actions/deploys.ts +++ b/packages/netlify-cms-core/src/actions/deploys.ts @@ -1,14 +1,12 @@ -import { actions as notifActions } from 'redux-notifications'; - import { currentBackend } from '../backend'; import { selectDeployPreview } from '../reducers'; +import { addSnackbar } from '../store/slices/snackbars'; -import type { ThunkDispatch } from 'redux-thunk'; +import type { t } from 'react-polyglot'; import type { AnyAction } from 'redux'; +import type { ThunkDispatch } from 'redux-thunk'; import type { Collection, Entry, State } from '../types/redux'; -const { notifSend } = notifActions; - export const DEPLOY_PREVIEW_REQUEST = 'DEPLOY_PREVIEW_REQUEST'; export const DEPLOY_PREVIEW_SUCCESS = 'DEPLOY_PREVIEW_SUCCESS'; export const DEPLOY_PREVIEW_FAILURE = 'DEPLOY_PREVIEW_FAILURE'; @@ -85,16 +83,12 @@ export function loadDeployPreview( return dispatch(deployPreviewLoaded(collectionName, slug, deploy)); } return dispatch(deployPreviewError(collectionName, slug)); - } catch (error) { + } catch (error: any) { console.error(error); dispatch( - notifSend({ - message: { - details: error.message, - key: 'ui.toast.onFailToLoadDeployPreview', - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onFailToLoadDeployPreview', details: error.message }, }), ); dispatch(deployPreviewError(collectionName, slug)); diff --git a/packages/netlify-cms-core/src/actions/editorialWorkflow.ts b/packages/netlify-cms-core/src/actions/editorialWorkflow.ts index 52d9a8dd..ca6d6696 100644 --- a/packages/netlify-cms-core/src/actions/editorialWorkflow.ts +++ b/packages/netlify-cms-core/src/actions/editorialWorkflow.ts @@ -1,45 +1,43 @@ +import { List, Map } from 'immutable'; import { get } from 'lodash'; -import { actions as notifActions } from 'redux-notifications'; -import { Map, List } from 'immutable'; -import { EDITORIAL_WORKFLOW_ERROR } from 'netlify-cms-lib-util'; import { currentBackend, slugFromCustomPath } from '../backend'; +import { EDITORIAL_WORKFLOW, status } from '../constants/publishModes'; +import ValidationErrorTypes from '../constants/validationErrorTypes'; +import { EDITORIAL_WORKFLOW_ERROR } from '../lib/util'; import { - selectPublishedSlugs, - selectUnpublishedSlugs, selectEntry, + selectPublishedSlugs, selectUnpublishedEntry, + selectUnpublishedSlugs, } from '../reducers'; import { selectEditingDraft } from '../reducers/entries'; -import { EDITORIAL_WORKFLOW, status } from '../constants/publishModes'; +import { navigateToEntry } from '../routing/history'; +import { addSnackbar } from '../store/slices/snackbars'; +import { createAssetProxy } from '../valueObjects/AssetProxy'; import { - loadEntry, + createDraftFromEntry, entryDeleted, getMediaAssets, - createDraftFromEntry, - loadEntries, getSerializedEntry, + loadEntries, + loadEntry, } from './entries'; -import { createAssetProxy } from '../valueObjects/AssetProxy'; import { addAssets } from './media'; import { loadMedia } from './mediaLibrary'; -import ValidationErrorTypes from '../constants/validationErrorTypes'; -import { navigateToEntry } from '../routing/history'; +import type { AnyAction } from 'redux'; +import type { ThunkDispatch } from 'redux-thunk'; +import type { Status } from '../constants/publishModes'; import type { Collection, - EntryMap, - State, Collections, EntryDraft, + EntryMap, MediaFile, + State, } from '../types/redux'; -import type { AnyAction } from 'redux'; import type { EntryValue } from '../valueObjects/Entry'; -import type { Status } from '../constants/publishModes'; -import type { ThunkDispatch } from 'redux-thunk'; - -const { notifSend } = notifActions; /* * Constant Declarations @@ -271,19 +269,15 @@ export function loadUnpublishedEntry(collection: Collection, slug: string) { dispatch(addAssets(assetProxies)); dispatch(unpublishedEntryLoaded(collection, entry)); dispatch(createDraftFromEntry(entry)); - } catch (error) { + } catch (error: any) { if (error.name === EDITORIAL_WORKFLOW_ERROR && error.notUnderEditorialWorkflow) { dispatch(unpublishedEntryRedirected(collection, slug)); dispatch(loadEntry(collection, slug)); } else { dispatch( - notifSend({ - message: { - key: 'ui.toast.onFailToLoadEntries', - details: error, - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onFailToLoadEntries', details: error }, }), ); } @@ -307,13 +301,9 @@ export function loadUnpublishedEntries(collections: Collections) { .then(response => dispatch(unpublishedEntriesLoaded(response.entries, response.pagination))) .catch((error: Error) => { dispatch( - notifSend({ - message: { - key: 'ui.toast.onFailToLoadEntries', - details: error, - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onFailToLoadEntries', details: error }, }), ); dispatch(unpublishedEntriesFailed(error)); @@ -343,12 +333,9 @@ export function persistUnpublishedEntry(collection: Collection, existingUnpublis if (hasPresenceErrors) { dispatch( - notifSend({ - message: { - key: 'ui.toast.missingRequiredField', - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.missingRequiredField' }, }), ); } @@ -378,12 +365,9 @@ export function persistUnpublishedEntry(collection: Collection, existingUnpublis usedSlugs, }); dispatch( - notifSend({ - message: { - key: 'ui.toast.entrySaved', - }, - kind: 'success', - dismissAfter: 4000, + addSnackbar({ + type: 'success', + message: { key: 'ui.toast.entrySaved' }, }), ); dispatch(unpublishedEntryPersisted(collection, serializedEntry)); @@ -392,15 +376,11 @@ export function persistUnpublishedEntry(collection: Collection, existingUnpublis dispatch(loadUnpublishedEntry(collection, newSlug)); navigateToEntry(collection.get('name'), newSlug); } - } catch (error) { + } catch (error: any) { dispatch( - notifSend({ - message: { - key: 'ui.toast.onFailToPersist', - details: error, - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onFailToPersist', details: error }, }), ); return Promise.reject( @@ -425,25 +405,18 @@ export function updateUnpublishedEntryStatus( .updateUnpublishedEntryStatus(collection, slug, newStatus) .then(() => { dispatch( - notifSend({ - message: { - key: 'ui.toast.entryUpdated', - }, - kind: 'success', - dismissAfter: 4000, + addSnackbar({ + type: 'success', + message: { key: 'ui.toast.entryUpdated' }, }), ); dispatch(unpublishedEntryStatusChangePersisted(collection, slug, newStatus)); }) .catch((error: Error) => { dispatch( - notifSend({ - message: { - key: 'ui.toast.onFailToUpdateStatus', - details: error, - }, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onFailToUpdateStatus', details: error }, }), ); dispatch(unpublishedEntryStatusChangeError(collection, slug)); @@ -460,20 +433,18 @@ export function deleteUnpublishedEntry(collection: string, slug: string) { .deleteUnpublishedEntry(collection, slug) .then(() => { dispatch( - notifSend({ + addSnackbar({ + type: 'success', message: { key: 'ui.toast.onDeleteUnpublishedChanges' }, - kind: 'success', - dismissAfter: 4000, }), ); dispatch(unpublishedEntryDeleted(collection, slug)); }) .catch((error: Error) => { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { key: 'ui.toast.onDeleteUnpublishedChanges', details: error }, - kind: 'danger', - dismissAfter: 8000, }), ); dispatch(unpublishedEntryDeleteError(collection, slug)); @@ -493,10 +464,9 @@ export function publishUnpublishedEntry(collectionName: string, slug: string) { // re-load media after entry was published dispatch(loadMedia()); dispatch( - notifSend({ + addSnackbar({ + type: 'success', message: { key: 'ui.toast.entryPublished' }, - kind: 'success', - dismissAfter: 4000, }), ); dispatch(unpublishedEntryPublished(collectionName, slug)); @@ -513,10 +483,9 @@ export function publishUnpublishedEntry(collectionName: string, slug: string) { } } catch (error) { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { key: 'ui.toast.onFailToPublishEntry', details: error }, - kind: 'danger', - dismissAfter: 8000, }), ); dispatch(unpublishedEntryPublishError(collectionName, slug)); @@ -548,19 +517,17 @@ export function unpublishPublishedEntry(collection: Collection, slug: string) { dispatch(entryDeleted(collection, slug)); dispatch(loadUnpublishedEntry(collection, slug)); dispatch( - notifSend({ + addSnackbar({ + type: 'success', message: { key: 'ui.toast.entryUnpublished' }, - kind: 'success', - dismissAfter: 4000, }), ); }) .catch((error: Error) => { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { key: 'ui.toast.onFailToUnpublishEntry', details: error }, - kind: 'danger', - dismissAfter: 8000, }), ); dispatch(unpublishedEntryPersistedFail(error, collection, entry.get('slug'))); diff --git a/packages/netlify-cms-core/src/actions/entries.ts b/packages/netlify-cms-core/src/actions/entries.ts index 83ce9285..01a2c99a 100644 --- a/packages/netlify-cms-core/src/actions/entries.ts +++ b/packages/netlify-cms-core/src/actions/entries.ts @@ -1,46 +1,36 @@ import { fromJS, List, Map } from 'immutable'; import { isEqual } from 'lodash'; -import { actions as notifActions } from 'redux-notifications'; -import { Cursor } from 'netlify-cms-lib-util'; -import { selectCollectionEntriesCursor } from '../reducers/cursors'; -import { selectFields, updateFieldByKey } from '../reducers/collections'; -import { selectIntegration, selectPublishedSlugs } from '../reducers'; -import { getIntegrationProvider } from '../integrations'; import { currentBackend } from '../backend'; -import { serializeValues } from '../lib/serializeEntryValues'; -import { createEntry } from '../valueObjects/Entry'; -import { createAssetProxy } from '../valueObjects/AssetProxy'; import ValidationErrorTypes from '../constants/validationErrorTypes'; -import { addAssets, getAsset } from './media'; -import { SortDirection } from '../types/redux'; -import { waitForMediaLibraryToLoad, loadMedia } from './mediaLibrary'; -import { waitUntil } from './waitUntil'; -import { selectIsFetching, selectEntriesSortFields, selectEntryByPath } from '../reducers/entries'; +import { getIntegrationProvider } from '../integrations'; +import { SortDirection } from '../interface'; +import { getProcessSegment } from '../lib/formatters'; +import { duplicateDefaultI18nFields, hasI18n, I18N, I18N_FIELD, serializeI18n } from '../lib/i18n'; +import { serializeValues } from '../lib/serializeEntryValues'; +import { Cursor } from '../lib/util'; +import { selectIntegration, selectPublishedSlugs } from '../reducers'; +import { selectFields, updateFieldByKey } from '../reducers/collections'; +import { selectCollectionEntriesCursor } from '../reducers/cursors'; +import { selectEntriesSortFields, selectEntryByPath, selectIsFetching } from '../reducers/entries'; import { selectCustomPath } from '../reducers/entryDraft'; import { navigateToEntry } from '../routing/history'; -import { getProcessSegment } from '../lib/formatters'; -import { hasI18n, duplicateDefaultI18nFields, serializeI18n, I18N, I18N_FIELD } from '../lib/i18n'; +import { addSnackbar } from '../store/slices/snackbars'; +import { createAssetProxy } from '../valueObjects/AssetProxy'; +import { createEntry } from '../valueObjects/Entry'; +import { addAssets, getAsset } from './media'; +import { loadMedia, waitForMediaLibraryToLoad } from './mediaLibrary'; +import { waitUntil } from './waitUntil'; -import type { ImplementationMediaFile } from 'netlify-cms-lib-util'; +import type { Set } from 'immutable'; import type { AnyAction } from 'redux'; import type { ThunkDispatch } from 'redux-thunk'; -import type { - Collection, - EntryMap, - State, - EntryFields, - EntryField, - ViewFilter, - ViewGroup, - Entry, -} from '../types/redux'; -import type { EntryValue } from '../valueObjects/Entry'; import type { Backend } from '../backend'; +import type { ViewFilter, ViewGroup } from '../interface'; +import type { ImplementationMediaFile } from '../lib/util'; +import type { Collection, Entry, EntryField, EntryFields, EntryMap, State } from '../types/redux'; import type AssetProxy from '../valueObjects/AssetProxy'; -import type { Set } from 'immutable'; - -const { notifSend } = notifActions; +import type { EntryValue } from '../valueObjects/Entry'; /* * Constant Declarations @@ -534,16 +524,15 @@ export function loadEntry(collection: Collection, slug: string) { const loadedEntry = await tryLoadEntry(getState(), collection, slug); dispatch(entryLoaded(collection, loadedEntry)); dispatch(createDraftFromEntry(loadedEntry)); - } catch (error) { + } catch (error: any) { console.error(error); dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { - details: error.message, key: 'ui.toast.onFailToLoadEntries', + details: error.message, }, - kind: 'danger', - dismissAfter: 8000, }), ); dispatch(entryLoadError(error, collection, slug)); @@ -630,15 +619,14 @@ export function loadEntries(collection: Collection, page = 0) { append, ), ); - } catch (err) { + } catch (err: any) { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { - details: err, key: 'ui.toast.onFailToLoadEntries', + details: err, }, - kind: 'danger', - dismissAfter: 8000, }), ); return Promise.reject(dispatch(entriesFailed(collection, err))); @@ -681,16 +669,15 @@ export function traverseCollectionCursor(collection: Collection, action: string) return dispatch( entriesLoaded(collection, entries, pagination, addAppendActionsToCursor(newCursor), append), ); - } catch (err) { + } catch (err: any) { console.error(err); dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { - details: err, key: 'ui.toast.onFailToLoadEntries', + details: err, }, - kind: 'danger', - dismissAfter: 8000, }), ); return Promise.reject(dispatch(entriesFailed(collection, err))); @@ -894,12 +881,11 @@ export function persistEntry(collection: Collection) { if (hasPresenceErrors) { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { key: 'ui.toast.missingRequiredField', }, - kind: 'danger', - dismissAfter: 8000, }), ); } @@ -926,12 +912,11 @@ export function persistEntry(collection: Collection) { }) .then(async (newSlug: string) => { dispatch( - notifSend({ + addSnackbar({ + type: 'success', message: { key: 'ui.toast.entrySaved', }, - kind: 'success', - dismissAfter: 4000, }), ); @@ -951,13 +936,12 @@ export function persistEntry(collection: Collection) { .catch((error: Error) => { console.error(error); dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { - details: error, key: 'ui.toast.onFailToPersist', + details: error, }, - kind: 'danger', - dismissAfter: 8000, }), ); return Promise.reject(dispatch(entryPersistFail(collection, serializedEntry, error))); @@ -978,13 +962,12 @@ export function deleteEntry(collection: Collection, slug: string) { }) .catch((error: Error) => { dispatch( - notifSend({ + addSnackbar({ + type: 'error', message: { - details: error, key: 'ui.toast.onFailToDelete', + details: error, }, - kind: 'danger', - dismissAfter: 8000, }), ); console.error(error); diff --git a/packages/netlify-cms-core/src/actions/media.ts b/packages/netlify-cms-core/src/actions/media.ts index 0aa0c724..feeb224a 100644 --- a/packages/netlify-cms-core/src/actions/media.ts +++ b/packages/netlify-cms-core/src/actions/media.ts @@ -1,5 +1,4 @@ -import { isAbsolutePath } from 'netlify-cms-lib-util'; - +import { isAbsolutePath } from '../lib/util'; import { createAssetProxy } from '../valueObjects/AssetProxy'; import { selectMediaFilePath } from '../reducers/entries'; import { selectMediaFileByPath } from '../reducers/mediaLibrary'; @@ -60,7 +59,7 @@ export function loadAsset(resolvedPath: string) { dispatch(addAsset(asset)); } dispatch(loadAssetSuccess(resolvedPath)); - } catch (e) { + } catch (e: any) { dispatch(loadAssetFailure(resolvedPath, e)); } }; diff --git a/packages/netlify-cms-core/src/actions/mediaLibrary.ts b/packages/netlify-cms-core/src/actions/mediaLibrary.ts index 266a324c..26d03642 100644 --- a/packages/netlify-cms-core/src/actions/mediaLibrary.ts +++ b/packages/netlify-cms-core/src/actions/mediaLibrary.ts @@ -1,35 +1,34 @@ import { Map } from 'immutable'; -import { actions as notifActions } from 'redux-notifications'; -import { basename, getBlobSHA } from 'netlify-cms-lib-util'; import { currentBackend } from '../backend'; -import { createAssetProxy } from '../valueObjects/AssetProxy'; +import confirm from '../components/UI/Confirm'; +import { getIntegrationProvider } from '../integrations'; +import { sanitizeSlug } from '../lib/urlHelper'; +import { basename, getBlobSHA } from '../lib/util'; import { selectIntegration } from '../reducers'; import { + selectEditingDraft, selectMediaFilePath, selectMediaFilePublicPath, - selectEditingDraft, } from '../reducers/entries'; import { selectMediaDisplayURL, selectMediaFiles } from '../reducers/mediaLibrary'; -import { getIntegrationProvider } from '../integrations'; -import { addAsset, removeAsset } from './media'; +import { addSnackbar } from '../store/slices/snackbars'; +import { createAssetProxy } from '../valueObjects/AssetProxy'; import { addDraftEntryMediaFile, removeDraftEntryMediaFile } from './entries'; -import { sanitizeSlug } from '../lib/urlHelper'; +import { addAsset, removeAsset } from './media'; import { waitUntilWithTimeout } from './waitUntil'; -import type { - State, - MediaFile, - DisplayURLState, - MediaLibraryInstance, - EntryField, -} from '../types/redux'; import type { AnyAction } from 'redux'; import type { ThunkDispatch } from 'redux-thunk'; +import type { ImplementationMediaFile } from '../lib/util'; +import type { + DisplayURLState, + EntryField, + MediaFile, + MediaLibraryInstance, + State, +} from '../types/redux'; import type AssetProxy from '../valueObjects/AssetProxy'; -import type { ImplementationMediaFile } from 'netlify-cms-lib-util'; - -const { notifSend } = notifActions; export const MEDIA_LIBRARY_OPEN = 'MEDIA_LIBRARY_OPEN'; export const MEDIA_LIBRARY_CLOSE = 'MEDIA_LIBRARY_CLOSE'; @@ -169,7 +168,7 @@ export function loadMedia( .catch((error: { status?: number }) => { console.error(error); if (error.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); dispatch(mediaLoaded([])); } else { dispatch(mediaLoadFailed()); @@ -231,7 +230,16 @@ export function persistMedia(file: File, opts: MediaOptions = {}) { * may not be unique, so we forego this check. */ if (!integration && existingFile) { - if (!window.confirm(`${existingFile.name} already exists. Do you want to replace it?`)) { + if ( + !(await confirm({ + title: 'mediaLibrary.mediaLibrary.alreadyExistsTitle', + body: { + key: 'mediaLibrary.mediaLibrary.alreadyExistsBody', + options: { filename: existingFile.name }, + }, + color: 'error', + })) + ) { return; } else { await dispatch(deleteMedia(existingFile, { privateUpload })); @@ -299,10 +307,12 @@ export function persistMedia(file: File, opts: MediaOptions = {}) { } catch (error) { console.error(error); dispatch( - notifSend({ - message: `Failed to persist media: ${error}`, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { + key: 'ui.toast.onFailToPersistMedia', + details: error, + }, }), ); return dispatch(mediaPersistFailed({ privateUpload })); @@ -323,13 +333,15 @@ export function deleteMedia(file: MediaFile, opts: MediaOptions = {}) { try { await provider.delete(file.id); return dispatch(mediaDeleted(file, { privateUpload })); - } catch (error) { + } catch (error: any) { console.error(error); dispatch( - notifSend({ - message: `Failed to delete media: ${error.message}`, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { + key: 'ui.toast.onFailToDeleteMedia', + details: error.message, + }, }), ); return dispatch(mediaDeleteFailed({ privateUpload })); @@ -353,13 +365,15 @@ export function deleteMedia(file: MediaFile, opts: MediaOptions = {}) { dispatch(removeDraftEntryMediaFile({ id: file.id })); } } - } catch (error) { + } catch (error: any) { console.error(error); dispatch( - notifSend({ - message: `Failed to delete media: ${error.message}`, - kind: 'danger', - dismissAfter: 8000, + addSnackbar({ + type: 'error', + message: { + key: 'ui.toast.onFailToDeleteMedia', + details: error.message, + }, }), ); return dispatch(mediaDeleteFailed()); @@ -401,7 +415,7 @@ export function loadMediaDisplayURL(file: MediaFile) { } else { throw new Error('No display URL was returned!'); } - } catch (err) { + } catch (err: any) { console.error(err); dispatch(mediaDisplayURLFailure(id, err)); } diff --git a/packages/netlify-cms-core/src/actions/status.ts b/packages/netlify-cms-core/src/actions/status.ts index b66a5930..8c09dffd 100644 --- a/packages/netlify-cms-core/src/actions/status.ts +++ b/packages/netlify-cms-core/src/actions/status.ts @@ -1,13 +1,10 @@ -import { actions as notifActions } from 'redux-notifications'; - import { currentBackend } from '../backend'; +import { addSnackbar, removeSnackbarById } from '../store/slices/snackbars'; -import type { ThunkDispatch } from 'redux-thunk'; import type { AnyAction } from 'redux'; +import type { ThunkDispatch } from 'redux-thunk'; import type { State } from '../types/redux'; -const { notifSend, notifDismiss } = notifActions; - export const STATUS_REQUEST = 'STATUS_REQUEST'; export const STATUS_SUCCESS = 'STATUS_SUCCESS'; export const STATUS_FAILURE = 'STATUS_FAILURE'; @@ -48,17 +45,16 @@ export function checkBackendStatus() { const status = await backend.status(); const backendDownKey = 'ui.toast.onBackendDown'; - const previousBackendDownNotifs = state.notifs.filter(n => n.message?.key === backendDownKey); + const previousBackendDownNotifs = state.snackbar.messages.filter( + n => n.message?.key === backendDownKey, + ); if (status.api.status === false) { if (previousBackendDownNotifs.length === 0) { dispatch( - notifSend({ - message: { - details: status.api.statusPage, - key: 'ui.toast.onBackendDown', - }, - kind: 'danger', + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onBackendDown', details: status.api.statusPage }, }), ); } @@ -66,21 +62,19 @@ export function checkBackendStatus() { } else if (status.api.status === true && previousBackendDownNotifs.length > 0) { // If backend is up, clear all the danger messages previousBackendDownNotifs.forEach(notif => { - dispatch(notifDismiss(notif.id)); + dispatch(removeSnackbarById(notif.id)); }); } const authError = status.auth.status === false; if (authError) { const key = 'ui.toast.onLoggedOut'; - const existingNotification = state.notifs.find(n => n.message?.key === key); + const existingNotification = state.snackbar.messages.find(n => n.message?.key === key); if (!existingNotification) { dispatch( - notifSend({ - message: { - key: 'ui.toast.onLoggedOut', - }, - kind: 'danger', + addSnackbar({ + type: 'error', + message: { key: 'ui.toast.onLoggedOut' }, }), ); } diff --git a/packages/netlify-cms-core/src/actions/waitUntil.ts b/packages/netlify-cms-core/src/actions/waitUntil.ts index d0a51b1d..524dae83 100644 --- a/packages/netlify-cms-core/src/actions/waitUntil.ts +++ b/packages/netlify-cms-core/src/actions/waitUntil.ts @@ -1,6 +1,6 @@ -import { WAIT_UNTIL_ACTION } from '../redux/middleware/waitUntilAction'; +import { WAIT_UNTIL_ACTION } from '../store/middleware/waitUntilAction'; -import type { WaitActionArgs } from '../redux/middleware/waitUntilAction'; +import type { WaitActionArgs } from '../store/middleware/waitUntilAction'; import type { ThunkDispatch } from 'redux-thunk'; import type { AnyAction } from 'redux'; import type { State } from '../types/redux'; diff --git a/packages/netlify-cms-core/src/backend.ts b/packages/netlify-cms-core/src/backend.ts index b328dac8..b7a94df5 100644 --- a/packages/netlify-cms-core/src/backend.ts +++ b/packages/netlify-cms-core/src/backend.ts @@ -1,78 +1,78 @@ -import { attempt, flatten, isError, uniq, trim, sortBy, get, set } from 'lodash'; -import { List, fromJS, Set } from 'immutable'; import * as fuzzy from 'fuzzy'; +import { fromJS, List, Set } from 'immutable'; +import { attempt, flatten, get, isError, set, sortBy, trim, uniq } from 'lodash'; +import { basename, dirname, extname, join } from 'path'; + +import { FILES, FOLDER } from './constants/collectionTypes'; +import { status } from './constants/publishModes'; +import { resolveFormat } from './formats/formats'; +import { commitMessageFormatter, previewUrlFormatter, slugFormatter } from './lib/formatters'; import { - localForage, + formatI18nBackup, + getFilePaths, + getI18nBackup, + getI18nDataFiles, + getI18nEntry, + getI18nFiles, + getI18nFilesDepth, + groupEntries, + hasI18n, +} from './lib/i18n'; +import { getBackend, invokeEvent } from './lib/registry'; +import { sanitizeChar } from './lib/urlHelper'; +import { + asyncLock, + blobToFileObj, Cursor, CURSOR_COMPATIBILITY_SYMBOL, - getPathDepth, - blobToFileObj, - asyncLock, EDITORIAL_WORKFLOW_ERROR, -} from 'netlify-cms-lib-util'; -import { basename, join, extname, dirname } from 'path'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; - -import { resolveFormat } from './formats/formats'; -import { selectUseWorkflow } from './reducers/config'; -import { selectMediaFilePath, selectEntry } from './reducers/entries'; -import { selectIntegration } from './reducers/integrations'; + getPathDepth, + localForage, +} from './lib/util'; +import { stringTemplate } from './lib/widgets'; import { - selectEntrySlug, - selectEntryPath, - selectFileEntryLabel, - selectAllowNewEntries, selectAllowDeletion, + selectAllowNewEntries, + selectEntryPath, + selectEntrySlug, + selectFieldsComments, + selectFileEntryLabel, selectFolderEntryExtension, + selectHasMetaPath, selectInferedField, selectMediaFolders, - selectFieldsComments, - selectHasMetaPath, } from './reducers/collections'; -import { createEntry } from './valueObjects/Entry'; -import { sanitizeChar } from './lib/urlHelper'; -import { getBackend, invokeEvent } from './lib/registry'; -import { commitMessageFormatter, slugFormatter, previewUrlFormatter } from './lib/formatters'; -import { status } from './constants/publishModes'; -import { FOLDER, FILES } from './constants/collectionTypes'; +import { selectUseWorkflow } from './reducers/config'; +import { selectEntry, selectMediaFilePath } from './reducers/entries'; import { selectCustomPath } from './reducers/entryDraft'; -import { - getI18nFilesDepth, - getI18nFiles, - hasI18n, - getFilePaths, - getI18nEntry, - groupEntries, - getI18nDataFiles, - getI18nBackup, - formatI18nBackup, -} from './lib/i18n'; +import { selectIntegration } from './reducers/integrations'; +import { createEntry } from './valueObjects/Entry'; -import type AssetProxy from './valueObjects/AssetProxy'; +import type { Map } from 'immutable'; +import type { CmsConfig } from './interface'; import type { - CmsConfig, + AsyncLock, + Credentials, + DataFile, + DisplayURL, + Implementation as BackendImplementation, + ImplementationEntry, + UnpublishedEntry, + UnpublishedEntryDiff, + User, +} from './lib/util'; +import type { + Collection, + CollectionFile, + Collections, + EntryDraft, + EntryField, EntryMap, FilterRule, - EntryDraft, - Collection, - Collections, - CollectionFile, State, - EntryField, } from './types/redux'; +import type AssetProxy from './valueObjects/AssetProxy'; import type { EntryValue } from './valueObjects/Entry'; -import type { - Implementation as BackendImplementation, - DisplayURL, - ImplementationEntry, - Credentials, - User, - AsyncLock, - UnpublishedEntry, - DataFile, - UnpublishedEntryDiff, -} from 'netlify-cms-lib-util'; -import type { Map } from 'immutable'; const { extractTemplateVars, dateParsers, expandPath } = stringTemplate; @@ -399,7 +399,7 @@ export class Backend { async logout() { try { await this.implementation.logout(); - } catch (e) { + } catch (e: any) { console.warn('Error during logout', e.message); } finally { this.user = null; diff --git a/packages/netlify-cms-backend-azure/src/API.ts b/packages/netlify-cms-core/src/backends/azure/API.ts similarity index 99% rename from packages/netlify-cms-backend-azure/src/API.ts rename to packages/netlify-cms-core/src/backends/azure/API.ts index bbc1668a..0b5998f3 100644 --- a/packages/netlify-cms-backend-azure/src/API.ts +++ b/packages/netlify-cms-core/src/backends/azure/API.ts @@ -1,5 +1,7 @@ import { Base64 } from 'js-base64'; import { partial, result, trim, trimStart } from 'lodash'; +import { dirname, basename } from 'path'; + import { localForage, APIError, @@ -18,10 +20,9 @@ import { PreviewState, readFileMetadata, branchFromContentKey, -} from 'netlify-cms-lib-util'; -import { dirname, basename } from 'path'; +} from '../../lib/util'; -import type { ApiRequest, AssetProxy, PersistOptions, DataFile } from 'netlify-cms-lib-util'; +import type { ApiRequest, AssetProxy, PersistOptions, DataFile } from '../../lib/util'; import type { Map } from 'immutable'; export const API_NAME = 'Azure DevOps'; @@ -277,7 +278,7 @@ export default class API { request = (req: ApiRequest): Promise => { try { return requestWithBackoff(this, req); - } catch (err) { + } catch (err: any) { throw new APIError(err.message, null, API_NAME); } }; @@ -377,9 +378,9 @@ export default class API { name: basename(file.path), })); return files; - } catch (err) { + } catch (err: any) { if (err && err.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); return []; } else { throw err; diff --git a/packages/netlify-cms-backend-azure/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/azure/AuthenticationPage.js similarity index 86% rename from packages/netlify-cms-backend-azure/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/azure/AuthenticationPage.js index 7ed93e08..cadee864 100644 --- a/packages/netlify-cms-backend-azure/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/azure/AuthenticationPage.js @@ -1,8 +1,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { ImplicitAuthenticator } from 'netlify-cms-lib-auth'; -import { AuthenticationPage, Icon } from 'netlify-cms-ui-default'; + +import { AuthenticationPage, Icon } from '../../ui'; +import { ImplicitAuthenticator } from '../../lib/auth'; +import alert from '../../components/UI/Alert'; const LoginButtonIcon = styled(Icon)` margin-right: 18px; @@ -32,7 +34,10 @@ export default class AzureAuthenticationPage extends React.Component { // Complete implicit authentication if we were redirected back to from the provider. this.auth.completeAuth((err, data) => { if (err) { - alert(err); + alert({ + title: 'auth.errors.authTitle', + body: { key: 'auth.errors.authBody', options: { details: err } }, + }); return; } this.props.onLogin(data); diff --git a/packages/netlify-cms-backend-azure/src/implementation.ts b/packages/netlify-cms-core/src/backends/azure/implementation.ts similarity index 99% rename from packages/netlify-cms-backend-azure/src/implementation.ts rename to packages/netlify-cms-core/src/backends/azure/implementation.ts index b80ad80e..1c0dfc12 100644 --- a/packages/netlify-cms-backend-azure/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/azure/implementation.ts @@ -1,5 +1,6 @@ import { trimStart, trim } from 'lodash'; import semaphore from 'semaphore'; + import { basename, getMediaDisplayURL, @@ -15,8 +16,7 @@ import { entriesByFolder, contentKeyFromBranch, getBlobSHA, -} from 'netlify-cms-lib-util'; - +} from '../../lib/util'; import AuthenticationPage from './AuthenticationPage'; import API, { API_NAME } from './API'; @@ -34,7 +34,7 @@ import type { AsyncLock, User, UnpublishedEntryMediaFile, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; const MAX_CONCURRENT_DOWNLOADS = 10; diff --git a/packages/netlify-cms-backend-azure/src/index.ts b/packages/netlify-cms-core/src/backends/azure/index.ts similarity index 100% rename from packages/netlify-cms-backend-azure/src/index.ts rename to packages/netlify-cms-core/src/backends/azure/index.ts diff --git a/packages/netlify-cms-backend-bitbucket/src/API.ts b/packages/netlify-cms-core/src/backends/bitbucket/API.ts similarity index 98% rename from packages/netlify-cms-backend-bitbucket/src/API.ts rename to packages/netlify-cms-core/src/backends/bitbucket/API.ts index 5e1ec935..7abaca38 100644 --- a/packages/netlify-cms-backend-bitbucket/src/API.ts +++ b/packages/netlify-cms-core/src/backends/bitbucket/API.ts @@ -1,4 +1,8 @@ import { flow, get } from 'lodash'; +import { dirname } from 'path'; +import { oneLine } from 'common-tags'; +import { parse } from 'what-the-diff'; + import { localForage, unsentRequest, @@ -22,10 +26,7 @@ import { requestWithBackoff, readFileMetadata, throwOnConflictingBranches, -} from 'netlify-cms-lib-util'; -import { dirname } from 'path'; -import { oneLine } from 'common-tags'; -import { parse } from 'what-the-diff'; +} from '../../lib/util'; import type { ApiRequest, @@ -33,7 +34,7 @@ import type { PersistOptions, FetchError, DataFile, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; interface Config { apiRoot?: string; @@ -192,7 +193,7 @@ const APPLICATION_JSON = 'application/json; charset=utf-8'; function replace404WithEmptyResponse(err: FetchError) { if (err && err.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); return { size: 0, values: [] as BitBucketFile[] } as BitBucketSrcResult; } else { return Promise.reject(err); @@ -236,7 +237,7 @@ export default class API { request = (req: ApiRequest): Promise => { try { return requestWithBackoff(this, req); - } catch (err) { + } catch (err: any) { throw new APIError(err.message, null, API_NAME); } }; @@ -345,7 +346,7 @@ export default class API { url: `${this.repoURL}/commits`, params: { include: branch, pagelen: 100 }, }).catch(e => { - console.log(`Failed getting commits for branch '${branch}'`, e); + console.info(`Failed getting commits for branch '${branch}'`, e); return []; }); @@ -493,7 +494,7 @@ export default class API { method: 'POST', body: formData, }); - } catch (error) { + } catch (error: any) { const message = error.message || ''; // very descriptive message from Bitbucket if (parentSha && message.includes('Something went wrong')) { @@ -681,7 +682,7 @@ export default class API { } async listUnpublishedBranches() { - console.log( + console.info( '%c Checking for Unpublished entries', 'line-height: 30px;text-align: center;font-weight: bold', ); diff --git a/packages/netlify-cms-backend-bitbucket/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/bitbucket/AuthenticationPage.js similarity index 94% rename from packages/netlify-cms-backend-bitbucket/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/bitbucket/AuthenticationPage.js index 9a459153..f5a05660 100644 --- a/packages/netlify-cms-backend-bitbucket/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/bitbucket/AuthenticationPage.js @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { NetlifyAuthenticator, ImplicitAuthenticator } from 'netlify-cms-lib-auth'; -import { AuthenticationPage, Icon } from 'netlify-cms-ui-default'; + +import { AuthenticationPage, Icon } from '../../ui'; +import { NetlifyAuthenticator, ImplicitAuthenticator } from '../../lib/auth'; const LoginButtonIcon = styled(Icon)` margin-right: 18px; diff --git a/packages/netlify-cms-backend-bitbucket/src/git-lfs-client.ts b/packages/netlify-cms-core/src/backends/bitbucket/git-lfs-client.ts similarity index 95% rename from packages/netlify-cms-backend-bitbucket/src/git-lfs-client.ts rename to packages/netlify-cms-core/src/backends/bitbucket/git-lfs-client.ts index ab4963c8..fc1e837d 100644 --- a/packages/netlify-cms-backend-bitbucket/src/git-lfs-client.ts +++ b/packages/netlify-cms-core/src/backends/bitbucket/git-lfs-client.ts @@ -1,7 +1,8 @@ import minimatch from 'minimatch'; -import { unsentRequest } from 'netlify-cms-lib-util'; -import type { ApiRequest, PointerFile } from 'netlify-cms-lib-util'; +import { unsentRequest } from '../../lib/util'; + +import type { ApiRequest, PointerFile } from '../../lib/util'; type MakeAuthorizedRequest = (req: ApiRequest) => Promise; diff --git a/packages/netlify-cms-backend-bitbucket/src/implementation.ts b/packages/netlify-cms-core/src/backends/bitbucket/implementation.ts similarity index 98% rename from packages/netlify-cms-backend-bitbucket/src/implementation.ts rename to packages/netlify-cms-core/src/backends/bitbucket/implementation.ts index 30375ad6..2e35dad2 100644 --- a/packages/netlify-cms-backend-bitbucket/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/bitbucket/implementation.ts @@ -1,6 +1,7 @@ import semaphore from 'semaphore'; import { trimStart } from 'lodash'; import { stripIndent } from 'common-tags'; + import { CURSOR_COMPATIBILITY_SYMBOL, filterByExtension, @@ -25,9 +26,8 @@ import { allEntriesByFolder, AccessTokenError, branchFromContentKey, -} from 'netlify-cms-lib-util'; -import { NetlifyAuthenticator } from 'netlify-cms-lib-auth'; - +} from '../../lib/util'; +import { NetlifyAuthenticator } from '../../lib/auth'; import AuthenticationPage from './AuthenticationPage'; import API, { API_NAME } from './API'; import { GitLfsClient } from './git-lfs-client'; @@ -46,7 +46,7 @@ import type { ImplementationFile, AsyncLock, FetchError, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; import type { Semaphore } from 'semaphore'; const MAX_CONCURRENT_DOWNLOADS = 10; @@ -386,7 +386,7 @@ export default class BitbucketBackend implements Implementation { .then(attributes => getLargeMediaPatternsFromGitAttributesFile(attributes as string)) .catch((err: FetchError) => { if (err.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); } else { console.error(err); } @@ -450,7 +450,7 @@ export default class BitbucketBackend implements Implementation { async persistMedia(mediaFile: AssetProxy, options: PersistOptions) { const { fileObj, path } = mediaFile; - const displayURL = URL.createObjectURL(fileObj); + const displayURL = URL.createObjectURL(fileObj as Blob); const client = await this.getLargeMediaClient(); const fixedPath = path.startsWith('/') ? path.slice(1) : path; if (!client.enabled || !client.matchPath(fixedPath)) { diff --git a/packages/netlify-cms-backend-bitbucket/src/index.ts b/packages/netlify-cms-core/src/backends/bitbucket/index.ts similarity index 100% rename from packages/netlify-cms-backend-bitbucket/src/index.ts rename to packages/netlify-cms-core/src/backends/bitbucket/index.ts diff --git a/packages/netlify-cms-backend-bitbucket/src/types/semaphore.d.ts b/packages/netlify-cms-core/src/backends/bitbucket/types/semaphore.d.ts similarity index 100% rename from packages/netlify-cms-backend-bitbucket/src/types/semaphore.d.ts rename to packages/netlify-cms-core/src/backends/bitbucket/types/semaphore.d.ts diff --git a/packages/netlify-cms-backend-bitbucket/src/types/what-the-diff.d.ts b/packages/netlify-cms-core/src/backends/bitbucket/types/what-the-diff.d.ts similarity index 100% rename from packages/netlify-cms-backend-bitbucket/src/types/what-the-diff.d.ts rename to packages/netlify-cms-core/src/backends/bitbucket/types/what-the-diff.d.ts diff --git a/packages/netlify-cms-backend-git-gateway/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/git-gateway/AuthenticationPage.js similarity index 99% rename from packages/netlify-cms-backend-git-gateway/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/git-gateway/AuthenticationPage.js index 2dc89c30..ca92d96d 100644 --- a/packages/netlify-cms-backend-git-gateway/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/git-gateway/AuthenticationPage.js @@ -2,6 +2,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import styled from '@emotion/styled'; import { partial } from 'lodash'; + import { AuthenticationPage, buttons, @@ -10,7 +11,7 @@ import { colorsRaw, lengths, zIndex, -} from 'netlify-cms-ui-default'; +} from '../../ui'; const LoginButton = styled.button` ${buttons.button}; diff --git a/packages/netlify-cms-backend-git-gateway/src/GitHubAPI.ts b/packages/netlify-cms-core/src/backends/git-gateway/GitHubAPI.ts similarity index 93% rename from packages/netlify-cms-backend-git-gateway/src/GitHubAPI.ts rename to packages/netlify-cms-core/src/backends/git-gateway/GitHubAPI.ts index cc5a71e0..86b97f51 100644 --- a/packages/netlify-cms-backend-git-gateway/src/GitHubAPI.ts +++ b/packages/netlify-cms-core/src/backends/git-gateway/GitHubAPI.ts @@ -1,8 +1,8 @@ -import { API as GithubAPI } from 'netlify-cms-backend-github'; -import { APIError } from 'netlify-cms-lib-util'; +import { APIError } from '../../lib/util'; +import { API as GithubAPI } from '../github'; -import type { Config as GitHubConfig, Diff } from 'netlify-cms-backend-github/src/API'; -import type { FetchError } from 'netlify-cms-lib-util'; +import type { Config as GitHubConfig, Diff } from '../github/API'; +import type { FetchError } from '../../lib/util'; import type { Octokit } from '@octokit/rest'; type Config = GitHubConfig & { diff --git a/packages/netlify-cms-backend-git-gateway/src/GitLabAPI.ts b/packages/netlify-cms-core/src/backends/git-gateway/GitLabAPI.ts similarity index 70% rename from packages/netlify-cms-backend-git-gateway/src/GitLabAPI.ts rename to packages/netlify-cms-core/src/backends/git-gateway/GitLabAPI.ts index 43292dab..6862a94b 100644 --- a/packages/netlify-cms-backend-git-gateway/src/GitLabAPI.ts +++ b/packages/netlify-cms-core/src/backends/git-gateway/GitLabAPI.ts @@ -1,8 +1,8 @@ -import { API as GitlabAPI } from 'netlify-cms-backend-gitlab'; -import { unsentRequest } from 'netlify-cms-lib-util'; +import { unsentRequest } from '../../lib/util'; +import { API as GitlabAPI } from '../gitlab'; -import type { Config as GitLabConfig, CommitAuthor } from 'netlify-cms-backend-gitlab/src/API'; -import type { ApiRequest } from 'netlify-cms-lib-util'; +import type { Config as GitLabConfig, CommitAuthor } from '../gitlab/API'; +import type { ApiRequest } from '../../lib/util'; type Config = GitLabConfig & { tokenPromise: () => Promise; commitAuthor: CommitAuthor }; diff --git a/packages/netlify-cms-backend-git-gateway/src/implementation.ts b/packages/netlify-cms-core/src/backends/git-gateway/implementation.ts similarity index 97% rename from packages/netlify-cms-backend-git-gateway/src/implementation.ts rename to packages/netlify-cms-core/src/backends/git-gateway/implementation.ts index 158124d3..04844f67 100644 --- a/packages/netlify-cms-backend-git-gateway/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/git-gateway/implementation.ts @@ -2,6 +2,7 @@ import GoTrue from 'gotrue-js'; import jwtDecode from 'jwt-decode'; import { get, pick, intersection } from 'lodash'; import ini from 'ini'; + import { APIError, unsentRequest, @@ -13,11 +14,10 @@ import { getLargeMediaFilteredMediaFiles, AccessTokenError, PreviewState, -} from 'netlify-cms-lib-util'; -import { GitHubBackend } from 'netlify-cms-backend-github'; -import { GitLabBackend } from 'netlify-cms-backend-gitlab'; -import { BitbucketBackend, API as BitBucketAPI } from 'netlify-cms-backend-bitbucket'; - +} from '../../lib/util'; +import { GitHubBackend } from '../github'; +import { GitLabBackend } from '../gitlab'; +import { BitbucketBackend, API as BitBucketAPI } from '../bitbucket'; import GitHubAPI from './GitHubAPI'; import GitLabAPI from './GitLabAPI'; import AuthenticationPage from './AuthenticationPage'; @@ -37,7 +37,7 @@ import type { Config, ImplementationFile, DisplayURLObject, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; const STATUS_PAGE = 'https://www.netlifystatus.com'; const GIT_GATEWAY_STATUS_ENDPOINT = `${STATUS_PAGE}/api/v2/components.json`; @@ -105,7 +105,7 @@ let initPromise = Promise.resolve() as Promise; if (window.netlifyIdentity) { let initialized = false; initPromise = Promise.race([ - new Promise(resolve => { + new Promise(resolve => { window.netlifyIdentity?.on('init', () => { initialized = true; resolve(); @@ -113,7 +113,7 @@ if (window.netlifyIdentity) { }), new Promise(resolve => setTimeout(resolve, 2500)).then(() => { if (!initialized) { - console.log('Manually initializing identity widget'); + console.info('Manually initializing identity widget'); window.netlifyIdentity?.init(); } }), @@ -273,7 +273,7 @@ export default class GitGateway implements Implementation { const func = user.jwt.bind(user); const token = await func(); return token; - } catch (error) { + } catch (error: any) { throw new AccessTokenError(`Failed getting access token: ${error.message}`); } }; @@ -416,9 +416,10 @@ export default class GitGateway implements Implementation { if (isLargeMedia) { const branch = this.backend!.getBranch(collection, slug); const { url, blob } = await this.getLargeMediaDisplayURL({ path, id }, branch); + const name = basename(path); return { id, - name: basename(path), + name, path, url, displayURL: url, @@ -457,7 +458,7 @@ export default class GitGateway implements Implementation { .then((patterns: string[]) => ({ err: null, patterns })) .catch((err: Error) => { if (err.message.includes('404')) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); return { err: null, patterns: [] as string[] }; } else { return { err, patterns: [] as string[] }; @@ -531,9 +532,10 @@ export default class GitGateway implements Implementation { const isLargeMedia = await this.isLargeMediaFile(path); if (isLargeMedia) { const { url, blob } = await this.getLargeMediaDisplayURL({ path, id: null }); + const name = basename(path); return { id: url, - name: basename(path), + name, path, url, displayURL: url, @@ -556,7 +558,7 @@ export default class GitGateway implements Implementation { async persistMedia(mediaFile: AssetProxy, options: PersistOptions) { const { fileObj, path } = mediaFile; - const displayURL = URL.createObjectURL(fileObj); + const displayURL = URL.createObjectURL(fileObj as Blob); const client = await this.getLargeMediaClient(); const fixedPath = path.startsWith('/') ? path.slice(1) : path; const isLargeMedia = await this.isLargeMediaFile(fixedPath); diff --git a/packages/netlify-cms-backend-git-gateway/src/index.ts b/packages/netlify-cms-core/src/backends/git-gateway/index.ts similarity index 100% rename from packages/netlify-cms-backend-git-gateway/src/index.ts rename to packages/netlify-cms-core/src/backends/git-gateway/index.ts diff --git a/packages/netlify-cms-backend-git-gateway/src/netlify-lfs-client.ts b/packages/netlify-cms-core/src/backends/git-gateway/netlify-lfs-client.ts similarity index 97% rename from packages/netlify-cms-backend-git-gateway/src/netlify-lfs-client.ts rename to packages/netlify-cms-core/src/backends/git-gateway/netlify-lfs-client.ts index 4255bcb5..6988ca5b 100644 --- a/packages/netlify-cms-backend-git-gateway/src/netlify-lfs-client.ts +++ b/packages/netlify-cms-core/src/backends/git-gateway/netlify-lfs-client.ts @@ -1,9 +1,10 @@ import { flow, fromPairs, map } from 'lodash/fp'; import { isPlainObject, isEmpty } from 'lodash'; import minimatch from 'minimatch'; -import { unsentRequest } from 'netlify-cms-lib-util'; -import type { ApiRequest, PointerFile } from 'netlify-cms-lib-util'; +import { unsentRequest } from '../../lib/util'; + +import type { ApiRequest, PointerFile } from '../../lib/util'; type MakeAuthorizedRequest = (req: ApiRequest) => Promise; diff --git a/packages/netlify-cms-backend-git-gateway/src/types/ini.d.ts b/packages/netlify-cms-core/src/backends/git-gateway/types/ini.d.ts similarity index 100% rename from packages/netlify-cms-backend-git-gateway/src/types/ini.d.ts rename to packages/netlify-cms-core/src/backends/git-gateway/types/ini.d.ts diff --git a/packages/netlify-cms-backend-github/src/API.ts b/packages/netlify-cms-core/src/backends/github/API.ts similarity index 96% rename from packages/netlify-cms-backend-github/src/API.ts rename to packages/netlify-cms-core/src/backends/github/API.ts index 449b95b0..a2888e93 100644 --- a/packages/netlify-cms-backend-github/src/API.ts +++ b/packages/netlify-cms-core/src/backends/github/API.ts @@ -1,7 +1,8 @@ import { Base64 } from 'js-base64'; import semaphore from 'semaphore'; import { initial, last, partial, result, trimStart, trim } from 'lodash'; -import { oneLine } from 'common-tags'; +import { dirname } from 'path'; + import { getAllResponses, APIError, @@ -23,16 +24,10 @@ import { requestWithBackoff, unsentRequest, throwOnConflictingBranches, -} from 'netlify-cms-lib-util'; -import { dirname } from 'path'; +} from '../../lib/util'; +import alert from '../../components/UI/Alert'; -import type { - AssetProxy, - DataFile, - PersistOptions, - FetchError, - ApiRequest, -} from 'netlify-cms-lib-util'; +import type { AssetProxy, DataFile, PersistOptions, FetchError, ApiRequest } from '../../lib/util'; import type { Semaphore } from 'semaphore'; import type { Octokit } from '@octokit/rest'; @@ -322,7 +317,7 @@ export default class API { responseStatus = response.status; const parsedResponse = await parser(response); return parsedResponse; - } catch (error) { + } catch (error: any) { return this.handleRequestError(error, responseStatus); } } @@ -395,7 +390,7 @@ export default class API { if (!this._metadataSemaphore) { this._metadataSemaphore = semaphore(1); } - return new Promise((resolve, reject) => + return new Promise((resolve, reject) => this._metadataSemaphore?.take(async () => { try { const branchData = await this.checkMetadataRef(); @@ -422,7 +417,7 @@ export default class API { if (!this._metadataSemaphore) { this._metadataSemaphore = semaphore(1); } - return new Promise(resolve => + return new Promise(resolve => this._metadataSemaphore?.take(async () => { try { const branchData = await this.checkMetadataRef(); @@ -442,7 +437,7 @@ export default class API { } async retrieveMetadataOld(key: string): Promise { - console.log( + console.info( '%c Checking for MetaData files', 'line-height: 30px;text-align: center;font-weight: bold', ); @@ -454,7 +449,7 @@ export default class API { function errorHandler(err: Error) { if (err.message === 'Not Found') { - console.log( + console.info( '%c %s does not have metadata', 'line-height: 30px;text-align: center;font-weight: bold', key, @@ -565,7 +560,7 @@ export default class API { ); return commits; } catch (e) { - console.log(e); + console.info(e); return []; } } @@ -696,9 +691,9 @@ export default class API { size: file.size!, })) ); - } catch (err) { + } catch (err: any) { if (err && err.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); return []; } else { throw err; @@ -771,40 +766,40 @@ export default class API { async migratePullRequest(pullRequest: GitHubPull, countMessage: string) { const { number } = pullRequest; - console.log(`Migrating Pull Request '${number}' (${countMessage})`); + console.info(`Migrating Pull Request '${number}' (${countMessage})`); const contentKey = contentKeyFromBranch(pullRequest.head.ref); let metadata = await this.retrieveMetadataOld(contentKey).catch(() => undefined); if (!metadata) { - console.log(`Skipped migrating Pull Request '${number}' (${countMessage})`); + console.info(`Skipped migrating Pull Request '${number}' (${countMessage})`); return; } let newNumber = number; if (!metadata.version) { - console.log(`Migrating Pull Request '${number}' to version 1`); + console.info(`Migrating Pull Request '${number}' to version 1`); // migrate branch from cms/slug to cms/collection/slug try { ({ metadata, pullRequest } = await this.migrateToVersion1(pullRequest, metadata)); } catch (e) { - console.log(`Failed to migrate Pull Request '${number}' to version 1. See error below.`); + console.info(`Failed to migrate Pull Request '${number}' to version 1. See error below.`); console.error(e); return; } newNumber = pullRequest.number; - console.log( + console.info( `Done migrating Pull Request '${number}' to version 1. New pull request '${newNumber}' created.`, ); } if (metadata.version === '1') { - console.log(`Migrating Pull Request '${newNumber}' to labels`); + console.info(`Migrating Pull Request '${newNumber}' to labels`); // migrate branch from using orphan ref to store metadata to pull requests label await this.migrateToPullRequestLabels(pullRequest, metadata); - console.log(`Done migrating Pull Request '${newNumber}' to labels`); + console.info(`Done migrating Pull Request '${newNumber}' to labels`); } - console.log( + console.info( `Done migrating Pull Request '${ number === newNumber ? newNumber : `${number} => ${newNumber}` }'`, @@ -819,7 +814,7 @@ export default class API { } async listUnpublishedBranches() { - console.log( + console.info( '%c Checking for Unpublished entries', 'line-height: 30px;text-align: center;font-weight: bold', ); @@ -846,11 +841,13 @@ export default class API { for (const pr of pullRequests) { if (!migrationNotified) { migrationNotified = true; - alert(oneLine` - Netlify CMS is adding labels to ${pullRequests.length} of your Editorial Workflow - entries. The "Workflow" tab will be unavailable during this migration. You may use other - areas of the CMS during this time. Note that closing the CMS will pause the migration. - `); + alert({ + title: 'api.labelsMigrationTitle', + body: { + key: 'api.labelsMigrationBody', + options: { pullRequests: pullRequests.length }, + }, + }); } prCount = prCount + 1; await this.migratePullRequest(pr, `${prCount} of ${pullRequests.length}`); @@ -1224,7 +1221,7 @@ export default class API { try { const result = await this.createRef('heads', branchName, sha); return result; - } catch (e) { + } catch (e: any) { const message = String(e.message || ''); if (message === 'Reference update failed') { await throwOnConflictingBranches(branchName, name => this.getBranch(name), API_NAME); @@ -1239,7 +1236,7 @@ export default class API { const result = await this.patchBranch(branchName, sha, { force: true }); return result; } catch (e) { - console.log(e); + console.error(e); } } throw e; @@ -1290,7 +1287,7 @@ export default class API { } async openPR(number: number) { - console.log('%c Re-opening PR', 'line-height: 30px;text-align: center;font-weight: bold'); + console.info('%c Re-opening PR', 'line-height: 30px;text-align: center;font-weight: bold'); const result: Octokit.PullsUpdateBranchResponse = await this.request( `${this.originRepoURL}/pulls/${number}`, { @@ -1304,7 +1301,7 @@ export default class API { } async closePR(number: number) { - console.log('%c Deleting PR', 'line-height: 30px;text-align: center;font-weight: bold'); + console.info('%c Deleting PR', 'line-height: 30px;text-align: center;font-weight: bold'); const result: Octokit.PullsUpdateBranchResponse = await this.request( `${this.originRepoURL}/pulls/${number}`, { @@ -1318,7 +1315,7 @@ export default class API { } async mergePR(pullrequest: GitHubPull) { - console.log('%c Merging PR', 'line-height: 30px;text-align: center;font-weight: bold'); + console.info('%c Merging PR', 'line-height: 30px;text-align: center;font-weight: bold'); try { const result: Octokit.PullsMergeResponse = await this.request( `${this.originRepoURL}/pulls/${pullrequest.number}/merge`, @@ -1349,7 +1346,7 @@ export default class API { files.forEach(file => { commitMessage += `\n* "${file.path}"`; }); - console.log( + console.info( '%c Automatic merge not possible - Forcing merge.', 'line-height: 30px;text-align: center;font-weight: bold', ); diff --git a/packages/netlify-cms-backend-github/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/github/AuthenticationPage.js similarity index 96% rename from packages/netlify-cms-backend-github/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/github/AuthenticationPage.js index 71325520..9f8319a8 100644 --- a/packages/netlify-cms-backend-github/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/github/AuthenticationPage.js @@ -1,8 +1,9 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { NetlifyAuthenticator } from 'netlify-cms-lib-auth'; -import { AuthenticationPage, Icon } from 'netlify-cms-ui-default'; + +import { AuthenticationPage, Icon } from '../../ui'; +import { NetlifyAuthenticator } from '../../lib/auth'; const LoginButtonIcon = styled(Icon)` margin-right: 18px; diff --git a/packages/netlify-cms-backend-github/src/GraphQLAPI.ts b/packages/netlify-cms-core/src/backends/github/GraphQLAPI.ts similarity index 99% rename from packages/netlify-cms-backend-github/src/GraphQLAPI.ts rename to packages/netlify-cms-core/src/backends/github/GraphQLAPI.ts index 23090dd2..809a4a81 100644 --- a/packages/netlify-cms-backend-github/src/GraphQLAPI.ts +++ b/packages/netlify-cms-core/src/backends/github/GraphQLAPI.ts @@ -6,6 +6,8 @@ import { } from 'apollo-cache-inmemory'; import { createHttpLink } from 'apollo-link-http'; import { setContext } from 'apollo-link-context'; +import { trim, trimStart } from 'lodash'; + import { APIError, readFile, @@ -14,9 +16,7 @@ import { branchFromContentKey, CMS_BRANCH_PREFIX, throwOnConflictingBranches, -} from 'netlify-cms-lib-util'; -import { trim, trimStart } from 'lodash'; - +} from '../../lib/util'; import introspectionQueryResultData from './fragmentTypes'; import API, { API_NAME, PullRequestState, MOCK_PULL_REQUEST } from './API'; import * as queries from './queries'; @@ -152,7 +152,7 @@ export default class GraphQLAPI extends API { try { const result = await this.client.mutate(options); return result; - } catch (error) { + } catch (error: any) { const errors = error.graphQLErrors; if (Array.isArray(errors) && errors.some(e => e.message === 'Ref cannot be created.')) { const refName = options?.variables?.createRefInput?.name || ''; @@ -180,7 +180,7 @@ export default class GraphQLAPI extends API { const result = await this.client.mutate(options); return result; } catch (e) { - console.log(e); + console.error(e); } } } @@ -581,7 +581,7 @@ export default class GraphQLAPI extends API { } else { return await this.deleteBranch(branchName); } - } catch (e) { + } catch (e: any) { const { graphQLErrors } = e; if (graphQLErrors && graphQLErrors.length > 0) { const branchNotFound = graphQLErrors.some((e: Error) => e.type === 'NOT_FOUND'); diff --git a/packages/netlify-cms-core/src/backends/github/fragmentTypes.js b/packages/netlify-cms-core/src/backends/github/fragmentTypes.js new file mode 100644 index 00000000..75d69566 --- /dev/null +++ b/packages/netlify-cms-core/src/backends/github/fragmentTypes.js @@ -0,0 +1,572 @@ +export default { + __schema: { + types: [ + { + kind: 'INTERFACE', + name: 'Node', + possibleTypes: [ + { name: 'AddedToProjectEvent' }, + { name: 'App' }, + { name: 'AssignedEvent' }, + { name: 'BaseRefChangedEvent' }, + { name: 'BaseRefForcePushedEvent' }, + { name: 'Blob' }, + { name: 'Bot' }, + { name: 'BranchProtectionRule' }, + { name: 'ClosedEvent' }, + { name: 'CodeOfConduct' }, + { name: 'CommentDeletedEvent' }, + { name: 'Commit' }, + { name: 'CommitComment' }, + { name: 'CommitCommentThread' }, + { name: 'ConvertedNoteToIssueEvent' }, + { name: 'CrossReferencedEvent' }, + { name: 'DemilestonedEvent' }, + { name: 'DeployKey' }, + { name: 'DeployedEvent' }, + { name: 'Deployment' }, + { name: 'DeploymentEnvironmentChangedEvent' }, + { name: 'DeploymentStatus' }, + { name: 'ExternalIdentity' }, + { name: 'Gist' }, + { name: 'GistComment' }, + { name: 'HeadRefDeletedEvent' }, + { name: 'HeadRefForcePushedEvent' }, + { name: 'HeadRefRestoredEvent' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'Label' }, + { name: 'LabeledEvent' }, + { name: 'Language' }, + { name: 'License' }, + { name: 'LockedEvent' }, + { name: 'Mannequin' }, + { name: 'MarketplaceCategory' }, + { name: 'MarketplaceListing' }, + { name: 'MentionedEvent' }, + { name: 'MergedEvent' }, + { name: 'Milestone' }, + { name: 'MilestonedEvent' }, + { name: 'MovedColumnsInProjectEvent' }, + { name: 'Organization' }, + { name: 'OrganizationIdentityProvider' }, + { name: 'OrganizationInvitation' }, + { name: 'PinnedEvent' }, + { name: 'Project' }, + { name: 'ProjectCard' }, + { name: 'ProjectColumn' }, + { name: 'PublicKey' }, + { name: 'PullRequest' }, + { name: 'PullRequestCommit' }, + { name: 'PullRequestCommitCommentThread' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + { name: 'PullRequestReviewThread' }, + { name: 'PushAllowance' }, + { name: 'Reaction' }, + { name: 'ReadyForReviewEvent' }, + { name: 'Ref' }, + { name: 'ReferencedEvent' }, + { name: 'RegistryPackage' }, + { name: 'RegistryPackageDependency' }, + { name: 'RegistryPackageFile' }, + { name: 'RegistryPackageTag' }, + { name: 'RegistryPackageVersion' }, + { name: 'Release' }, + { name: 'ReleaseAsset' }, + { name: 'RemovedFromProjectEvent' }, + { name: 'RenamedTitleEvent' }, + { name: 'ReopenedEvent' }, + { name: 'Repository' }, + { name: 'RepositoryInvitation' }, + { name: 'RepositoryTopic' }, + { name: 'ReviewDismissalAllowance' }, + { name: 'ReviewDismissedEvent' }, + { name: 'ReviewRequest' }, + { name: 'ReviewRequestRemovedEvent' }, + { name: 'ReviewRequestedEvent' }, + { name: 'SavedReply' }, + { name: 'SecurityAdvisory' }, + { name: 'SponsorsListing' }, + { name: 'Sponsorship' }, + { name: 'Status' }, + { name: 'StatusContext' }, + { name: 'SubscribedEvent' }, + { name: 'Tag' }, + { name: 'Team' }, + { name: 'Topic' }, + { name: 'TransferredEvent' }, + { name: 'Tree' }, + { name: 'UnassignedEvent' }, + { name: 'UnlabeledEvent' }, + { name: 'UnlockedEvent' }, + { name: 'UnpinnedEvent' }, + { name: 'UnsubscribedEvent' }, + { name: 'User' }, + { name: 'UserBlockedEvent' }, + { name: 'UserContentEdit' }, + { name: 'UserStatus' }, + ], + }, + { + kind: 'INTERFACE', + name: 'UniformResourceLocatable', + possibleTypes: [ + { name: 'Bot' }, + { name: 'ClosedEvent' }, + { name: 'Commit' }, + { name: 'CrossReferencedEvent' }, + { name: 'Gist' }, + { name: 'Issue' }, + { name: 'Mannequin' }, + { name: 'MergedEvent' }, + { name: 'Milestone' }, + { name: 'Organization' }, + { name: 'PullRequest' }, + { name: 'PullRequestCommit' }, + { name: 'ReadyForReviewEvent' }, + { name: 'Release' }, + { name: 'Repository' }, + { name: 'RepositoryTopic' }, + { name: 'ReviewDismissedEvent' }, + { name: 'User' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Actor', + possibleTypes: [ + { name: 'Bot' }, + { name: 'Mannequin' }, + { name: 'Organization' }, + { name: 'User' }, + ], + }, + { + kind: 'INTERFACE', + name: 'RegistryPackageOwner', + possibleTypes: [{ name: 'Organization' }, { name: 'Repository' }, { name: 'User' }], + }, + { + kind: 'INTERFACE', + name: 'ProjectOwner', + possibleTypes: [{ name: 'Organization' }, { name: 'Repository' }, { name: 'User' }], + }, + { + kind: 'INTERFACE', + name: 'Closable', + possibleTypes: [ + { name: 'Issue' }, + { name: 'Milestone' }, + { name: 'Project' }, + { name: 'PullRequest' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Updatable', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'GistComment' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'Project' }, + { name: 'PullRequest' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'UNION', + name: 'ProjectCardItem', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'INTERFACE', + name: 'Assignable', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'INTERFACE', + name: 'Comment', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'GistComment' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'PullRequest' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'INTERFACE', + name: 'UpdatableComment', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'GistComment' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'PullRequest' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Labelable', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'INTERFACE', + name: 'Lockable', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'INTERFACE', + name: 'RegistryPackageSearch', + possibleTypes: [{ name: 'Organization' }, { name: 'User' }], + }, + { + kind: 'INTERFACE', + name: 'RepositoryOwner', + possibleTypes: [{ name: 'Organization' }, { name: 'User' }], + }, + { + kind: 'INTERFACE', + name: 'MemberStatusable', + possibleTypes: [{ name: 'Organization' }, { name: 'Team' }], + }, + { + kind: 'INTERFACE', + name: 'ProfileOwner', + possibleTypes: [{ name: 'Organization' }, { name: 'User' }], + }, + { + kind: 'UNION', + name: 'PinnableItem', + possibleTypes: [{ name: 'Gist' }, { name: 'Repository' }], + }, + { + kind: 'INTERFACE', + name: 'Starrable', + possibleTypes: [{ name: 'Gist' }, { name: 'Repository' }, { name: 'Topic' }], + }, + { kind: 'INTERFACE', name: 'RepositoryInfo', possibleTypes: [{ name: 'Repository' }] }, + { + kind: 'INTERFACE', + name: 'GitObject', + possibleTypes: [{ name: 'Blob' }, { name: 'Commit' }, { name: 'Tag' }, { name: 'Tree' }], + }, + { + kind: 'INTERFACE', + name: 'RepositoryNode', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'CommitCommentThread' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'PullRequest' }, + { name: 'PullRequestCommitCommentThread' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Subscribable', + possibleTypes: [ + { name: 'Commit' }, + { name: 'Issue' }, + { name: 'PullRequest' }, + { name: 'Repository' }, + { name: 'Team' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Deletable', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'GistComment' }, + { name: 'IssueComment' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'INTERFACE', + name: 'Reactable', + possibleTypes: [ + { name: 'CommitComment' }, + { name: 'Issue' }, + { name: 'IssueComment' }, + { name: 'PullRequest' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewComment' }, + ], + }, + { + kind: 'INTERFACE', + name: 'GitSignature', + possibleTypes: [ + { name: 'GpgSignature' }, + { name: 'SmimeSignature' }, + { name: 'UnknownSignature' }, + ], + }, + { + kind: 'UNION', + name: 'RequestedReviewer', + possibleTypes: [{ name: 'User' }, { name: 'Team' }, { name: 'Mannequin' }], + }, + { + kind: 'UNION', + name: 'PullRequestTimelineItem', + possibleTypes: [ + { name: 'Commit' }, + { name: 'CommitCommentThread' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewThread' }, + { name: 'PullRequestReviewComment' }, + { name: 'IssueComment' }, + { name: 'ClosedEvent' }, + { name: 'ReopenedEvent' }, + { name: 'SubscribedEvent' }, + { name: 'UnsubscribedEvent' }, + { name: 'MergedEvent' }, + { name: 'ReferencedEvent' }, + { name: 'CrossReferencedEvent' }, + { name: 'AssignedEvent' }, + { name: 'UnassignedEvent' }, + { name: 'LabeledEvent' }, + { name: 'UnlabeledEvent' }, + { name: 'MilestonedEvent' }, + { name: 'DemilestonedEvent' }, + { name: 'RenamedTitleEvent' }, + { name: 'LockedEvent' }, + { name: 'UnlockedEvent' }, + { name: 'DeployedEvent' }, + { name: 'DeploymentEnvironmentChangedEvent' }, + { name: 'HeadRefDeletedEvent' }, + { name: 'HeadRefRestoredEvent' }, + { name: 'HeadRefForcePushedEvent' }, + { name: 'BaseRefForcePushedEvent' }, + { name: 'ReviewRequestedEvent' }, + { name: 'ReviewRequestRemovedEvent' }, + { name: 'ReviewDismissedEvent' }, + { name: 'UserBlockedEvent' }, + ], + }, + { + kind: 'UNION', + name: 'Closer', + possibleTypes: [{ name: 'Commit' }, { name: 'PullRequest' }], + }, + { + kind: 'UNION', + name: 'ReferencedSubject', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'UNION', + name: 'Assignee', + possibleTypes: [ + { name: 'Bot' }, + { name: 'Mannequin' }, + { name: 'Organization' }, + { name: 'User' }, + ], + }, + { + kind: 'UNION', + name: 'MilestoneItem', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'UNION', + name: 'RenamedTitleSubject', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'UNION', + name: 'PullRequestTimelineItems', + possibleTypes: [ + { name: 'PullRequestCommit' }, + { name: 'PullRequestCommitCommentThread' }, + { name: 'PullRequestReview' }, + { name: 'PullRequestReviewThread' }, + { name: 'PullRequestRevisionMarker' }, + { name: 'BaseRefChangedEvent' }, + { name: 'BaseRefForcePushedEvent' }, + { name: 'DeployedEvent' }, + { name: 'DeploymentEnvironmentChangedEvent' }, + { name: 'HeadRefDeletedEvent' }, + { name: 'HeadRefForcePushedEvent' }, + { name: 'HeadRefRestoredEvent' }, + { name: 'MergedEvent' }, + { name: 'ReviewDismissedEvent' }, + { name: 'ReviewRequestedEvent' }, + { name: 'ReviewRequestRemovedEvent' }, + { name: 'ReadyForReviewEvent' }, + { name: 'IssueComment' }, + { name: 'CrossReferencedEvent' }, + { name: 'AddedToProjectEvent' }, + { name: 'AssignedEvent' }, + { name: 'ClosedEvent' }, + { name: 'CommentDeletedEvent' }, + { name: 'ConvertedNoteToIssueEvent' }, + { name: 'DemilestonedEvent' }, + { name: 'LabeledEvent' }, + { name: 'LockedEvent' }, + { name: 'MentionedEvent' }, + { name: 'MilestonedEvent' }, + { name: 'MovedColumnsInProjectEvent' }, + { name: 'PinnedEvent' }, + { name: 'ReferencedEvent' }, + { name: 'RemovedFromProjectEvent' }, + { name: 'RenamedTitleEvent' }, + { name: 'ReopenedEvent' }, + { name: 'SubscribedEvent' }, + { name: 'TransferredEvent' }, + { name: 'UnassignedEvent' }, + { name: 'UnlabeledEvent' }, + { name: 'UnlockedEvent' }, + { name: 'UserBlockedEvent' }, + { name: 'UnpinnedEvent' }, + { name: 'UnsubscribedEvent' }, + ], + }, + { + kind: 'UNION', + name: 'IssueOrPullRequest', + possibleTypes: [{ name: 'Issue' }, { name: 'PullRequest' }], + }, + { + kind: 'UNION', + name: 'IssueTimelineItem', + possibleTypes: [ + { name: 'Commit' }, + { name: 'IssueComment' }, + { name: 'CrossReferencedEvent' }, + { name: 'ClosedEvent' }, + { name: 'ReopenedEvent' }, + { name: 'SubscribedEvent' }, + { name: 'UnsubscribedEvent' }, + { name: 'ReferencedEvent' }, + { name: 'AssignedEvent' }, + { name: 'UnassignedEvent' }, + { name: 'LabeledEvent' }, + { name: 'UnlabeledEvent' }, + { name: 'UserBlockedEvent' }, + { name: 'MilestonedEvent' }, + { name: 'DemilestonedEvent' }, + { name: 'RenamedTitleEvent' }, + { name: 'LockedEvent' }, + { name: 'UnlockedEvent' }, + { name: 'TransferredEvent' }, + ], + }, + { + kind: 'UNION', + name: 'IssueTimelineItems', + possibleTypes: [ + { name: 'IssueComment' }, + { name: 'CrossReferencedEvent' }, + { name: 'AddedToProjectEvent' }, + { name: 'AssignedEvent' }, + { name: 'ClosedEvent' }, + { name: 'CommentDeletedEvent' }, + { name: 'ConvertedNoteToIssueEvent' }, + { name: 'DemilestonedEvent' }, + { name: 'LabeledEvent' }, + { name: 'LockedEvent' }, + { name: 'MentionedEvent' }, + { name: 'MilestonedEvent' }, + { name: 'MovedColumnsInProjectEvent' }, + { name: 'PinnedEvent' }, + { name: 'ReferencedEvent' }, + { name: 'RemovedFromProjectEvent' }, + { name: 'RenamedTitleEvent' }, + { name: 'ReopenedEvent' }, + { name: 'SubscribedEvent' }, + { name: 'TransferredEvent' }, + { name: 'UnassignedEvent' }, + { name: 'UnlabeledEvent' }, + { name: 'UnlockedEvent' }, + { name: 'UserBlockedEvent' }, + { name: 'UnpinnedEvent' }, + { name: 'UnsubscribedEvent' }, + ], + }, + { + kind: 'UNION', + name: 'ReviewDismissalAllowanceActor', + possibleTypes: [{ name: 'User' }, { name: 'Team' }], + }, + { + kind: 'UNION', + name: 'PushAllowanceActor', + possibleTypes: [{ name: 'User' }, { name: 'Team' }], + }, + { + kind: 'UNION', + name: 'PermissionGranter', + possibleTypes: [{ name: 'Organization' }, { name: 'Repository' }, { name: 'Team' }], + }, + { kind: 'INTERFACE', name: 'Sponsorable', possibleTypes: [{ name: 'User' }] }, + { + kind: 'INTERFACE', + name: 'Contribution', + possibleTypes: [ + { name: 'CreatedCommitContribution' }, + { name: 'CreatedIssueContribution' }, + { name: 'CreatedPullRequestContribution' }, + { name: 'CreatedPullRequestReviewContribution' }, + { name: 'CreatedRepositoryContribution' }, + { name: 'JoinedGitHubContribution' }, + { name: 'RestrictedContribution' }, + ], + }, + { + kind: 'UNION', + name: 'CreatedRepositoryOrRestrictedContribution', + possibleTypes: [ + { name: 'CreatedRepositoryContribution' }, + { name: 'RestrictedContribution' }, + ], + }, + { + kind: 'UNION', + name: 'CreatedIssueOrRestrictedContribution', + possibleTypes: [{ name: 'CreatedIssueContribution' }, { name: 'RestrictedContribution' }], + }, + { + kind: 'UNION', + name: 'CreatedPullRequestOrRestrictedContribution', + possibleTypes: [ + { name: 'CreatedPullRequestContribution' }, + { name: 'RestrictedContribution' }, + ], + }, + { + kind: 'UNION', + name: 'SearchResultItem', + possibleTypes: [ + { name: 'Issue' }, + { name: 'PullRequest' }, + { name: 'Repository' }, + { name: 'User' }, + { name: 'Organization' }, + { name: 'MarketplaceListing' }, + { name: 'App' }, + ], + }, + { + kind: 'UNION', + name: 'CollectionItemContent', + possibleTypes: [{ name: 'Repository' }, { name: 'Organization' }, { name: 'User' }], + }, + ], + }, +}; diff --git a/packages/netlify-cms-backend-github/src/fragments.ts b/packages/netlify-cms-core/src/backends/github/fragments.ts similarity index 100% rename from packages/netlify-cms-backend-github/src/fragments.ts rename to packages/netlify-cms-core/src/backends/github/fragments.ts diff --git a/packages/netlify-cms-backend-github/src/implementation.tsx b/packages/netlify-cms-core/src/backends/github/implementation.tsx similarity index 99% rename from packages/netlify-cms-backend-github/src/implementation.tsx rename to packages/netlify-cms-core/src/backends/github/implementation.tsx index 4b4e1b3c..a7d5a490 100644 --- a/packages/netlify-cms-backend-github/src/implementation.tsx +++ b/packages/netlify-cms-core/src/backends/github/implementation.tsx @@ -2,6 +2,7 @@ import * as React from 'react'; import semaphore from 'semaphore'; import trimStart from 'lodash/trimStart'; import { stripIndent } from 'common-tags'; + import { CURSOR_COMPATIBILITY_SYMBOL, Cursor, @@ -20,8 +21,7 @@ import { contentKeyFromBranch, unsentRequest, branchFromContentKey, -} from 'netlify-cms-lib-util'; - +} from '../../lib/util'; import AuthenticationPage from './AuthenticationPage'; import API, { API_NAME } from './API'; import GraphQLAPI from './GraphQLAPI'; @@ -39,7 +39,7 @@ import type { ImplementationFile, UnpublishedEntryMediaFile, Entry, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; import type { Semaphore } from 'semaphore'; type GitHubUser = Octokit.UsersGetAuthenticatedResponse; @@ -190,7 +190,7 @@ export default class GitHub implements Implementation { .then(() => true) .catch(err => { if (err && err.status === 404) { - console.log('This 404 was expected and handled appropriately.'); + console.info('This 404 was expected and handled appropriately.'); return false; } else { return Promise.reject(err); @@ -495,7 +495,7 @@ export default class GitHub implements Implementation { try { await this.api!.persistFiles([], [mediaFile], options); const { sha, path, fileObj } = mediaFile as AssetProxy & { sha: string }; - const displayURL = URL.createObjectURL(fileObj); + const displayURL = URL.createObjectURL(fileObj as Blob); return { id: sha, name: fileObj!.name, diff --git a/packages/netlify-cms-backend-github/src/index.ts b/packages/netlify-cms-core/src/backends/github/index.ts similarity index 100% rename from packages/netlify-cms-backend-github/src/index.ts rename to packages/netlify-cms-core/src/backends/github/index.ts diff --git a/packages/netlify-cms-backend-github/src/mutations.ts b/packages/netlify-cms-core/src/backends/github/mutations.ts similarity index 100% rename from packages/netlify-cms-backend-github/src/mutations.ts rename to packages/netlify-cms-core/src/backends/github/mutations.ts diff --git a/packages/netlify-cms-backend-github/src/queries.ts b/packages/netlify-cms-core/src/backends/github/queries.ts similarity index 100% rename from packages/netlify-cms-backend-github/src/queries.ts rename to packages/netlify-cms-core/src/backends/github/queries.ts diff --git a/packages/netlify-cms-backend-github/scripts/createFragmentTypes.js b/packages/netlify-cms-core/src/backends/github/scripts/createFragmentTypes.js similarity index 94% rename from packages/netlify-cms-backend-github/scripts/createFragmentTypes.js rename to packages/netlify-cms-core/src/backends/github/scripts/createFragmentTypes.js index c60835a9..03b31887 100644 --- a/packages/netlify-cms-backend-github/scripts/createFragmentTypes.js +++ b/packages/netlify-cms-core/src/backends/github/scripts/createFragmentTypes.js @@ -41,7 +41,7 @@ fetch(`${API_HOST}/graphql`, { if (err) { console.error('Error writing fragmentTypes file', err); } else { - console.log('Fragment types successfully extracted!'); + console.info('Fragment types successfully extracted!'); } }, ); diff --git a/packages/netlify-cms-backend-github/src/types/semaphore.d.ts b/packages/netlify-cms-core/src/backends/github/types/semaphore.d.ts similarity index 100% rename from packages/netlify-cms-backend-github/src/types/semaphore.d.ts rename to packages/netlify-cms-core/src/backends/github/types/semaphore.d.ts diff --git a/packages/netlify-cms-backend-gitlab/src/API.ts b/packages/netlify-cms-core/src/backends/gitlab/API.ts similarity index 99% rename from packages/netlify-cms-backend-gitlab/src/API.ts rename to packages/netlify-cms-core/src/backends/gitlab/API.ts index 8dc88f8d..cab40c4f 100644 --- a/packages/netlify-cms-backend-gitlab/src/API.ts +++ b/packages/netlify-cms-core/src/backends/gitlab/API.ts @@ -2,6 +2,13 @@ import { ApolloClient } from 'apollo-client'; import { InMemoryCache } from 'apollo-cache-inmemory'; import { createHttpLink } from 'apollo-link-http'; import { setContext } from 'apollo-link-context'; +import { Base64 } from 'js-base64'; +import { Map } from 'immutable'; +import { flow, partial, result, trimStart } from 'lodash'; +import { dirname } from 'path'; + +const NO_CACHE = 'no-cache'; +import * as queries from './queries'; import { localForage, parseLinkHeader, @@ -25,14 +32,7 @@ import { requestWithBackoff, readFileMetadata, throwOnConflictingBranches, -} from 'netlify-cms-lib-util'; -import { Base64 } from 'js-base64'; -import { Map } from 'immutable'; -import { flow, partial, result, trimStart } from 'lodash'; -import { dirname } from 'path'; - -const NO_CACHE = 'no-cache'; -import * as queries from './queries'; +} from '../../lib/util'; import type { ApolloQueryResult } from 'apollo-client'; import type { NormalizedCacheObject } from 'apollo-cache-inmemory'; @@ -43,7 +43,7 @@ import type { PersistOptions, FetchError, ImplementationFile, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; export const API_NAME = 'GitLab'; @@ -288,7 +288,7 @@ export default class API { request = async (req: ApiRequest): Promise => { try { return requestWithBackoff(this, req); - } catch (err) { + } catch (err: any) { throw new APIError(err.message, null, API_NAME); } }; @@ -333,7 +333,7 @@ export default class API { return true; } } catch (e) { - console.log('Failed getting default branch', e); + console.error('Failed getting default branch', e); } } } @@ -607,7 +607,7 @@ export default class API { body: JSON.stringify(commitParams), }); return result; - } catch (error) { + } catch (error: any) { const message = error.message || ''; if (newBranch && message.includes(`Could not update ${branch}`)) { await throwOnConflictingBranches(branch, name => this.getBranch(name), API_NAME); @@ -710,7 +710,7 @@ export default class API { } async listUnpublishedBranches() { - console.log( + console.info( '%c Checking for Unpublished entries', 'line-height: 30px;text-align: center;font-weight: bold', ); diff --git a/packages/netlify-cms-backend-gitlab/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/gitlab/AuthenticationPage.js similarity index 96% rename from packages/netlify-cms-backend-gitlab/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/gitlab/AuthenticationPage.js index ff41ef76..c859fbca 100644 --- a/packages/netlify-cms-backend-gitlab/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/gitlab/AuthenticationPage.js @@ -1,12 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; + +import { AuthenticationPage, Icon } from '../../ui'; import { NetlifyAuthenticator, ImplicitAuthenticator, PkceAuthenticator, -} from 'netlify-cms-lib-auth'; -import { AuthenticationPage, Icon } from 'netlify-cms-ui-default'; +} from '../../lib/auth'; const LoginButtonIcon = styled(Icon)` margin-right: 18px; diff --git a/packages/netlify-cms-backend-gitlab/src/implementation.ts b/packages/netlify-cms-core/src/backends/gitlab/implementation.ts similarity index 99% rename from packages/netlify-cms-backend-gitlab/src/implementation.ts rename to packages/netlify-cms-core/src/backends/gitlab/implementation.ts index bf9df133..74feec41 100644 --- a/packages/netlify-cms-backend-gitlab/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/gitlab/implementation.ts @@ -2,6 +2,7 @@ import trimStart from 'lodash/trimStart'; import semaphore from 'semaphore'; import { trim } from 'lodash'; import { stripIndent } from 'common-tags'; + import { CURSOR_COMPATIBILITY_SYMBOL, basename, @@ -21,8 +22,7 @@ import { allEntriesByFolder, filterByExtension, branchFromContentKey, -} from 'netlify-cms-lib-util'; - +} from '../../lib/util'; import AuthenticationPage from './AuthenticationPage'; import API, { API_NAME } from './API'; @@ -39,7 +39,7 @@ import type { ImplementationFile, UnpublishedEntryMediaFile, AsyncLock, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; import type { Semaphore } from 'semaphore'; const MAX_CONCURRENT_DOWNLOADS = 10; diff --git a/packages/netlify-cms-backend-gitlab/src/index.ts b/packages/netlify-cms-core/src/backends/gitlab/index.ts similarity index 100% rename from packages/netlify-cms-backend-gitlab/src/index.ts rename to packages/netlify-cms-core/src/backends/gitlab/index.ts diff --git a/packages/netlify-cms-backend-gitlab/src/queries.ts b/packages/netlify-cms-core/src/backends/gitlab/queries.ts similarity index 100% rename from packages/netlify-cms-backend-gitlab/src/queries.ts rename to packages/netlify-cms-core/src/backends/gitlab/queries.ts diff --git a/packages/netlify-cms-core/src/backends/index.tsx b/packages/netlify-cms-core/src/backends/index.tsx new file mode 100644 index 00000000..8d56e340 --- /dev/null +++ b/packages/netlify-cms-core/src/backends/index.tsx @@ -0,0 +1,17 @@ +import { AzureBackend } from './azure'; +import { BitbucketBackend } from './bitbucket'; +import { GitGatewayBackend } from './git-gateway'; +import { GitHubBackend } from './github'; +import { GitLabBackend } from './gitlab'; +import { ProxyBackend } from './proxy'; +import { TestBackend } from './test'; + +export { + AzureBackend, + BitbucketBackend, + GitGatewayBackend, + GitHubBackend, + GitLabBackend, + ProxyBackend, + TestBackend, +}; diff --git a/packages/netlify-cms-backend-proxy/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/proxy/AuthenticationPage.js similarity index 94% rename from packages/netlify-cms-backend-proxy/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/proxy/AuthenticationPage.js index e4fdfb35..c3a8a38c 100644 --- a/packages/netlify-cms-backend-proxy/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/proxy/AuthenticationPage.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { Icon, buttons, shadows, GoBackButton } from 'netlify-cms-ui-default'; + +import { Icon, buttons, shadows, GoBackButton } from '../../ui'; const StyledAuthenticationPage = styled.section` display: flex; diff --git a/packages/netlify-cms-backend-proxy/src/implementation.ts b/packages/netlify-cms-core/src/backends/proxy/implementation.ts similarity index 98% rename from packages/netlify-cms-backend-proxy/src/implementation.ts rename to packages/netlify-cms-core/src/backends/proxy/implementation.ts index 53b9e9cb..534e1579 100644 --- a/packages/netlify-cms-backend-proxy/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/proxy/implementation.ts @@ -3,8 +3,7 @@ import { APIError, unsentRequest, blobToFileObj, -} from 'netlify-cms-lib-util'; - +} from '../../lib/util'; import AuthenticationPage from './AuthenticationPage'; import type { @@ -16,7 +15,7 @@ import type { Implementation, ImplementationFile, UnpublishedEntry, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; async function serializeAsset(assetProxy: AssetProxy) { const base64content = await assetProxy.toBase64!(); @@ -155,7 +154,7 @@ export default class ProxyBackend implements Implementation { }); return entry; - } catch (e) { + } catch (e: any) { if (e.status === 404) { throw new EditorialWorkflowError('content is not under editorial workflow', true); } diff --git a/packages/netlify-cms-backend-proxy/src/index.ts b/packages/netlify-cms-core/src/backends/proxy/index.ts similarity index 100% rename from packages/netlify-cms-backend-proxy/src/index.ts rename to packages/netlify-cms-core/src/backends/proxy/index.ts diff --git a/packages/netlify-cms-backend-test/src/AuthenticationPage.js b/packages/netlify-cms-core/src/backends/test/AuthenticationPage.js similarity index 95% rename from packages/netlify-cms-backend-test/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/backends/test/AuthenticationPage.js index e61dc987..272c353f 100644 --- a/packages/netlify-cms-backend-test/src/AuthenticationPage.js +++ b/packages/netlify-cms-core/src/backends/test/AuthenticationPage.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { Icon, buttons, shadows, GoBackButton } from 'netlify-cms-ui-default'; + +import { Icon, buttons, shadows, GoBackButton } from '../../ui'; const StyledAuthenticationPage = styled.section` display: flex; diff --git a/packages/netlify-cms-backend-test/src/implementation.ts b/packages/netlify-cms-core/src/backends/test/implementation.ts similarity index 99% rename from packages/netlify-cms-backend-test/src/implementation.ts rename to packages/netlify-cms-core/src/backends/test/implementation.ts index fd5df865..9dc00491 100644 --- a/packages/netlify-cms-backend-test/src/implementation.ts +++ b/packages/netlify-cms-core/src/backends/test/implementation.ts @@ -1,13 +1,13 @@ import { attempt, isError, take, unset, isEmpty } from 'lodash'; import uuid from 'uuid/v4'; +import { extname, dirname } from 'path'; + import { EditorialWorkflowError, Cursor, CURSOR_COMPATIBILITY_SYMBOL, basename, -} from 'netlify-cms-lib-util'; -import { extname, dirname } from 'path'; - +} from '../../lib/util'; import AuthenticationPage from './AuthenticationPage'; import type { @@ -20,7 +20,7 @@ import type { Config, ImplementationFile, DataFile, -} from 'netlify-cms-lib-util'; +} from '../../lib/util'; type RepoFile = { path: string; content: string | AssetProxy }; type RepoTree = { [key: string]: RepoFile | RepoTree }; diff --git a/packages/netlify-cms-backend-test/src/index.ts b/packages/netlify-cms-core/src/backends/test/index.ts similarity index 100% rename from packages/netlify-cms-backend-test/src/index.ts rename to packages/netlify-cms-core/src/backends/test/index.ts diff --git a/packages/netlify-cms-core/src/bootstrap.js b/packages/netlify-cms-core/src/bootstrap.js index fca6eb2d..9f5311ef 100644 --- a/packages/netlify-cms-core/src/bootstrap.js +++ b/packages/netlify-cms-core/src/bootstrap.js @@ -1,11 +1,11 @@ import React from 'react'; import { render } from 'react-dom'; import { Provider, connect } from 'react-redux'; -import { Route, Router } from 'react-router-dom'; +import { Router } from 'react-router-dom'; import { I18n } from 'react-polyglot'; -import { GlobalStyles } from 'netlify-cms-ui-default'; -import { store } from './redux'; +import { GlobalStyles } from './ui'; +import { store } from './store'; import { history } from './routing/history'; import { loadConfig } from './actions/config'; import { authenticateUser } from './actions/auth'; @@ -24,7 +24,7 @@ function TranslatedApp({ locale, config }) { - + @@ -44,7 +44,7 @@ function bootstrap(opts = {}) { * Log the version number. */ if (typeof NETLIFY_CMS_CORE_VERSION === 'string') { - console.log(`netlify-cms-core ${NETLIFY_CMS_CORE_VERSION}`); + console.info(`netlify-cms-core ${NETLIFY_CMS_CORE_VERSION}`); } /** diff --git a/packages/netlify-cms-core/src/components/App/App.js b/packages/netlify-cms-core/src/components/App/App.js index fd01bc11..72e63c36 100644 --- a/packages/netlify-cms-core/src/components/App/App.js +++ b/packages/netlify-cms-core/src/components/App/App.js @@ -1,29 +1,31 @@ +import styled from '@emotion/styled'; import PropTypes from 'prop-types'; import React from 'react'; import { hot } from 'react-hot-loader'; -import { translate } from 'react-polyglot'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import styled from '@emotion/styled'; +import { translate } from 'react-polyglot'; import { connect } from 'react-redux'; -import { Route, Switch, Redirect } from 'react-router-dom'; -import { Notifs } from 'redux-notifications'; -import TopBarProgress from 'react-topbar-progress-indicator'; -import { Loader, colors } from 'netlify-cms-ui-default'; +import { Redirect, Route, Switch } from 'react-router-dom'; import { ScrollSync } from 'react-scroll-sync'; +import TopBarProgress from 'react-topbar-progress-indicator'; import { loginUser, logoutUser } from '../../actions/auth'; -import { currentBackend } from '../../backend'; import { createNewEntry } from '../../actions/collections'; import { openMediaLibrary } from '../../actions/mediaLibrary'; -import MediaLibrary from '../MediaLibrary/MediaLibrary'; -import { Toast } from '../UI'; +import { currentBackend } from '../../backend'; +import { EDITORIAL_WORKFLOW, SIMPLE } from '../../constants/publishModes'; import { history } from '../../routing/history'; -import { SIMPLE, EDITORIAL_WORKFLOW } from '../../constants/publishModes'; +import { colors, Loader } from '../../ui'; import Collection from '../Collection/Collection'; -import Workflow from '../Workflow/Workflow'; import Editor from '../Editor/Editor'; -import NotFoundPage from './NotFoundPage'; +import MediaLibrary from '../MediaLibrary/MediaLibrary'; +import Page from '../page/Page'; +import Snackbars from '../snackbar/Snackbars'; +import { Alert } from '../UI/Alert'; +import { Confirm } from '../UI/Confirm'; +import Workflow from '../Workflow/Workflow'; import Header from './Header'; +import NotFoundPage from './NotFoundPage'; TopBarProgress.config({ barColors: { @@ -39,7 +41,7 @@ const AppRoot = styled.div` min-width: 1200px; height: 100vh; position: relative; - overflow: hidden; + overflow-y: auto; `; const AppWrapper = styled.div` @@ -65,7 +67,13 @@ const ErrorCodeBlock = styled.pre` `; function getDefaultPath(collections) { - const first = collections.filter(collection => collection.get('hide') !== true && (!collection.has('files') || collection.get('files').size > 1)).first(); + const first = collections + .filter( + collection => + collection.get('hide') !== true && + (!collection.has('files') || collection.get('files').size > 1), + ) + .first(); if (first) { return `/collections/${first.get('name')}`; } else { @@ -175,7 +183,6 @@ class App extends React.Component { return (
- {React.createElement(backend.authComponent(), { onLogin: this.handleLogin.bind(this), error: auth.error, @@ -234,7 +241,7 @@ class App extends React.Component { - +
; }} /> + } /> {useMediaLibrary ? : null} + + diff --git a/packages/netlify-cms-core/src/components/App/Header.js b/packages/netlify-cms-core/src/components/App/Header.js index 3ee8c74b..75262b39 100644 --- a/packages/netlify-cms-core/src/components/App/Header.js +++ b/packages/netlify-cms-core/src/components/App/Header.js @@ -5,6 +5,8 @@ import styled from '@emotion/styled'; import { css } from '@emotion/react'; import { translate } from 'react-polyglot'; import { NavLink } from 'react-router-dom'; +import { connect } from 'react-redux'; + import { Icon, Dropdown, @@ -15,9 +17,7 @@ import { shadows, buttons, zIndex, -} from 'netlify-cms-ui-default'; -import { connect } from 'react-redux'; - +} from '../../ui'; import { SettingsDropdown } from '../UI'; import { checkBackendStatus } from '../../actions/status'; diff --git a/packages/netlify-cms-core/src/components/App/NotFoundPage.js b/packages/netlify-cms-core/src/components/App/NotFoundPage.js index ff93df34..92c571b6 100644 --- a/packages/netlify-cms-core/src/components/App/NotFoundPage.js +++ b/packages/netlify-cms-core/src/components/App/NotFoundPage.js @@ -1,9 +1,10 @@ import React from 'react'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; -import { lengths } from 'netlify-cms-ui-default'; import PropTypes from 'prop-types'; +import { lengths } from '../../ui'; + const NotFoundContainer = styled.div` margin: ${lengths.pageMargin}; `; diff --git a/packages/netlify-cms-core/src/components/Collection/Collection.js b/packages/netlify-cms-core/src/components/Collection/Collection.js deleted file mode 100644 index f0edb0a1..00000000 --- a/packages/netlify-cms-core/src/components/Collection/Collection.js +++ /dev/null @@ -1,205 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import styled from '@emotion/styled'; -import { connect } from 'react-redux'; -import { translate } from 'react-polyglot'; -import { lengths, components } from 'netlify-cms-ui-default'; - -import { getNewEntryUrl } from '../../lib/urlHelper'; -import Sidebar from './Sidebar'; -import CollectionTop from './CollectionTop'; -import EntriesCollection from './Entries/EntriesCollection'; -import EntriesSearch from './Entries/EntriesSearch'; -import CollectionControls from './CollectionControls'; -import { sortByField, filterByField, changeViewStyle, groupByField } from '../../actions/entries'; -import { - selectSortableFields, - selectViewFilters, - selectViewGroups, -} from '../../reducers/collections'; -import { - selectEntriesSort, - selectEntriesFilter, - selectEntriesGroup, - selectViewStyle, -} from '../../reducers/entries'; - -const CollectionContainer = styled.div` - margin: ${lengths.pageMargin}; -`; - -const CollectionMain = styled.main` - padding-left: 280px; -`; - -const SearchResultContainer = styled.div` - ${components.cardTop}; - margin-bottom: 22px; -`; - -const SearchResultHeading = styled.h1` - ${components.cardTopHeading}; -`; - -export class Collection extends React.Component { - static propTypes = { - searchTerm: PropTypes.string, - collectionName: PropTypes.string, - isSearchResults: PropTypes.bool, - isSingleSearchResult: PropTypes.bool, - collection: ImmutablePropTypes.map.isRequired, - collections: ImmutablePropTypes.map.isRequired, - sortableFields: PropTypes.array, - sort: ImmutablePropTypes.orderedMap, - onSortClick: PropTypes.func.isRequired, - }; - - renderEntriesCollection = () => { - const { collection, filterTerm, viewStyle } = this.props; - return ( - - ); - }; - - renderEntriesSearch = () => { - const { searchTerm, collections, collection, isSingleSearchResult } = this.props; - return ( - c === collection) : collections} - searchTerm={searchTerm} - /> - ); - }; - - render() { - const { - collection, - collections, - collectionName, - isSearchEnabled, - isSearchResults, - isSingleSearchResult, - searchTerm, - sortableFields, - onSortClick, - sort, - viewFilters, - viewGroups, - filterTerm, - t, - onFilterClick, - onGroupClick, - filter, - group, - onChangeViewStyle, - viewStyle, - } = this.props; - - let newEntryUrl = collection.get('create') ? getNewEntryUrl(collectionName) : ''; - if (newEntryUrl && filterTerm) { - newEntryUrl = getNewEntryUrl(collectionName); - if (filterTerm) { - newEntryUrl = `${newEntryUrl}?path=${filterTerm}`; - } - } - - const searchResultKey = - 'collection.collectionTop.searchResults' + (isSingleSearchResult ? 'InCollection' : ''); - - return ( - - - - {isSearchResults ? ( - - - {t(searchResultKey, { searchTerm, collection: collection.get('label') })} - - - ) : ( - <> - - - - )} - {isSearchResults ? this.renderEntriesSearch() : this.renderEntriesCollection()} - - - ); - } -} - -function mapStateToProps(state, ownProps) { - const { collections } = state; - const isSearchEnabled = state.config && state.config.search != false; - const { isSearchResults, match, t } = ownProps; - const { name, searchTerm = '', filterTerm = '' } = match.params; - const collection = name ? collections.get(name) : collections.first(); - const sort = selectEntriesSort(state.entries, collection.get('name')); - const sortableFields = selectSortableFields(collection, t); - const viewFilters = selectViewFilters(collection); - const viewGroups = selectViewGroups(collection); - const filter = selectEntriesFilter(state.entries, collection.get('name')); - const group = selectEntriesGroup(state.entries, collection.get('name')); - const viewStyle = selectViewStyle(state.entries); - - return { - collection, - collections, - collectionName: name, - isSearchEnabled, - isSearchResults, - searchTerm, - filterTerm, - sort, - sortableFields, - viewFilters, - viewGroups, - filter, - group, - viewStyle, - }; -} - -const mapDispatchToProps = { - sortByField, - filterByField, - changeViewStyle, - groupByField, -}; - -function mergeProps(stateProps, dispatchProps, ownProps) { - return { - ...stateProps, - ...ownProps, - onSortClick: (key, direction) => - dispatchProps.sortByField(stateProps.collection, key, direction), - onFilterClick: filter => dispatchProps.filterByField(stateProps.collection, filter), - onGroupClick: group => dispatchProps.groupByField(stateProps.collection, group), - onChangeViewStyle: viewStyle => dispatchProps.changeViewStyle(viewStyle), - }; -} - -const ConnectedCollection = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Collection); - -export default translate()(ConnectedCollection); diff --git a/packages/netlify-cms-core/src/components/Collection/Collection.tsx b/packages/netlify-cms-core/src/components/Collection/Collection.tsx new file mode 100644 index 00000000..73efaec1 --- /dev/null +++ b/packages/netlify-cms-core/src/components/Collection/Collection.tsx @@ -0,0 +1,236 @@ +import styled from '@emotion/styled'; +import React, { useCallback, useEffect, useMemo } from 'react'; +import { translate } from 'react-polyglot'; +import { connect } from 'react-redux'; + +import { changeViewStyle, filterByField, groupByField, sortByField } from '../../actions/entries'; +import { SortDirection } from '../../interface'; +import { getNewEntryUrl } from '../../lib/urlHelper'; +import { + selectSortableFields, + selectViewFilters, + selectViewGroups, +} from '../../reducers/collections'; +import { + selectEntriesFilter, + selectEntriesGroup, + selectEntriesSort, + selectViewStyle, +} from '../../reducers/entries'; +import { components, lengths } from '../../ui'; +import CollectionControls from './CollectionControls'; +import CollectionTop from './CollectionTop'; +import EntriesCollection from './Entries/EntriesCollection'; +import EntriesSearch from './Entries/EntriesSearch'; +import Sidebar from './Sidebar'; + +import type { RouteComponentProps } from 'react-router-dom'; +import type { + CmsSortableFieldsDefault, + TranslatedProps, + ViewFilter, + ViewGroup, +} from '../../interface'; +import type { Collection, State } from '../../types/redux'; +import type { StaticallyTypedRecord } from '../../types/immutable'; + +const CollectionContainer = styled.div` + margin: ${lengths.pageMargin}; +`; + +const CollectionMain = styled.main` + padding-left: 280px; +`; + +const SearchResultContainer = styled.div` + ${components.cardTop}; + margin-bottom: 22px; +`; + +const SearchResultHeading = styled.h1` + ${components.cardTopHeading}; +`; + +interface CollectionRouterParams { + name: string; + searchTerm?: string; + filterTerm?: string; +} + +interface CollectionViewProps extends RouteComponentProps { + isSearchResults?: boolean; + isSingleSearchResult?: boolean; +} + +const CollectionView = ({ + collection, + collections, + collectionName, + isSearchEnabled, + isSearchResults, + isSingleSearchResult, + searchTerm, + sortableFields, + onSortClick, + sort, + viewFilters, + viewGroups, + filterTerm, + t, + onFilterClick, + onGroupClick, + filter, + group, + onChangeViewStyle, + viewStyle, +}: ReturnType) => { + const newEntryUrl = useMemo(() => { + let url = collection.get('create') ? getNewEntryUrl(collectionName) : ''; + if (url && filterTerm) { + url = getNewEntryUrl(collectionName); + if (filterTerm) { + url = `${newEntryUrl}?path=${filterTerm}`; + } + } + }, [collection, collectionName, filterTerm]); + + const searchResultKey = useMemo( + () => `collection.collectionTop.searchResults${isSingleSearchResult ? 'InCollection' : ''}`, + [isSingleSearchResult], + ); + + const renderEntriesCollection = useCallback(() => { + return ( + + ); + }, [collection, filterTerm, viewStyle]); + + const renderEntriesSearch = useCallback(() => { + return ( + c === collection) : collections} + searchTerm={searchTerm} + /> + ); + }, [searchTerm, collections, collection, isSingleSearchResult]); + + useEffect(() => { + if (sort?.first()?.get('key')) { + return; + } + + const defaultSort = collection.getIn(['sortable_fields', 'default']) as + | StaticallyTypedRecord + | undefined; + + if (!defaultSort || !defaultSort.get('field')) { + return; + } + + onSortClick(defaultSort.get('field'), defaultSort.get('direction') ?? SortDirection.Ascending); + }, [collection]); + + return ( + + + + {isSearchResults ? ( + + + {t(searchResultKey, { searchTerm, collection: collection.get('label') })} + + + ) : ( + <> + + + + )} + {isSearchResults ? renderEntriesSearch() : renderEntriesCollection()} + + + ); +}; + +function mapStateToProps(state: State, ownProps: TranslatedProps) { + const { collections } = state; + const isSearchEnabled = state.config && state.config.search != false; + const { isSearchResults, match, t } = ownProps; + const { name, searchTerm = '', filterTerm = '' } = match.params; + const collection: Collection = name ? collections.get(name) : collections.first(); + const sort = selectEntriesSort(state.entries, collection.get('name')); + const sortableFields = selectSortableFields(collection, t); + const viewFilters = selectViewFilters(collection); + const viewGroups = selectViewGroups(collection); + const filter = selectEntriesFilter(state.entries, collection.get('name')); + const group = selectEntriesGroup(state.entries, collection.get('name')); + const viewStyle = selectViewStyle(state.entries); + + return { + collection, + collections, + collectionName: name, + isSearchEnabled, + isSearchResults, + searchTerm, + filterTerm, + sort, + sortableFields, + viewFilters, + viewGroups, + filter, + group, + viewStyle, + }; +} + +const mapDispatchToProps = { + sortByField, + filterByField, + changeViewStyle, + groupByField, +}; + +function mergeProps( + stateProps: ReturnType, + dispatchProps: typeof mapDispatchToProps, + ownProps: TranslatedProps, +) { + return { + ...stateProps, + ...ownProps, + onSortClick: (key: string, direction: SortDirection) => + dispatchProps.sortByField(stateProps.collection, key, direction), + onFilterClick: (filter: ViewFilter) => + dispatchProps.filterByField(stateProps.collection, filter), + onGroupClick: (group: ViewGroup) => dispatchProps.groupByField(stateProps.collection, group), + onChangeViewStyle: (viewStyle: string) => dispatchProps.changeViewStyle(viewStyle), + }; +} + +const ConnectedCollection = connect( + mapStateToProps, + mapDispatchToProps, + mergeProps, +)(CollectionView); + +export default translate()(ConnectedCollection); diff --git a/packages/netlify-cms-core/src/components/Collection/CollectionControls.js b/packages/netlify-cms-core/src/components/Collection/CollectionControls.js index a301ab34..f21deeb7 100644 --- a/packages/netlify-cms-core/src/components/Collection/CollectionControls.js +++ b/packages/netlify-cms-core/src/components/Collection/CollectionControls.js @@ -1,7 +1,7 @@ import React from 'react'; import styled from '@emotion/styled'; -import { lengths } from 'netlify-cms-ui-default'; +import { lengths } from '../../ui'; import ViewStyleControl from './ViewStyleControl'; import SortControl from './SortControl'; import FilterControl from './FilterControl'; diff --git a/packages/netlify-cms-core/src/components/Collection/CollectionSearch.js b/packages/netlify-cms-core/src/components/Collection/CollectionSearch.js index 956498d0..383fe0ca 100644 --- a/packages/netlify-cms-core/src/components/Collection/CollectionSearch.js +++ b/packages/netlify-cms-core/src/components/Collection/CollectionSearch.js @@ -1,10 +1,11 @@ import React from 'react'; import styled from '@emotion/styled'; -import { colorsRaw, colors, Icon, lengths, zIndex } from 'netlify-cms-ui-default'; import { translate } from 'react-polyglot'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; +import { colorsRaw, colors, Icon, lengths, zIndex } from '../../ui'; + const SearchContainer = styled.div` margin: 0 12px; position: relative; diff --git a/packages/netlify-cms-core/src/components/Collection/CollectionTop.js b/packages/netlify-cms-core/src/components/Collection/CollectionTop.js index 5d5a8c3b..1028d7c0 100644 --- a/packages/netlify-cms-core/src/components/Collection/CollectionTop.js +++ b/packages/netlify-cms-core/src/components/Collection/CollectionTop.js @@ -4,7 +4,8 @@ import React from 'react'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; import { Link } from 'react-router-dom'; -import { components, buttons, shadows } from 'netlify-cms-ui-default'; + +import { components, buttons, shadows } from '../../ui'; const CollectionTopContainer = styled.div` ${components.cardTop}; diff --git a/packages/netlify-cms-core/src/components/Collection/ControlButton.js b/packages/netlify-cms-core/src/components/Collection/ControlButton.js index 679e7be5..7c19a2fe 100644 --- a/packages/netlify-cms-core/src/components/Collection/ControlButton.js +++ b/packages/netlify-cms-core/src/components/Collection/ControlButton.js @@ -1,7 +1,8 @@ import React from 'react'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; -import { buttons, StyledDropdownButton, colors } from 'netlify-cms-ui-default'; + +import { buttons, StyledDropdownButton, colors } from '../../ui'; const Button = styled(StyledDropdownButton)` ${buttons.button}; diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/Entries.js b/packages/netlify-cms-core/src/components/Collection/Entries/Entries.js index aba9f0e1..8f7e6224 100644 --- a/packages/netlify-cms-core/src/components/Collection/Entries/Entries.js +++ b/packages/netlify-cms-core/src/components/Collection/Entries/Entries.js @@ -3,8 +3,8 @@ import React from 'react'; import styled from '@emotion/styled'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { translate } from 'react-polyglot'; -import { Loader, lengths } from 'netlify-cms-ui-default'; +import { Loader, lengths } from '../../../ui'; import EntryListing from './EntryListing'; const PaginationMessage = styled.div` diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/EntriesCollection.js b/packages/netlify-cms-core/src/components/Collection/Entries/EntriesCollection.js index ccc74094..f8b4f9b0 100644 --- a/packages/netlify-cms-core/src/components/Collection/Entries/EntriesCollection.js +++ b/packages/netlify-cms-core/src/components/Collection/Entries/EntriesCollection.js @@ -5,9 +5,9 @@ import { connect } from 'react-redux'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; import { partial } from 'lodash'; -import { Cursor } from 'netlify-cms-lib-util'; -import { colors } from 'netlify-cms-ui-default'; +import { colors } from '../../../ui'; +import { Cursor } from '../../../lib/util'; import { loadEntries as actionLoadEntries, traverseCollectionCursor as actionTraverseCollectionCursor, @@ -56,7 +56,7 @@ function withGroups(groups, entries, EntriesToRender, t) { }); } -export class EntriesCollection extends React.Component { +class EntriesCollection extends React.Component { static propTypes = { collection: ImmutablePropTypes.map.isRequired, page: PropTypes.number, diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/EntriesSearch.js b/packages/netlify-cms-core/src/components/Collection/Entries/EntriesSearch.js index 4789ced8..f72ab31f 100644 --- a/packages/netlify-cms-core/src/components/Collection/Entries/EntriesSearch.js +++ b/packages/netlify-cms-core/src/components/Collection/Entries/EntriesSearch.js @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; import { isEqual } from 'lodash'; -import { Cursor } from 'netlify-cms-lib-util'; +import { Cursor } from '../../../lib/util'; import { selectSearchedEntries } from '../../../reducers'; import { searchEntries as actionSearchEntries, diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js b/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js index 3af33765..0a809eb5 100644 --- a/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js +++ b/packages/netlify-cms-core/src/components/Collection/Entries/EntryCard.js @@ -2,8 +2,8 @@ import React from 'react'; import styled from '@emotion/styled'; import { connect } from 'react-redux'; import { Link } from 'react-router-dom'; -import { colors, colorsRaw, components, lengths, zIndex } from 'netlify-cms-ui-default'; +import { colors, colorsRaw, components, lengths, zIndex } from '../../../ui'; import { boundGetAsset } from '../../../actions/media'; import { VIEW_STYLE_LIST, VIEW_STYLE_GRID } from '../../../constants/collectionViews'; import { selectIsLoadingAsset } from '../../../reducers/medias'; diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js b/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js deleted file mode 100644 index 5afbd19b..00000000 --- a/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/EntriesCollection.spec.js +++ /dev/null @@ -1,155 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { fromJS } from 'immutable'; -import configureStore from 'redux-mock-store'; -import { Provider } from 'react-redux'; - -import ConnectedEntriesCollection, { - EntriesCollection, - filterNestedEntries, -} from '../EntriesCollection'; - -jest.mock('../Entries', () => 'mock-entries'); - -const middlewares = []; -const mockStore = configureStore(middlewares); - -function renderWithRedux(component, { store } = {}) { - function Wrapper({ children }) { - return {children}; - } - - return render(component, { wrapper: Wrapper }); -} - -function toEntriesState(collection, entriesArray) { - const entries = entriesArray.reduce( - (acc, entry) => { - acc.entities[`${collection.get('name')}.${entry.slug}`] = entry; - acc.pages[collection.get('name')].ids.push(entry.slug); - return acc; - }, - { pages: { [collection.get('name')]: { ids: [] } }, entities: {} }, - ); - return fromJS(entries); -} - -describe('filterNestedEntries', () => { - it('should return only immediate children for non root path', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } }, - { slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } }, - { slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } }, - ]; - const entries = fromJS(entriesArray); - expect(filterNestedEntries('dir3', 'src/pages', entries).toJS()).toEqual([ - { slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } }, - ]); - }); - - it('should return immediate children and root for root path', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } }, - { slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } }, - { slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } }, - ]; - const entries = fromJS(entriesArray); - expect(filterNestedEntries('', 'src/pages', entries).toJS()).toEqual([ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } }, - ]); - }); -}); - -describe('EntriesCollection', () => { - const collection = fromJS({ name: 'pages', label: 'Pages', folder: 'src/pages' }); - const props = { - t: jest.fn(), - loadEntries: jest.fn(), - traverseCollectionCursor: jest.fn(), - isFetching: false, - cursor: {}, - collection, - }; - it('should render with entries', () => { - const entries = fromJS([{ slug: 'index' }]); - const { asFragment } = render(); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render connected component', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir2/index', path: 'src/pages/dir2/index.md', data: { title: 'File 2' } }, - ]; - - const store = mockStore({ - entries: toEntriesState(collection, entriesArray), - cursors: fromJS({}), - }); - - const { asFragment } = renderWithRedux(, { - store, - }); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render show only immediate children for nested collection', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } }, - { slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } }, - { slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } }, - ]; - - const store = mockStore({ - entries: toEntriesState(collection, entriesArray), - cursors: fromJS({}), - }); - - const { asFragment } = renderWithRedux( - , - { - store, - }, - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render apply filter term for nested collections', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'dir1/index', path: 'src/pages/dir1/index.md', data: { title: 'File 1' } }, - { slug: 'dir1/dir2/index', path: 'src/pages/dir1/dir2/index.md', data: { title: 'File 2' } }, - { slug: 'dir3/index', path: 'src/pages/dir3/index.md', data: { title: 'File 3' } }, - { slug: 'dir3/dir4/index', path: 'src/pages/dir3/dir4/index.md', data: { title: 'File 4' } }, - ]; - - const store = mockStore({ - entries: toEntriesState(collection, entriesArray), - cursors: fromJS({}), - }); - - const { asFragment } = renderWithRedux( - , - { - store, - }, - ); - - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap b/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap deleted file mode 100644 index ccc4d591..00000000 --- a/packages/netlify-cms-core/src/components/Collection/Entries/__tests__/__snapshots__/EntriesCollection.spec.js.snap +++ /dev/null @@ -1,49 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EntriesCollection should render apply filter term for nested collections 1`] = ` - - - -`; - -exports[`EntriesCollection should render connected component 1`] = ` - - - -`; - -exports[`EntriesCollection should render show only immediate children for nested collection 1`] = ` - - - -`; - -exports[`EntriesCollection should render with entries 1`] = ` - - - -`; diff --git a/packages/netlify-cms-core/src/components/Collection/FilterControl.js b/packages/netlify-cms-core/src/components/Collection/FilterControl.js index a41bfd26..86a655ca 100644 --- a/packages/netlify-cms-core/src/components/Collection/FilterControl.js +++ b/packages/netlify-cms-core/src/components/Collection/FilterControl.js @@ -1,7 +1,7 @@ import React from 'react'; import { translate } from 'react-polyglot'; -import { Dropdown, DropdownCheckedItem } from 'netlify-cms-ui-default'; +import { Dropdown, DropdownCheckedItem } from '../../ui'; import { ControlButton } from './ControlButton'; function FilterControl({ viewFilters, t, onFilterClick, filter }) { diff --git a/packages/netlify-cms-core/src/components/Collection/GroupControl.js b/packages/netlify-cms-core/src/components/Collection/GroupControl.js index 42e2881c..1ebfc41b 100644 --- a/packages/netlify-cms-core/src/components/Collection/GroupControl.js +++ b/packages/netlify-cms-core/src/components/Collection/GroupControl.js @@ -1,7 +1,7 @@ import React from 'react'; import { translate } from 'react-polyglot'; -import { Dropdown, DropdownItem } from 'netlify-cms-ui-default'; +import { Dropdown, DropdownItem } from '../../ui'; import { ControlButton } from './ControlButton'; function GroupControl({ viewGroups, t, onGroupClick, group }) { diff --git a/packages/netlify-cms-core/src/components/Collection/NestedCollection.js b/packages/netlify-cms-core/src/components/Collection/NestedCollection.js index d80bed70..ba0d94a0 100644 --- a/packages/netlify-cms-core/src/components/Collection/NestedCollection.js +++ b/packages/netlify-cms-core/src/components/Collection/NestedCollection.js @@ -5,12 +5,12 @@ import styled from '@emotion/styled'; import { connect } from 'react-redux'; import { NavLink } from 'react-router-dom'; import { dirname, sep } from 'path'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; -import { Icon, colors, components } from 'netlify-cms-ui-default'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { sortBy } from 'lodash'; +import { Icon, colors, components } from '../../ui'; +import { stringTemplate } from '../../lib/widgets'; import { selectEntries } from '../../reducers/entries'; import { selectEntryCollectionTitle } from '../../reducers/collections'; diff --git a/packages/netlify-cms-core/src/components/Collection/Sidebar.js b/packages/netlify-cms-core/src/components/Collection/Sidebar.js index c817cc45..b1a6d897 100644 --- a/packages/netlify-cms-core/src/components/Collection/Sidebar.js +++ b/packages/netlify-cms-core/src/components/Collection/Sidebar.js @@ -5,8 +5,8 @@ import styled from '@emotion/styled'; import { css } from '@emotion/react'; import { translate } from 'react-polyglot'; import { NavLink } from 'react-router-dom'; -import { Icon, components, colors } from 'netlify-cms-ui-default'; +import { Icon, components, colors } from '../../ui'; import { searchCollections } from '../../actions/collections'; import CollectionSearch from './CollectionSearch'; import NestedCollection from './NestedCollection'; @@ -97,7 +97,7 @@ const IconWrapper = styled.div` margin-right: 8px; `; -export class Sidebar extends React.Component { +class Sidebar extends React.Component { static propTypes = { collections: ImmutablePropTypes.map.isRequired, collection: ImmutablePropTypes.map, @@ -142,7 +142,7 @@ export class Sidebar extends React.Component { ); }; - renderAdditionalLink = ({ title, url, iconName }) => { + renderAdditionalLink = ({ id, title, data, iconName }) => { let icon = ; if (iconName) { const storedIcon = getIcon(iconName); @@ -150,12 +150,25 @@ export class Sidebar extends React.Component { icon = storedIcon; } } + + const content = ( + <> + {icon} + {title} + + ); + return (
  • - - {icon} - {title} - + {typeof data === 'string' ? ( + + {content} + + ) : ( + + {content} + + )}
  • ); }; diff --git a/packages/netlify-cms-core/src/components/Collection/SortControl.js b/packages/netlify-cms-core/src/components/Collection/SortControl.js index 978d44df..611d0d5f 100644 --- a/packages/netlify-cms-core/src/components/Collection/SortControl.js +++ b/packages/netlify-cms-core/src/components/Collection/SortControl.js @@ -1,8 +1,8 @@ import React from 'react'; import { translate } from 'react-polyglot'; -import { Dropdown, DropdownItem } from 'netlify-cms-ui-default'; -import { SortDirection } from '../../types/redux'; +import { SortDirection } from '../../interface'; +import { Dropdown, DropdownItem } from '../../ui'; import { ControlButton } from './ControlButton'; function nextSortDirection(direction) { diff --git a/packages/netlify-cms-core/src/components/Collection/ViewStyleControl.js b/packages/netlify-cms-core/src/components/Collection/ViewStyleControl.js index 234feedd..01a4fa1b 100644 --- a/packages/netlify-cms-core/src/components/Collection/ViewStyleControl.js +++ b/packages/netlify-cms-core/src/components/Collection/ViewStyleControl.js @@ -1,7 +1,7 @@ import React from 'react'; import styled from '@emotion/styled'; -import { Icon, buttons, colors } from 'netlify-cms-ui-default'; +import { Icon, buttons, colors } from '../../ui'; import { VIEW_STYLE_LIST, VIEW_STYLE_GRID } from '../../constants/collectionViews'; const ViewControlsSection = styled.div` diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/Collection.spec.js b/packages/netlify-cms-core/src/components/Collection/__tests__/Collection.spec.js deleted file mode 100644 index eca5af8d..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/Collection.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { fromJS } from 'immutable'; -import configureStore from 'redux-mock-store'; -import { Provider } from 'react-redux'; - -import ConnectedCollection, { Collection } from '../Collection'; - -jest.mock('../Entries/EntriesCollection', () => 'mock-entries-collection'); -jest.mock('../CollectionTop', () => 'mock-collection-top'); -jest.mock('../CollectionControls', () => 'mock-collection-controls'); -jest.mock('../Sidebar', () => 'mock-sidebar'); - -const middlewares = []; -const mockStore = configureStore(middlewares); - -function renderWithRedux(component, { store } = {}) { - function Wrapper({ children }) { - return {children}; - } - - return render(component, { wrapper: Wrapper }); -} - -describe('Collection', () => { - const collection = fromJS({ - name: 'pages', - sortable_fields: [], - view_filters: [], - view_groups: [], - }); - const props = { - collections: fromJS([collection]).toOrderedMap(), - collection, - collectionName: collection.get('name'), - t: jest.fn(key => key), - onSortClick: jest.fn(), - }; - - it('should render with collection without create url', () => { - const { asFragment } = render( - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - it('should render with collection with create url', () => { - const { asFragment } = render( - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render with collection with create url and path', () => { - const { asFragment } = render( - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render connected component', () => { - const store = mockStore({ - collections: props.collections, - entries: fromJS({}), - }); - - const { asFragment } = renderWithRedux(, { - store, - }); - - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/NestedCollection.spec.js b/packages/netlify-cms-core/src/components/Collection/__tests__/NestedCollection.spec.js deleted file mode 100644 index 87aaa1a6..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/NestedCollection.spec.js +++ /dev/null @@ -1,442 +0,0 @@ -import React from 'react'; -import { MemoryRouter } from 'react-router-dom'; -import { render, fireEvent } from '@testing-library/react'; -import { fromJS } from 'immutable'; -import configureStore from 'redux-mock-store'; -import { Provider } from 'react-redux'; - -import ConnectedNestedCollection, { - NestedCollection, - getTreeData, - walk, - updateNode, -} from '../NestedCollection'; - -jest.mock('netlify-cms-ui-default', () => { - const actual = jest.requireActual('netlify-cms-ui-default'); - return { - ...actual, - Icon: 'mocked-icon', - }; -}); - -const middlewares = []; -const mockStore = configureStore(middlewares); - -function renderWithRedux(component, { store } = {}) { - function Wrapper({ children }) { - return {children}; - } - - return render(component, { wrapper: Wrapper }); -} - -describe('NestedCollection', () => { - const collection = fromJS({ - name: 'pages', - label: 'Pages', - folder: 'src/pages', - fields: [{ name: 'title', widget: 'string' }], - }); - - it('should render correctly with no entries', () => { - const entries = fromJS([]); - const { asFragment, getByTestId } = render( - - - , - ); - - expect(getByTestId('/')).toHaveTextContent('Pages'); - expect(getByTestId('/')).toHaveAttribute('href', '/collections/pages'); - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render correctly with nested entries', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/b/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 3' } }, - { path: 'src/pages/b/a/index.md', data: { title: 'File 4' } }, - ]); - const { asFragment, getByTestId } = render( - - - , - ); - - // expand the tree - fireEvent.click(getByTestId('/')); - - expect(getByTestId('/a')).toHaveTextContent('File 1'); - expect(getByTestId('/a')).toHaveAttribute('href', '/collections/pages/filter/a'); - - expect(getByTestId('/b')).toHaveTextContent('File 2'); - expect(getByTestId('/b')).toHaveAttribute('href', '/collections/pages/filter/b'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should keep expanded nodes on re-render', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/b/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 3' } }, - { path: 'src/pages/b/a/index.md', data: { title: 'File 4' } }, - ]); - const { getByTestId, rerender } = render( - - - , - ); - - fireEvent.click(getByTestId('/')); - fireEvent.click(getByTestId('/a')); - - expect(getByTestId('/a')).toHaveTextContent('File 1'); - - const newEntries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/b/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 3' } }, - { path: 'src/pages/b/a/index.md', data: { title: 'File 4' } }, - { path: 'src/pages/c/index.md', data: { title: 'File 5' } }, - { path: 'src/pages/c/a/index.md', data: { title: 'File 6' } }, - ]); - - rerender( - - - , - ); - - expect(getByTestId('/a')).toHaveTextContent('File 1'); - }); - - it('should expand nodes based on filterTerm', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/a/index.md', data: { title: 'File 3' } }, - ]); - - const { getByTestId, queryByTestId, rerender } = render( - - - , - ); - - expect(queryByTestId('/a/a')).toBeNull(); - - rerender( - - - , - ); - - expect(getByTestId('/a/a')).toHaveTextContent('File 2'); - }); - - it('should ignore filterTerm once a user toggles an node', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/a/index.md', data: { title: 'File 3' } }, - ]); - - const { getByTestId, queryByTestId, rerender } = render( - - - , - ); - - rerender( - - - , - ); - - expect(getByTestId('/a/a')).toHaveTextContent('File 2'); - - fireEvent.click(getByTestId('/a')); - - rerender( - - - , - ); - - expect(queryByTestId('/a/a')).toBeNull(); - }); - - it('should not collapse an unselected node when clicked', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/a/index.md', data: { title: 'File 3' } }, - { path: 'src/pages/a/a/a/a/index.md', data: { title: 'File 4' } }, - ]); - - const { getByTestId } = render( - - - , - ); - - fireEvent.click(getByTestId('/')); - fireEvent.click(getByTestId('/a')); - fireEvent.click(getByTestId('/a/a')); - - expect(getByTestId('/a/a')).toHaveTextContent('File 2'); - fireEvent.click(getByTestId('/a')); - expect(getByTestId('/a/a')).toHaveTextContent('File 2'); - }); - - it('should collapse a selected node when clicked', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { path: 'src/pages/a/a/index.md', data: { title: 'File 2' } }, - { path: 'src/pages/a/a/a/index.md', data: { title: 'File 3' } }, - { path: 'src/pages/a/a/a/a/index.md', data: { title: 'File 4' } }, - ]); - - const { getByTestId, queryByTestId } = render( - - - , - ); - - fireEvent.click(getByTestId('/')); - fireEvent.click(getByTestId('/a')); - fireEvent.click(getByTestId('/a/a')); - - expect(getByTestId('/a/a/a')).toHaveTextContent('File 3'); - fireEvent.click(getByTestId('/a/a')); - expect(queryByTestId('/a/a/a')).toBeNull(); - }); - - it('should render connected component', () => { - const entriesArray = [ - { slug: 'index', path: 'src/pages/index.md', data: { title: 'Root' } }, - { slug: 'a/index', path: 'src/pages/a/index.md', data: { title: 'File 1' } }, - { slug: 'b/index', path: 'src/pages/b/index.md', data: { title: 'File 2' } }, - { slug: 'a/a/index', path: 'src/pages/a/a/index.md', data: { title: 'File 3' } }, - { slug: 'b/a/index', path: 'src/pages/b/a/index.md', data: { title: 'File 4' } }, - ]; - const entries = entriesArray.reduce( - (acc, entry) => { - acc.entities[`${collection.get('name')}.${entry.slug}`] = entry; - acc.pages[collection.get('name')].ids.push(entry.slug); - return acc; - }, - { pages: { [collection.get('name')]: { ids: [] } }, entities: {} }, - ); - - const store = mockStore({ entries: fromJS(entries) }); - - const { asFragment, getByTestId } = renderWithRedux( - - - , - { store }, - ); - - // expand the root - fireEvent.click(getByTestId('/')); - - expect(getByTestId('/a')).toHaveTextContent('File 1'); - expect(getByTestId('/a')).toHaveAttribute('href', '/collections/pages/filter/a'); - - expect(getByTestId('/b')).toHaveTextContent('File 2'); - expect(getByTestId('/b')).toHaveAttribute('href', '/collections/pages/filter/b'); - - expect(asFragment()).toMatchSnapshot(); - }); - - describe('getTreeData', () => { - it('should return nested tree data from entries', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/intro/index.md', data: { title: 'intro index' } }, - { path: 'src/pages/intro/category/index.md', data: { title: 'intro category index' } }, - { path: 'src/pages/compliance/index.md', data: { title: 'compliance index' } }, - ]); - - const treeData = getTreeData(collection, entries); - - expect(treeData).toEqual([ - { - title: 'Pages', - path: '/', - isDir: true, - isRoot: true, - children: [ - { - title: 'intro', - path: '/intro', - isDir: true, - isRoot: false, - children: [ - { - title: 'category', - path: '/intro/category', - isDir: true, - isRoot: false, - children: [ - { - path: '/intro/category/index.md', - data: { title: 'intro category index' }, - title: 'intro category index', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - { - path: '/intro/index.md', - data: { title: 'intro index' }, - title: 'intro index', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - { - title: 'compliance', - path: '/compliance', - isDir: true, - isRoot: false, - children: [ - { - path: '/compliance/index.md', - data: { title: 'compliance index' }, - title: 'compliance index', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - { - path: '/index.md', - data: { title: 'Root' }, - title: 'Root', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - ]); - }); - - it('should ignore collection summary', () => { - const entries = fromJS([{ path: 'src/pages/index.md', data: { title: 'Root' } }]); - - const treeData = getTreeData(collection, entries); - - expect(treeData).toEqual([ - { - title: 'Pages', - path: '/', - isDir: true, - isRoot: true, - children: [ - { - path: '/index.md', - data: { title: 'Root' }, - title: 'Root', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - ]); - }); - - it('should use nested collection summary for title', () => { - const entries = fromJS([{ path: 'src/pages/index.md', data: { title: 'Root' } }]); - - const treeData = getTreeData( - collection.setIn(['nested', 'summary'], '{{filename}}'), - entries, - ); - - expect(treeData).toEqual([ - { - title: 'Pages', - path: '/', - isDir: true, - isRoot: true, - children: [ - { - path: '/index.md', - data: { title: 'Root' }, - title: 'index', - isDir: false, - isRoot: false, - children: [], - }, - ], - }, - ]); - }); - }); - - describe('walk', () => { - it('should visit every tree node', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/dir1/index.md', data: { title: 'Dir1 File' } }, - { path: 'src/pages/dir2/index.md', data: { title: 'Dir2 File' } }, - ]); - - const treeData = getTreeData(collection, entries); - const callback = jest.fn(); - walk(treeData, callback); - - expect(callback).toHaveBeenCalledTimes(6); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/' })); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/index.md' })); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/dir1' })); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/dir2' })); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/dir1/index.md' })); - expect(callback).toHaveBeenCalledWith(expect.objectContaining({ path: '/dir2/index.md' })); - }); - }); - - describe('updateNode', () => { - it('should update node', () => { - const entries = fromJS([ - { path: 'src/pages/index.md', data: { title: 'Root' } }, - { path: 'src/pages/dir1/index.md', data: { title: 'Dir1 File' } }, - { path: 'src/pages/dir2/index.md', data: { title: 'Dir2 File' } }, - ]); - - const treeData = getTreeData(collection, entries); - expect(treeData[0].children[0].children[0].expanded).toBeUndefined(); - - const callback = jest.fn(node => ({ ...node, expanded: true })); - const node = { path: '/dir1/index.md' }; - updateNode(treeData, node, callback); - - expect(callback).toHaveBeenCalledTimes(1); - expect(callback).toHaveBeenCalledWith(node); - expect(treeData[0].children[0].children[0].expanded).toEqual(true); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/Sidebar.spec.js b/packages/netlify-cms-core/src/components/Collection/__tests__/Sidebar.spec.js deleted file mode 100644 index 1fa04cb8..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/Sidebar.spec.js +++ /dev/null @@ -1,87 +0,0 @@ -import React from 'react'; -import { MemoryRouter } from 'react-router-dom'; -import { render } from '@testing-library/react'; -import { fromJS } from 'immutable'; - -import { Sidebar } from '../Sidebar'; - -jest.mock('netlify-cms-ui-default', () => { - const actual = jest.requireActual('netlify-cms-ui-default'); - return { - ...actual, - Icon: 'mocked-icon', - }; -}); - -jest.mock('../NestedCollection', () => 'nested-collection'); -jest.mock('../CollectionSearch', () => 'collection-search'); -jest.mock('../../../actions/collections'); - -describe('Sidebar', () => { - const props = { - searchTerm: '', - isSearchEnabled: true, - t: jest.fn(key => key), - }; - it('should render sidebar with a simple collection', () => { - const collections = fromJS([{ name: 'posts', label: 'Posts' }]).toOrderedMap(); - const { asFragment, getByTestId } = render( - - - , - ); - - expect(getByTestId('posts')).toHaveTextContent('Posts'); - expect(getByTestId('posts')).toHaveAttribute('href', '/collections/posts'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should not render a hidden collection', () => { - const collections = fromJS([{ name: 'posts', label: 'Posts', hide: true }]).toOrderedMap(); - const { queryByTestId } = render( - - - , - ); - - expect(queryByTestId('posts')).toBeNull(); - }); - - it('should render sidebar with a nested collection', () => { - const collections = fromJS([ - { name: 'posts', label: 'Posts', nested: { depth: 10 } }, - ]).toOrderedMap(); - const { asFragment } = render( - - - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render nested collection with filterTerm', () => { - const collections = fromJS([ - { name: 'posts', label: 'Posts', nested: { depth: 10 } }, - ]).toOrderedMap(); - const { asFragment } = render( - - - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render sidebar without search', () => { - const collections = fromJS([{ name: 'posts', label: 'Posts' }]).toOrderedMap(); - const { asFragment } = render( - - - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap b/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap deleted file mode 100644 index ac958e9a..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Collection.spec.js.snap +++ /dev/null @@ -1,144 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Collection should render connected component 1`] = ` - - .emotion-2 { - margin: 28px 18px; -} - -.emotion-0 { - padding-left: 280px; -} - -
    - -
    - - - -
    -
    -
    -`; - -exports[`Collection should render with collection with create url 1`] = ` - - .emotion-2 { - margin: 28px 18px; -} - -.emotion-0 { - padding-left: 280px; -} - -
    - -
    - - - -
    -
    -
    -`; - -exports[`Collection should render with collection with create url and path 1`] = ` - - .emotion-2 { - margin: 28px 18px; -} - -.emotion-0 { - padding-left: 280px; -} - -
    - -
    - - - -
    -
    -
    -`; - -exports[`Collection should render with collection without create url 1`] = ` - - .emotion-2 { - margin: 28px 18px; -} - -.emotion-0 { - padding-left: 280px; -} - -
    - -
    - - - -
    -
    -
    -`; diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap b/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap deleted file mode 100644 index 11c2d4f9..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/NestedCollection.spec.js.snap +++ /dev/null @@ -1,550 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`NestedCollection should render connected component 1`] = ` - - .emotion-6 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 12px; - border-left: 2px solid #fff; -} - -.emotion-6 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-6:hover, -.emotion-6:active, -.emotion-6.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-2 { - position: relative; - top: 2px; - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - color: currentColor; -} - - - -
    -
    - Pages -
    -
    -
    -
    - .emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 32px; - border-left: 2px solid #fff; -} - -.emotion-4 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-4:hover, -.emotion-4:active, -.emotion-4.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -
    -
    - File 1 -
    -
    -
    - .emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 32px; - border-left: 2px solid #fff; -} - -.emotion-4 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-4:hover, -.emotion-4:active, -.emotion-4.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -
    -
    - File 2 -
    -
    -
    - -`; - -exports[`NestedCollection should render correctly with nested entries 1`] = ` - - .emotion-6 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 12px; - border-left: 2px solid #fff; -} - -.emotion-6 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-6:hover, -.emotion-6:active, -.emotion-6.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-2 { - position: relative; - top: 2px; - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - color: currentColor; -} - - - -
    -
    - Pages -
    -
    -
    -
    - .emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 32px; - border-left: 2px solid #fff; -} - -.emotion-4 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-4:hover, -.emotion-4:active, -.emotion-4.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -
    -
    - File 1 -
    -
    -
    - .emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 32px; - border-left: 2px solid #fff; -} - -.emotion-4 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-4:hover, -.emotion-4:active, -.emotion-4.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -
    -
    - File 2 -
    -
    -
    - -`; - -exports[`NestedCollection should render correctly with no entries 1`] = ` - - .emotion-6 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px; - padding-left: 12px; - border-left: 2px solid #fff; -} - -.emotion-6 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-6:hover, -.emotion-6:active, -.emotion-6.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - -.emotion-4 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-0 { - margin-right: 4px; -} - -.emotion-2 { - position: relative; - top: 2px; - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-left: 6px solid currentColor; - border-right: 0; - color: currentColor; - left: 2px; -} - - - -
    -
    - Pages -
    -
    -
    -
    - -`; diff --git a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap b/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap deleted file mode 100644 index 6d5f2978..00000000 --- a/packages/netlify-cms-core/src/components/Collection/__tests__/__snapshots__/Sidebar.spec.js.snap +++ /dev/null @@ -1,308 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Sidebar should render nested collection with filterTerm 1`] = ` - - .emotion-4 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1); - border-radius: 5px; - background-color: #fff; - width: 250px; - padding: 8px 0 12px; - position: fixed; - max-height: calc(100vh - 112px); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.emotion-0 { - font-size: 23px; - font-weight: 600; - padding: 0; - margin: 18px 12px 12px; - color: #313d3e; -} - -.emotion-2 { - margin: 16px 0 0; - list-style: none; - overflow: auto; -} - - - -`; - -exports[`Sidebar should render sidebar with a nested collection 1`] = ` - - .emotion-4 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1); - border-radius: 5px; - background-color: #fff; - width: 250px; - padding: 8px 0 12px; - position: fixed; - max-height: calc(100vh - 112px); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.emotion-0 { - font-size: 23px; - font-weight: 600; - padding: 0; - margin: 18px 12px 12px; - color: #313d3e; -} - -.emotion-2 { - margin: 16px 0 0; - list-style: none; - overflow: auto; -} - - - -`; - -exports[`Sidebar should render sidebar with a simple collection 1`] = ` - - .emotion-6 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1); - border-radius: 5px; - background-color: #fff; - width: 250px; - padding: 8px 0 12px; - position: fixed; - max-height: calc(100vh - 112px); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.emotion-0 { - font-size: 23px; - font-weight: 600; - padding: 0; - margin: 18px 12px 12px; - color: #313d3e; -} - -.emotion-4 { - margin: 16px 0 0; - list-style: none; - overflow: auto; -} - -.emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px 12px; - border-left: 2px solid #fff; - z-index: -1; -} - -.emotion-2 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-2:hover, -.emotion-2:active, -.emotion-2.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -`; - -exports[`Sidebar should render sidebar without search 1`] = ` - - .emotion-6 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1); - border-radius: 5px; - background-color: #fff; - width: 250px; - padding: 8px 0 12px; - position: fixed; - max-height: calc(100vh - 112px); - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-direction: column; - -ms-flex-direction: column; - flex-direction: column; -} - -.emotion-0 { - font-size: 23px; - font-weight: 600; - padding: 0; - margin: 18px 12px 12px; - color: #313d3e; -} - -.emotion-4 { - margin: 16px 0 0; - list-style: none; - overflow: auto; -} - -.emotion-2 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - font-size: 14px; - font-weight: 500; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 8px 12px; - border-left: 2px solid #fff; - z-index: -1; -} - -.emotion-2 mocked-icon { - margin-right: 8px; - -webkit-flex-shrink: 0; - -ms-flex-negative: 0; - flex-shrink: 0; -} - -.emotion-2:hover, -.emotion-2:active, -.emotion-2.sidebar-active { - color: #3a69c7; - background-color: #e8f5fe; - border-left-color: #4863c6; -} - - - -`; diff --git a/packages/netlify-cms-core/src/components/Editor/Editor.js b/packages/netlify-cms-core/src/components/Editor/Editor.js index a6edd935..76d8b63b 100644 --- a/packages/netlify-cms-core/src/components/Editor/Editor.js +++ b/packages/netlify-cms-core/src/components/Editor/Editor.js @@ -1,5 +1,4 @@ import { debounce } from 'lodash'; -import { Loader } from 'netlify-cms-ui-default'; import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; @@ -34,6 +33,9 @@ import { EDITORIAL_WORKFLOW, status } from '../../constants/publishModes'; import { selectDeployPreview, selectEntry, selectUnpublishedEntry } from '../../reducers'; import { selectFields } from '../../reducers/collections'; import { history, navigateToCollection, navigateToNewEntry } from '../../routing/history'; +import { Loader } from '../../ui'; +import alert from '../UI/Alert'; +import confirm from '../UI/Confirm'; import EditorInterface from './EditorInterface'; import withWorkflow from './withWorkflow'; @@ -167,21 +169,32 @@ export class Editor extends React.Component { } } - componentDidUpdate(prevProps) { - if (!prevProps.localBackup && this.props.localBackup) { - const confirmLoadBackup = window.confirm(this.props.t('editor.editor.confirmLoadBackup')); + async checkLocalBackup(prevProps) { + const { t, hasChanged, localBackup, loadLocalBackup, entryDraft, collection } = this.props; + + if (!prevProps.localBackup && localBackup) { + const confirmLoadBackup = await confirm({ + title: 'editor.editor.confirmLoadBackupTitle', + body: 'editor.editor.confirmLoadBackupBody', + }); if (confirmLoadBackup) { - this.props.loadLocalBackup(); + loadLocalBackup(); } else { this.deleteBackup(); } } - if (this.props.hasChanged) { - this.createBackup(this.props.entryDraft.get('entry'), this.props.collection); + if (hasChanged) { + this.createBackup(entryDraft.get('entry'), collection); } + } - if (prevProps.entry === this.props.entry) return; + componentDidUpdate(prevProps) { + this.checkLocalBackup(prevProps); + + if (prevProps.entry === this.props.entry) { + return; + } const { newEntry, collection } = this.props; @@ -206,10 +219,13 @@ export class Editor extends React.Component { }; handleChangeStatus = newStatusName => { - const { entryDraft, updateUnpublishedEntryStatus, collection, slug, currentStatus, t } = + const { entryDraft, updateUnpublishedEntryStatus, collection, slug, currentStatus } = this.props; if (entryDraft.get('hasChanged')) { - window.alert(t('editor.editor.onUpdatingWithUnsavedChanges')); + alert({ + title: 'editor.editor.onUpdatingWithUnsavedChangesTitle', + body: 'editor.editor.onUpdatingWithUnsavedChangesBody', + }); return; } const newStatus = status.get(newStatusName); @@ -256,15 +272,25 @@ export class Editor extends React.Component { collection, slug, currentStatus, - t, } = this.props; if (currentStatus !== status.last()) { - window.alert(t('editor.editor.onPublishingNotReady')); + alert({ + title: 'editor.editor.onPublishingNotReadyTitle', + body: 'editor.editor.onPublishingNotReadyBody', + }); return; } else if (entryDraft.get('hasChanged')) { - window.alert(t('editor.editor.onPublishingWithUnsavedChanges')); + alert({ + title: 'editor.editor.onPublishingWithUnsavedChangesTitle', + body: 'editor.editor.onPublishingWithUnsavedChangesBody', + }); return; - } else if (!window.confirm(t('editor.editor.onPublishing'))) { + } else if ( + !(await confirm({ + title: 'editor.editor.onPublishingTitle', + body: 'editor.editor.onPublishingBody', + })) + ) { return; } @@ -280,8 +306,16 @@ export class Editor extends React.Component { }; handleUnpublishEntry = async () => { - const { unpublishPublishedEntry, collection, slug, t } = this.props; - if (!window.confirm(t('editor.editor.onUnpublishing'))) return; + const { unpublishPublishedEntry, collection, slug } = this.props; + if ( + !(await confirm({ + title: 'editor.editor.onUnpublishingTitle', + body: 'editor.editor.onUnpublishingBody', + color: 'error', + })) + ) { + return; + } await unpublishPublishedEntry(collection, slug); @@ -295,15 +329,28 @@ export class Editor extends React.Component { createDraftDuplicateFromEntry(entryDraft.get('entry')); }; - handleDeleteEntry = () => { - const { entryDraft, newEntry, collection, deleteEntry, slug, t } = this.props; + handleDeleteEntry = async () => { + const { entryDraft, newEntry, collection, deleteEntry, slug } = this.props; if (entryDraft.get('hasChanged')) { - if (!window.confirm(t('editor.editor.onDeleteWithUnsavedChanges'))) { + if ( + !(await confirm({ + title: 'editor.editor.onDeleteWithUnsavedChangesTitle', + body: 'editor.editor.onDeleteWithUnsavedChangesBody', + color: 'error', + })) + ) { return; } - } else if (!window.confirm(t('editor.editor.onDeletePublishedEntry'))) { + } else if ( + !(await confirm({ + title: 'editor.editor.onDeletePublishedEntryTitle', + body: 'editor.editor.onDeletePublishedEntryBody', + color: 'error', + })) + ) { return; } + if (newEntry) { return navigateToCollection(collection.get('name')); } @@ -316,14 +363,24 @@ export class Editor extends React.Component { }; handleDeleteUnpublishedChanges = async () => { - const { entryDraft, collection, slug, deleteUnpublishedEntry, loadEntry, isModification, t } = + const { entryDraft, collection, slug, deleteUnpublishedEntry, loadEntry, isModification } = this.props; if ( entryDraft.get('hasChanged') && - !window.confirm(t('editor.editor.onDeleteUnpublishedChangesWithUnsavedChanges')) + !(await confirm({ + title: 'editor.editor.onDeleteUnpublishedChangesWithUnsavedChangesTitle', + body: 'editor.editor.onDeleteUnpublishedChangesWithUnsavedChangesBody', + color: 'error', + })) ) { return; - } else if (!window.confirm(t('editor.editor.onDeleteUnpublishedChanges'))) { + } else if ( + !(await confirm({ + title: 'editor.editor.onDeleteUnpublishedChangesTitle', + body: 'editor.editor.onDeleteUnpublishedChangesBody', + color: 'error', + })) + ) { return; } await deleteUnpublishedEntry(collection.get('name'), slug); diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js index 7e287239..d06d4648 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControl.js @@ -7,16 +7,16 @@ import { ClassNames, Global, css as coreCss } from '@emotion/react'; import styled from '@emotion/styled'; import { partial, uniqueId } from 'lodash'; import { connect } from 'react-redux'; +import ReactMarkdown from 'react-markdown'; +import gfm from 'remark-gfm'; + import { FieldLabel, colors, transitions, lengths, borders, -} from 'netlify-cms-ui-default'; -import ReactMarkdown from 'react-markdown'; -import gfm from 'remark-gfm'; - +} from '../../../ui'; import { resolveWidget, getEditorComponents } from '../../../lib/registry'; import { clearFieldErrors, tryLoadEntry, validateMetaField } from '../../../actions/entries'; import { addAsset, boundGetAsset } from '../../../actions/media'; @@ -289,6 +289,7 @@ class EditorControl extends React.Component { ${styleStrings.labelActive}; `} controlComponent={widget.control} + validator={widget.validator} entry={entry} collection={collection} config={config} diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControlPane.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControlPane.js index 0ffc41fe..4b3992a4 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControlPane.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/EditorControlPane.js @@ -3,15 +3,8 @@ import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; -import { - buttons, - colors, - Dropdown, - DropdownItem, - StyledDropdownButton, - text, -} from 'netlify-cms-ui-default'; +import { buttons, colors, Dropdown, DropdownItem, StyledDropdownButton, text } from '../../../ui'; import EditorControl from './EditorControl'; import { getI18nInfo, @@ -116,13 +109,15 @@ export default class ControlPane extends React.Component { copyFromOtherLocale = ({ targetLocale, t }) => - sourceLocale => { + async sourceLocale => { if ( - !window.confirm( - t('editor.editorControlPane.i18n.copyFromLocaleConfirm', { - locale: sourceLocale.toUpperCase(), - }), - ) + !(await confirm({ + title: 'editor.editorControlPane.i18n.copyFromLocaleConfirmTitle', + body: { + key: 'editor.editorControlPane.i18n.copyFromLocaleConfirmBody', + options: { locale: sourceLocale.toUpperCase() }, + }, + })) ) { return; } diff --git a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js index 827d434f..ca74db83 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorControlPane/Widget.js @@ -23,7 +23,8 @@ function isEmpty(value) { export default class Widget extends Component { static propTypes = { - controlComponent: PropTypes.func.isRequired, + controlComponent: PropTypes.oneOfType([PropTypes.func, PropTypes.object]).isRequired, + validator: PropTypes.func, field: ImmutablePropTypes.map.isRequired, hasActiveStyle: PropTypes.bool, setActiveStyle: PropTypes.func.isRequired, @@ -99,8 +100,6 @@ export default class Widget extends Component { */ this.innerWrappedControl = ref.getWrappedInstance ? ref.getWrappedInstance() : ref; - this.wrappedControlValid = this.innerWrappedControl.isValid || truthy; - /** * Get the `shouldComponentUpdate` method from the wrapped control, and * provide the control instance is the `this` binding. @@ -180,44 +179,38 @@ export default class Widget extends Component { }; validateWrappedControl = field => { - const { t, parentIds } = this.props; - if (typeof this.wrappedControlValid !== 'function') { - throw new Error(oneLine` - this.wrappedControlValid is not a function. Are you sure widget - "${field.get('widget')}" is registered? - `); - } + const { t, parentIds, validator, value } = this.props; + const response = validator?.({ value, field, t }); + if (response !== undefined) { + if (typeof response === 'boolean') { + return { error: !response }; + } else if (Object.prototype.hasOwnProperty.call(response, 'error')) { + return response; + } else if (response instanceof Promise) { + response.then( + () => { + this.validate({ error: false }); + }, + err => { + const error = { + type: ValidationErrorTypes.CUSTOM, + message: `${field.get('label', field.get('name'))} - ${err}.`, + }; - const response = this.wrappedControlValid(); - if (typeof response === 'boolean') { - const isValid = response; - return { error: !isValid }; - } else if (Object.prototype.hasOwnProperty.call(response, 'error')) { - return response; - } else if (response instanceof Promise) { - response.then( - () => { - this.validate({ error: false }); - }, - err => { - const error = { - type: ValidationErrorTypes.CUSTOM, - message: `${field.get('label', field.get('name'))} - ${err}.`, - }; + this.validate({ error }); + }, + ); - this.validate({ error }); - }, - ); + const error = { + type: ValidationErrorTypes.CUSTOM, + parentIds, + message: t('editor.editorControlPane.widget.processing', { + fieldLabel: field.get('label', field.get('name')), + }), + }; - const error = { - type: ValidationErrorTypes.CUSTOM, - parentIds, - message: t('editor.editorControlPane.widget.processing', { - fieldLabel: field.get('label', field.get('name')), - }), - }; - - return { error }; + return { error }; + } } return { error: false }; }; @@ -315,7 +308,6 @@ export default class Widget extends Component { onRemoveInsertedMedia, getAsset, forID: uniqueFieldId, - ref: this.processInnerControlRef, validate: this.validate, classNameWrapper, classNameWidget, diff --git a/packages/netlify-cms-core/src/components/Editor/EditorInterface.js b/packages/netlify-cms-core/src/components/Editor/EditorInterface.js index a9e27c42..480fc1d8 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorInterface.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorInterface.js @@ -3,6 +3,8 @@ import React, { Component } from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { css, Global } from '@emotion/react'; import styled from '@emotion/styled'; +import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync'; + import { colors, colorsRaw, @@ -10,9 +12,7 @@ import { transitions, IconButton, zIndex, -} from 'netlify-cms-ui-default'; -import { ScrollSync, ScrollSyncPane } from 'react-scroll-sync'; - +} from '../../ui'; import EditorControlPane from './EditorControlPane/EditorControlPane'; import EditorPreviewPane from './EditorPreviewPane/EditorPreviewPane'; import EditorToolbar from './EditorToolbar'; diff --git a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js index 10915b2f..dc768e6e 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorPreviewPane/EditorPreviewPane.js @@ -3,9 +3,9 @@ import React from 'react'; import styled from '@emotion/styled'; import { List, Map } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { lengths } from 'netlify-cms-ui-default'; import { connect } from 'react-redux'; +import { lengths } from '../../../ui'; import { resolveWidget, getPreviewTemplate, diff --git a/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js b/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js index a562c423..c1c62f6f 100644 --- a/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js +++ b/packages/netlify-cms-core/src/components/Editor/EditorToolbar.js @@ -5,6 +5,7 @@ import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; import { Link } from 'react-router-dom'; + import { Icon, Dropdown, @@ -15,8 +16,7 @@ import { components, buttons, zIndex, -} from 'netlify-cms-ui-default'; - +} from '../../ui'; import { status } from '../../constants/publishModes'; import { SettingsDropdown } from '../UI'; diff --git a/packages/netlify-cms-core/src/components/Editor/__tests__/Editor.spec.js b/packages/netlify-cms-core/src/components/Editor/__tests__/Editor.spec.js deleted file mode 100644 index cecfc254..00000000 --- a/packages/netlify-cms-core/src/components/Editor/__tests__/Editor.spec.js +++ /dev/null @@ -1,219 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { fromJS } from 'immutable'; - -import { Editor } from '../Editor'; - -jest.mock('lodash/debounce', () => { - const flush = jest.fn(); - return func => { - func.flush = flush; - return func; - }; -}); -// eslint-disable-next-line react/display-name -jest.mock('../EditorInterface', () => props => ); -jest.mock('netlify-cms-ui-default', () => { - return { - // eslint-disable-next-line react/display-name - Loader: props => , - }; -}); -jest.mock('../../../routing/history'); - -describe('Editor', () => { - const props = { - boundGetAsset: jest.fn(), - changeDraftField: jest.fn(), - changeDraftFieldValidation: jest.fn(), - collection: fromJS({ name: 'posts' }), - createDraftDuplicateFromEntry: jest.fn(), - createEmptyDraft: jest.fn(), - discardDraft: jest.fn(), - entry: fromJS({}), - entryDraft: fromJS({}), - loadEntry: jest.fn(), - persistEntry: jest.fn(), - deleteEntry: jest.fn(), - showDelete: true, - fields: fromJS([]), - slug: 'slug', - newEntry: true, - updateUnpublishedEntryStatus: jest.fn(), - publishUnpublishedEntry: jest.fn(), - deleteUnpublishedEntry: jest.fn(), - logoutUser: jest.fn(), - loadEntries: jest.fn(), - deployPreview: fromJS({}), - loadDeployPreview: jest.fn(), - user: fromJS({}), - t: jest.fn(key => key), - localBackup: fromJS({}), - retrieveLocalBackup: jest.fn(), - persistLocalBackup: jest.fn(), - location: { search: '?title=title' }, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should render loader when entryDraft is null', () => { - // suppress prop type error - jest.spyOn(console, 'error').mockImplementation(() => {}); - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledWith( - 'Warning: Failed prop type: Required prop `entryDraft` was not specified in `Editor`.\n in Editor', - ); - }); - - it('should render loader when entryDraft entry is undefined', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render loader when entry is fetching', () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render editor interface when entry is not fetching', () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - - it('should call retrieveLocalBackup on mount', () => { - render( - , - ); - - expect(props.retrieveLocalBackup).toHaveBeenCalledTimes(1); - expect(props.retrieveLocalBackup).toHaveBeenCalledWith(props.collection, props.slug); - }); - - it('should create new draft on new entry when mounting', () => { - render( - , - ); - - expect(props.createEmptyDraft).toHaveBeenCalledTimes(1); - expect(props.createEmptyDraft).toHaveBeenCalledWith(props.collection, '?title=title'); - expect(props.loadEntry).toHaveBeenCalledTimes(0); - }); - - it('should load entry on existing entry when mounting', () => { - render( - , - ); - - expect(props.createEmptyDraft).toHaveBeenCalledTimes(0); - expect(props.loadEntry).toHaveBeenCalledTimes(1); - expect(props.loadEntry).toHaveBeenCalledWith(props.collection, 'slug'); - }); - - it('should load entires when entries are not loaded when mounting', () => { - render( - , - ); - - expect(props.loadEntries).toHaveBeenCalledTimes(1); - expect(props.loadEntries).toHaveBeenCalledWith(props.collection); - }); - - it('should not load entires when entries are loaded when mounting', () => { - render( - , - ); - - expect(props.loadEntries).toHaveBeenCalledTimes(0); - }); - - it('should flush debounce createBackup, discard draft and remove exit blocker on umount', () => { - window.removeEventListener = jest.fn(); - const debounce = require('lodash/debounce'); - - const flush = debounce({}).flush; - const { unmount } = render( - , - ); - - jest.clearAllMocks(); - unmount(); - - expect(flush).toHaveBeenCalledTimes(1); - expect(props.discardDraft).toHaveBeenCalledTimes(1); - expect(window.removeEventListener).toHaveBeenCalledWith('beforeunload', expect.any(Function)); - - const callback = window.removeEventListener.mock.calls.find( - call => call[0] === 'beforeunload', - )[1]; - - const event = {}; - callback(event); - expect(event).toEqual({ returnValue: 'editor.editor.onLeavePage' }); - }); - - it('should persist backup when changed', () => { - const { rerender } = render( - , - ); - - jest.clearAllMocks(); - rerender( - , - ); - - expect(props.persistLocalBackup).toHaveBeenCalledTimes(1); - expect(props.persistLocalBackup).toHaveBeenCalledWith( - fromJS({ mediaFiles: [{ id: '1' }] }), - props.collection, - ); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Editor/__tests__/EditorToolbar.spec.js b/packages/netlify-cms-core/src/components/Editor/__tests__/EditorToolbar.spec.js deleted file mode 100644 index 5f1917ab..00000000 --- a/packages/netlify-cms-core/src/components/Editor/__tests__/EditorToolbar.spec.js +++ /dev/null @@ -1,120 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { fromJS } from 'immutable'; - -import { EditorToolbar } from '../EditorToolbar'; - -jest.mock('../../UI', () => ({ - // eslint-disable-next-line react/display-name - SettingsDropdown: props => , -})); -jest.mock('react-router-dom', () => { - return { - // eslint-disable-next-line react/display-name - Link: props => , - }; -}); - -describe('EditorToolbar', () => { - const props = { - isPersisting: false, - isPublishing: false, - isUpdatingStatus: false, - isDeleting: false, - onPersist: jest.fn(), - onPersistAndNew: jest.fn(), - onPersistAndDuplicate: jest.fn(), - showDelete: true, - onDelete: jest.fn(), - onDeleteUnpublishedChanges: jest.fn(), - onChangeStatus: jest.fn(), - onPublish: jest.fn(), - unPublish: jest.fn(), - onDuplicate: jest.fn(), - onPublishAndNew: jest.fn(), - onPublishAndDuplicate: jest.fn(), - hasChanged: false, - collection: fromJS({ name: 'posts' }), - hasWorkflow: false, - useOpenAuthoring: false, - hasUnpublishedChanges: false, - isNewEntry: false, - isModification: false, - onLogoutClick: jest.fn(), - loadDeployPreview: jest.fn(), - t: jest.fn(key => key), - editorBackLink: '', - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should render with default props', () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); - - [false, true].forEach(useOpenAuthoring => { - it(`should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=true,useOpenAuthoring=${useOpenAuthoring}`, () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - - it(`should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=false,useOpenAuthoring=${useOpenAuthoring}`, () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - - it(`should render with workflow controls hasUnpublishedChanges=false,isNewEntry=false,isModification=false,useOpenAuthoring=${useOpenAuthoring}`, () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - - ['draft', 'pending_review', 'pending_publish'].forEach(status => { - it(`should render with status=${status},useOpenAuthoring=${useOpenAuthoring}`, () => { - const { asFragment } = render( - , - ); - expect(asFragment()).toMatchSnapshot(); - }); - }); - - it(`should render normal save button`, () => { - const { asFragment } = render(); - expect(asFragment()).toMatchSnapshot(); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap b/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap deleted file mode 100644 index 37b5d550..00000000 --- a/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/Editor.spec.js.snap +++ /dev/null @@ -1,45 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Editor should render editor interface when entry is not fetching 1`] = ` - - - -`; - -exports[`Editor should render loader when entry is fetching 1`] = ` - - - editor.editor.loadingEntry - - -`; - -exports[`Editor should render loader when entryDraft entry is undefined 1`] = ` - - - editor.editor.loadingEntry - - -`; - -exports[`Editor should render loader when entryDraft is null 1`] = ` - - - editor.editor.loadingEntry - - -`; diff --git a/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap b/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap deleted file mode 100644 index 09201b98..00000000 --- a/packages/netlify-cms-core/src/components/Editor/__tests__/__snapshots__/EditorToolbar.spec.js.snap +++ /dev/null @@ -1,4020 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`EditorToolbar should render normal save button 1`] = ` - - .emotion-21 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-17 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-13 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-11 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-11 { - padding: 0 10px; - } -} - -.emotion-15 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-19 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-9 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-9 .ei6fm2r1 { - color: #17a2b8; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #ff003b; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #17a2b8; -} - -.emotion-6:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-6 { - padding-left: 10px; - } -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.unsavedChanges -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render normal save button 2`] = ` - - .emotion-21 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-17 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-13 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-11 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-11 { - padding: 0 10px; - } -} - -.emotion-15 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-19 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-9 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-9 .ei6fm2r1 { - color: #17a2b8; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #ff003b; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #17a2b8; -} - -.emotion-6:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-6 { - padding-left: 10px; - } -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.unsavedChanges -
    -
    -
    -
    -
    -
    -
    - -
    -
    -
    - -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with default props 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #ddf5f9; - color: #17a2b8; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=draft,useOpenAuthoring=false 1`] = ` - - .emotion-23 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-19 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-15 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-13 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-13 { - padding: 0 10px; - } -} - -.emotion-17 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-21 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .ei6fm2r1 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=draft,useOpenAuthoring=true 1`] = ` - - .emotion-30 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-26 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-22 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-24 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-28 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .emotion-13 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -.emotion-20 { - position: relative; -} - -.emotion-16 { - position: relative; - display: inline-block; -} - -.emotion-16:hover + .emotion-19 { - visibility: visible; - opacity: 0.9; -} - -.emotion-14 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-14 path:not(.no-fill), -.emotion-14 circle:not(.no-fill), -.emotion-14 polygon:not(.no-fill), -.emotion-14 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-14 path.clipped { - fill: transparent; -} - -.emotion-14 svg { - width: 100%; - height: 100%; -} - -.emotion-18 { - visibility: hidden; - width: 321px; - background-color: #555; - color: #fff; - text-align: unset; - border-radius: 6px; - padding: 5px; - position: absolute; - z-index: 1; - top: 145%; - left: 50%; - margin-left: -320px; - opacity: 0; - -webkit-transition: opacity 0.3s; - transition: opacity 0.3s; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - -
    -
    - editor.editorToolbar.statusInfoTooltipDraft -
    -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=pending_publish,useOpenAuthoring=false 1`] = ` - - .emotion-23 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-19 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-15 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-13 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-13 { - padding: 0 10px; - } -} - -.emotion-17 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-21 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .ei6fm2r1 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=pending_publish,useOpenAuthoring=true 1`] = ` - - .emotion-28 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-24 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-20 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-22 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-26 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .emotion-13 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -.emotion-18 { - position: relative; -} - -.emotion-16 { - position: relative; - display: inline-block; -} - -.emotion-16:hover + .evqrzhe0 { - visibility: visible; - opacity: 0.9; -} - -.emotion-14 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-14 path:not(.no-fill), -.emotion-14 circle:not(.no-fill), -.emotion-14 polygon:not(.no-fill), -.emotion-14 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-14 path.clipped { - fill: transparent; -} - -.emotion-14 svg { - width: 100%; - height: 100%; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - -
    -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring=false 1`] = ` - - .emotion-23 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-19 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-15 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-13 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-13 { - padding: 0 10px; - } -} - -.emotion-17 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-21 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .ei6fm2r1 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with status=pending_review,useOpenAuthoring=true 1`] = ` - - .emotion-30 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-26 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-22 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-24 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-28 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -.emotion-11 { - position: relative; - font-size: 14px; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - margin: 0 10px; -} - -.emotion-11 .emotion-13 { - color: #17a2b8; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - display: block; - padding-left: 20px; - padding-right: 40px; - position: relative; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - background-color: #ddf5f9; - color: #17a2b8; -} - -.emotion-8:after { - color: #fff; - width: 0; - height: 0; - border: 5px solid transparent; - border-radius: 2px; - border-top: 6px solid currentColor; - border-bottom: 0; - content: ''; - display: block; - position: absolute; - top: 16px; - right: 10px; - color: currentColor; -} - -@media (max-width:1200px) { - .emotion-8 { - padding-left: 10px; - } -} - -.emotion-20 { - position: relative; -} - -.emotion-16 { - position: relative; - display: inline-block; -} - -.emotion-16:hover + .emotion-19 { - visibility: visible; - opacity: 0.9; -} - -.emotion-14 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-14 path:not(.no-fill), -.emotion-14 circle:not(.no-fill), -.emotion-14 polygon:not(.no-fill), -.emotion-14 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-14 path.clipped { - fill: transparent; -} - -.emotion-14 svg { - width: 100%; - height: 100%; -} - -.emotion-18 { - visibility: hidden; - width: 321px; - background-color: #555; - color: #fff; - text-align: unset; - border-radius: 6px; - padding: 5px; - position: absolute; - z-index: 1; - top: 145%; - left: 50%; - margin-left: -320px; - opacity: 0; - -webkit-transition: opacity 0.3s; - transition: opacity 0.3s; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - -
    -
    - editor.editorToolbar.statusInfoTooltipInReview -
    -
    -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=false,isNewEntry=false,isModification=false,useOpenAuthoring=false 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=false,isNewEntry=false,isModification=false,useOpenAuthoring=true 1`] = ` - - .emotion-16 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-12 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-8 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=false,useOpenAuthoring=false 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=false,useOpenAuthoring=true 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=true,useOpenAuthoring=false 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    - -`; - -exports[`EditorToolbar should render with workflow controls hasUnpublishedChanges=true,isNewEntry=false,isModification=true,useOpenAuthoring=true 1`] = ` - - .emotion-18 { - box-shadow: 0 2px 6px 0 rgba(68,74,87,0.05),0 1px 3px 0 rgba(68,74,87,0.1),0 2px 54px rgba(0,0,0,0.1); - position: fixed; - top: 0; - left: 0; - width: 100%; - min-width: 800px; - z-index: 300; - background-color: #fff; - height: 66px; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; -} - -.emotion-0 { - color: #313d3e; - font-size: 21px; - font-weight: 600; - margin-right: 16px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-2 { - color: #313d3e; - font-size: 14px; -} - -.emotion-4 { - margin-top: 6px; - font-size: 13px; - line-height: 1; - display: inline-block; - font-weight: 700; - text-transform: uppercase; - color: #005614; -} - -.emotion-14 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - -webkit-flex: 10; - -ms-flex: 10; - flex: 10; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - padding: 0 10px; -} - -.emotion-10 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; -} - -.emotion-8 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #fcefea; - color: #ff003b; -} - -@media (max-width:1200px) { - .emotion-8 { - padding: 0 10px; - } -} - -.emotion-12 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - -ms-flex-pack: end; - justify-content: flex-end; -} - -.emotion-16 { - height: 100%; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - border: 0 solid #dfdfe3; - border-left-width: 1px; - padding: 0 7px; -} - -.emotion-6 { - border: 0; - border-radius: 5px; - cursor: pointer; - height: 36px; - line-height: 36px; - font-weight: 500; - padding: 0 15px; - background-color: #798291; - color: #fff; - margin: 0 10px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: block; - background-color: #e8f5fe; - color: #3a69c7; -} - -@media (max-width:1200px) { - .emotion-6 { - padding: 0 10px; - } -} - -.emotion-6[disabled] { - background-color: #eff0f4; - color: #798291; - cursor: default; -} - -
    - -
    - ← -
    -
    -
    - editor.editorToolbar.backCollection -
    -
    - editor.editorToolbar.changesSaved -
    -
    -
    -
    -
    - - -
    -
    -
    -
    - -
    -
    - -`; diff --git a/packages/netlify-cms-core/src/components/Editor/withWorkflow.js b/packages/netlify-cms-core/src/components/Editor/withWorkflow.js index 47fb52c0..9b4344c9 100644 --- a/packages/netlify-cms-core/src/components/Editor/withWorkflow.js +++ b/packages/netlify-cms-core/src/components/Editor/withWorkflow.js @@ -1,10 +1,10 @@ import React from 'react'; import { connect } from 'react-redux'; +import { loadUnpublishedEntry, persistUnpublishedEntry } from '../../actions/editorialWorkflow'; import { EDITORIAL_WORKFLOW } from '../../constants/publishModes'; import { selectUnpublishedEntry } from '../../reducers'; import { selectAllowDeletion } from '../../reducers/collections'; -import { loadUnpublishedEntry, persistUnpublishedEntry } from '../../actions/editorialWorkflow'; function mapStateToProps(state, ownProps) { const { collections } = state; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/EmptyMessage.js b/packages/netlify-cms-core/src/components/MediaLibrary/EmptyMessage.js index 5890d6e9..bb4825fb 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/EmptyMessage.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/EmptyMessage.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { colors } from 'netlify-cms-ui-default'; + +import { colors } from '../../ui'; const EmptyMessageContainer = styled.div` height: 100%; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrary.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrary.js index efe357e5..8fda51d7 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrary.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrary.js @@ -1,21 +1,23 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import { connect } from 'react-redux'; -import { orderBy, map } from 'lodash'; -import { translate } from 'react-polyglot'; import fuzzy from 'fuzzy'; -import { fileExtension } from 'netlify-cms-lib-util'; +import { map, orderBy } from 'lodash'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import { translate } from 'react-polyglot'; +import { connect } from 'react-redux'; import { - loadMedia as loadMediaAction, - persistMedia as persistMediaAction, + closeMediaLibrary as closeMediaLibraryAction, deleteMedia as deleteMediaAction, insertMedia as insertMediaAction, + loadMedia as loadMediaAction, loadMediaDisplayURL as loadMediaDisplayURLAction, - closeMediaLibrary as closeMediaLibraryAction, + persistMedia as persistMediaAction, } from '../../actions/mediaLibrary'; +import { fileExtension } from '../../lib/util'; import { selectMediaFiles } from '../../reducers/mediaLibrary'; +import alert from '../UI/Alert'; +import confirm from '../UI/Confirm'; import MediaLibraryModal, { fileShape } from './MediaLibraryModal'; /** @@ -171,18 +173,22 @@ class MediaLibrary extends React.Component { event.persist(); event.stopPropagation(); event.preventDefault(); - const { persistMedia, privateUpload, config, t, field } = this.props; + const { persistMedia, privateUpload, config, field } = this.props; const { files: fileList } = event.dataTransfer || event.target; const files = [...fileList]; const file = files[0]; const maxFileSize = config.get('max_file_size'); if (maxFileSize && file.size > maxFileSize) { - window.alert( - t('mediaLibrary.mediaLibrary.fileTooLarge', { - size: Math.floor(maxFileSize / 1000), - }), - ); + alert({ + title: 'mediaLibrary.mediaLibrary.fileTooLargeTitle', + body: { + key: 'mediaLibrary.mediaLibrary.fileTooLargeBody', + options: { + size: Math.floor(maxFileSize / 1000), + }, + }, + }); } else { await persistMedia(file, { privateUpload, field }); @@ -209,10 +215,16 @@ class MediaLibrary extends React.Component { /** * Removes the selected file from the backend. */ - handleDelete = () => { + handleDelete = async () => { const { selectedFile } = this.state; const { files, deleteMedia, privateUpload, t } = this.props; - if (!window.confirm(t('mediaLibrary.mediaLibrary.onDelete'))) { + if ( + !(await confirm({ + title: 'mediaLibrary.mediaLibrary.onDeleteTitle', + body: 'mediaLibrary.mediaLibrary.onDeleteBody', + color: 'error', + })) + ) { return; } const file = files.find(file => selectedFile.key === file.key); diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js index 25ab12d6..ea25657a 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryButtons.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; import copyToClipboard from 'copy-text-to-clipboard'; -import { isAbsolutePath } from 'netlify-cms-lib-util'; -import { buttons, shadows, zIndex } from 'netlify-cms-ui-default'; +import { buttons, shadows, zIndex } from '../../ui'; +import { isAbsolutePath } from '../../lib/util'; import { FileUploadButton } from '../UI'; const styles = { diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCard.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCard.js index 68920677..6dc652c0 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCard.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCard.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; -import { colors, borders, lengths, shadows, effects } from 'netlify-cms-ui-default'; + +import { colors, borders, lengths, shadows, effects } from '../../ui'; const IMAGE_HEIGHT = 160; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCardGrid.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCardGrid.js index 8d13b12e..d2d627c3 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCardGrid.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryCardGrid.js @@ -3,10 +3,10 @@ import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import { Waypoint } from 'react-waypoint'; import { Map } from 'immutable'; -import { colors } from 'netlify-cms-ui-default'; import { FixedSizeGrid as Grid } from 'react-window'; import AutoSizer from 'react-virtualized-auto-sizer'; +import { colors } from '../../ui'; import MediaLibraryCard from './MediaLibraryCard'; function CardWrapper(props) { diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryHeader.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryHeader.js index fe354ab8..5bbffeb5 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryHeader.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryHeader.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { Icon, shadows, colors, buttons } from 'netlify-cms-ui-default'; + +import { Icon, shadows, colors, buttons } from '../../ui'; const CloseButton = styled.button` ${buttons.button}; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js index d2499400..52bfd5b0 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibraryModal.js @@ -4,8 +4,8 @@ import styled from '@emotion/styled'; import { Map } from 'immutable'; import { isEmpty } from 'lodash'; import { translate } from 'react-polyglot'; -import { colors } from 'netlify-cms-ui-default'; +import { colors } from '../../ui'; import { Modal } from '../UI'; import MediaLibraryTop from './MediaLibraryTop'; import MediaLibraryCardGrid from './MediaLibraryCardGrid'; diff --git a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrarySearch.js b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrarySearch.js index 9c188adf..e63aca19 100644 --- a/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrarySearch.js +++ b/packages/netlify-cms-core/src/components/MediaLibrary/MediaLibrarySearch.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { Icon, lengths, colors, zIndex } from 'netlify-cms-ui-default'; + +import { Icon, lengths, colors, zIndex } from '../../ui'; const SearchContainer = styled.div` height: 37px; diff --git a/packages/netlify-cms-core/src/components/UI/Alert.tsx b/packages/netlify-cms-core/src/components/UI/Alert.tsx new file mode 100644 index 00000000..d7b19cd6 --- /dev/null +++ b/packages/netlify-cms-core/src/components/UI/Alert.tsx @@ -0,0 +1,103 @@ +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import React, { useCallback, useMemo, useState } from 'react'; +import { translate, TranslateProps } from 'react-polyglot'; + +import AlertEvent from '../../lib/util/events/AlertEvent'; +import { useWindowEvent } from '../../lib/util/window.util'; + +interface AlertProps { + title: string | { key: string; options?: any }; + body: string | { key: string; options?: any }; + okay?: string | { key: string; options?: any }; + color?: 'success' | 'error' | 'primary'; +} + +export interface AlertDialogProps extends AlertProps { + resolve: () => void; +} + +const AlertDialog = ({ t }: TranslateProps) => { + const [detail, setDetail] = useState(null); + const { + resolve, + title: rawTitle, + body: rawBody, + okay: rawOkay = 'ui.common.okay', + color = 'primary', + } = detail ?? {}; + + const onAlertMessage = useCallback((event: AlertEvent) => { + setDetail(event.detail); + }, []); + + useWindowEvent('alert', onAlertMessage); + + const handleClose = useCallback(() => { + setDetail(null); + resolve?.(); + }, [resolve]); + + const title = useMemo(() => { + if (!rawTitle) { + return ''; + } + return typeof rawTitle === 'string' ? t(rawTitle) : t(rawTitle.key, rawTitle.options); + }, [rawTitle]); + + const body = useMemo(() => { + if (!rawBody) { + return ''; + } + return typeof rawBody === 'string' ? t(rawBody) : t(rawBody.key, rawBody.options); + }, [rawBody]); + + const okay = useMemo( + () => (typeof rawOkay === 'string' ? t(rawOkay) : t(rawOkay.key, rawOkay.options)), + [rawOkay], + ); + + if (!detail) { + return null; + } + + return ( +
    + + {t(title)} + + {body} + + + + + +
    + ); +}; + +export const Alert = translate()(AlertDialog); + +const alert = (props: AlertProps) => { + return new Promise(resolve => { + window.dispatchEvent( + new AlertEvent({ + ...props, + resolve, + }), + ); + }); +}; + +export default alert; diff --git a/packages/netlify-cms-core/src/components/UI/Confirm.tsx b/packages/netlify-cms-core/src/components/UI/Confirm.tsx new file mode 100644 index 00000000..706bb802 --- /dev/null +++ b/packages/netlify-cms-core/src/components/UI/Confirm.tsx @@ -0,0 +1,122 @@ +import Button from '@mui/material/Button'; +import Dialog from '@mui/material/Dialog'; +import DialogActions from '@mui/material/DialogActions'; +import DialogContent from '@mui/material/DialogContent'; +import DialogContentText from '@mui/material/DialogContentText'; +import DialogTitle from '@mui/material/DialogTitle'; +import React, { useCallback, useMemo, useState } from 'react'; +import { translate, TranslateProps } from 'react-polyglot'; + +import ConfirmEvent from '../../lib/util/events/ConfirmEvent'; +import { useWindowEvent } from '../../lib/util/window.util'; + +interface ConfirmProps { + title: string | { key: string; options?: any }; + body: string | { key: string; options?: any }; + cancel?: string | { key: string; options?: any }; + confirm?: string | { key: string; options?: any }; + color?: 'success' | 'error' | 'primary'; +} + +export interface ConfirmDialogProps extends ConfirmProps { + resolve: (value: boolean | PromiseLike) => void; +} + +const ConfirmDialog = ({ t }: TranslateProps) => { + const [detail, setDetail] = useState(null); + const { + resolve, + title: rawTitle, + body: rawBody, + cancel: rawCancel = 'ui.common.no', + confirm: rawConfirm = 'ui.common.yes', + color = 'primary', + } = detail ?? {}; + + const onConfirmMessage = useCallback((event: ConfirmEvent) => { + setDetail(event.detail); + }, []); + + useWindowEvent('confirm', onConfirmMessage); + + const handleClose = useCallback(() => { + setDetail(null); + }, []); + + const handleCancel = useCallback(() => { + resolve?.(false); + handleClose(); + }, [handleClose, resolve]); + + const handleConfirm = useCallback(() => { + resolve?.(true); + handleClose(); + }, [handleClose, resolve]); + + const title = useMemo(() => { + if (!rawTitle) { + return ''; + } + return typeof rawTitle === 'string' ? t(rawTitle) : t(rawTitle.key, rawTitle.options); + }, [rawTitle]); + + const body = useMemo(() => { + if (!rawBody) { + return ''; + } + return typeof rawBody === 'string' ? t(rawBody) : t(rawBody.key, rawBody.options); + }, [rawBody]); + + const cancel = useMemo( + () => (typeof rawCancel === 'string' ? t(rawCancel) : t(rawCancel.key, rawCancel.options)), + [rawCancel], + ); + + const confirm = useMemo( + () => (typeof rawConfirm === 'string' ? t(rawConfirm) : t(rawConfirm.key, rawConfirm.options)), + [rawConfirm], + ); + + if (!detail) { + return null; + } + + return ( +
    + + {title} + + {body} + + + + + + +
    + ); +}; + +export const Confirm = translate()(ConfirmDialog); + +const confirm = (props: ConfirmProps) => { + return new Promise(resolve => { + window.dispatchEvent( + new ConfirmEvent({ + ...props, + resolve, + }), + ); + }); +}; + +export default confirm; diff --git a/packages/netlify-cms-core/src/components/UI/ErrorBoundary.js b/packages/netlify-cms-core/src/components/UI/ErrorBoundary.js index 173be80a..d3abc94d 100644 --- a/packages/netlify-cms-core/src/components/UI/ErrorBoundary.js +++ b/packages/netlify-cms-core/src/components/UI/ErrorBoundary.js @@ -5,10 +5,11 @@ import styled from '@emotion/styled'; import yaml from 'yaml'; import { truncate } from 'lodash'; import copyToClipboard from 'copy-text-to-clipboard'; -import { localForage } from 'netlify-cms-lib-util'; -import { buttons, colors } from 'netlify-cms-ui-default'; import cleanStack from 'clean-stack'; +import { buttons, colors } from '../../ui'; +import { localForage } from '../../lib/util'; + const ISSUE_URL = 'https://github.com/netlify/netlify-cms/issues/new?'; function getIssueTemplate({ version, provider, browser, config }) { @@ -39,8 +40,6 @@ function buildIssueTemplate({ config }) { let version = ''; if (typeof NETLIFY_CMS_VERSION === 'string') { version = `netlify-cms@${NETLIFY_CMS_VERSION}`; - } else if (typeof NETLIFY_CMS_APP_VERSION === 'string') { - version = `netlify-cms-app@${NETLIFY_CMS_APP_VERSION}`; } const template = getIssueTemplate({ version, @@ -63,7 +62,7 @@ function buildIssueUrl({ title, config }) { return `${ISSUE_URL}${params.toString()}`; } catch (e) { - console.log(e); + console.info(e); return `${ISSUE_URL}template=bug_report.md`; } } @@ -111,7 +110,7 @@ const CopyButton = styled.button` `; function RecoveredEntry({ entry, t }) { - console.log(entry); + console.info(entry); return ( <>
    @@ -162,7 +161,7 @@ export class ErrorBoundary extends React.Component { async componentDidUpdate() { if (this.props.showBackup) { const backup = await localForage.getItem('backup'); - backup && console.log(backup); + backup && console.info(backup); this.setState({ backup }); } } diff --git a/packages/netlify-cms-core/src/components/UI/Modal.js b/packages/netlify-cms-core/src/components/UI/Modal.js index 98ab6fc5..67725b8a 100644 --- a/packages/netlify-cms-core/src/components/UI/Modal.js +++ b/packages/netlify-cms-core/src/components/UI/Modal.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { css, Global, ClassNames } from '@emotion/react'; import ReactModal from 'react-modal'; -import { transitions, shadows, lengths, zIndex } from 'netlify-cms-ui-default'; + +import { transitions, shadows, lengths, zIndex } from '../../ui'; function ReactModalGlobalStyles() { return ( @@ -31,7 +32,7 @@ const styleStrings = { } `, overlay: ` - z-index: ${zIndex.zIndex99999}; + z-index: ${zIndex.zIndex1002}; position: fixed; top: 0; left: 0; diff --git a/packages/netlify-cms-core/src/components/UI/SettingsDropdown.js b/packages/netlify-cms-core/src/components/UI/SettingsDropdown.js index c429af17..36908927 100644 --- a/packages/netlify-cms-core/src/components/UI/SettingsDropdown.js +++ b/packages/netlify-cms-core/src/components/UI/SettingsDropdown.js @@ -3,8 +3,8 @@ import PropTypes from 'prop-types'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; -import { Icon, Dropdown, DropdownItem, DropdownButton, colors } from 'netlify-cms-ui-default'; +import { Icon, Dropdown, DropdownItem, DropdownButton, colors } from '../../ui'; import { stripProtocol } from '../../lib/urlHelper'; const styles = { diff --git a/packages/netlify-cms-core/src/components/UI/Toast.js b/packages/netlify-cms-core/src/components/UI/Toast.js deleted file mode 100644 index f0b94530..00000000 --- a/packages/netlify-cms-core/src/components/UI/Toast.js +++ /dev/null @@ -1,67 +0,0 @@ -// eslint-disable-next-line no-unused-vars -import React from 'react'; -import PropTypes from 'prop-types'; -import { css, Global } from '@emotion/react'; -import { translate } from 'react-polyglot'; -import reduxNotificationsStyles from 'redux-notifications/lib/styles.css'; -import { shadows, colors, lengths, zIndex } from 'netlify-cms-ui-default'; - -function ReduxNotificationsGlobalStyles() { - return ( - - ); -} - -const styles = { - toast: css` - ${shadows.drop}; - background-color: ${colors.background}; - color: ${colors.textLight}; - border-radius: ${lengths.borderRadius}; - margin: 50px; - padding: 20px; - overflow: hidden; - `, - info: css` - background-color: ${colors.infoBackground}; - color: ${colors.infoText}; - `, - success: css` - background-color: ${colors.successBackground}; - color: ${colors.successText}; - `, - warning: css` - background-color: ${colors.warnBackground}; - color: ${colors.warnText}; - `, - danger: css` - background-color: ${colors.errorBackground}; - color: ${colors.errorText}; - `, -}; - -function Toast({ kind, message, t }) { - return ( -
    - - {t(message.key, { details: message.details })} -
    - ); -} - -Toast.propTypes = { - kind: PropTypes.oneOf(['info', 'success', 'warning', 'danger']).isRequired, - message: PropTypes.object, - t: PropTypes.func.isRequired, -}; - -export default translate()(Toast); diff --git a/packages/netlify-cms-core/src/components/UI/__tests__/ErrorBoundary.spec.js b/packages/netlify-cms-core/src/components/UI/__tests__/ErrorBoundary.spec.js deleted file mode 100644 index c5884b7e..00000000 --- a/packages/netlify-cms-core/src/components/UI/__tests__/ErrorBoundary.spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import { oneLineTrim } from 'common-tags'; - -import { ErrorBoundary } from '../ErrorBoundary'; - -function WithError() { - throw new Error('Some unknown error'); -} - -jest.spyOn(console, 'error').mockImplementation(() => ({})); - -Object.defineProperty( - window.navigator, - 'userAgent', - (value => ({ - get() { - return value; - }, - set(v) { - value = v; - }, - }))(window.navigator['userAgent']), -); - -describe('Editor', () => { - const config = { backend: { name: 'github' } }; - - const props = { t: jest.fn(key => key), config }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should match snapshot with issue URL', () => { - global.navigator.userAgent = 'Test User Agent'; - const { getByTestId } = render( - - - , - ); - - expect(console.error).toHaveBeenCalledWith(new Error('Some unknown error')); - expect(getByTestId('issue-url').getAttribute('href')).toEqual( - oneLineTrim`https://github.com/netlify/netlify-cms/issues/new? - title=Error%3A+Some+unknown+error& - body=%0A**Describe+the+bug**%0A%0A**To+Reproduce**%0A%0A**Expected+behavior**%0A%0A** - Screenshots**%0A%0A**Applicable+Versions%3A**%0A+-+ - Netlify+CMS+version%3A+%60%60%0A+-+ - Git+provider%3A+%60github%60%0A+-+ - Browser+version%3A+%60Test+User+Agent%60%0A%0A** - CMS+configuration**%0A%60%60%60%0Abackend%3A%0A++name%3A+github%0A%0A%60%60%60%0A%0A** - Additional+context**%0A&labels=type%3A+bug - `, - ); - }); -}); diff --git a/packages/netlify-cms-core/src/components/UI/index.js b/packages/netlify-cms-core/src/components/UI/index.js index 5d84fa9a..8f58d1cd 100644 --- a/packages/netlify-cms-core/src/components/UI/index.js +++ b/packages/netlify-cms-core/src/components/UI/index.js @@ -2,5 +2,4 @@ export { DragSource, DropTarget, HTML5DragDrop } from './DragDrop'; export { default as ErrorBoundary } from './ErrorBoundary'; export { FileUploadButton } from './FileUploadButton'; export { Modal } from './Modal'; -export { default as Toast } from './Toast'; export { default as SettingsDropdown } from './SettingsDropdown'; diff --git a/packages/netlify-cms-core/src/components/Workflow/Workflow.js b/packages/netlify-cms-core/src/components/Workflow/Workflow.js index eaf261fa..796b2a81 100644 --- a/packages/netlify-cms-core/src/components/Workflow/Workflow.js +++ b/packages/netlify-cms-core/src/components/Workflow/Workflow.js @@ -5,6 +5,7 @@ import styled from '@emotion/styled'; import { OrderedMap } from 'immutable'; import { translate } from 'react-polyglot'; import { connect } from 'react-redux'; + import { Dropdown, DropdownItem, @@ -13,8 +14,7 @@ import { lengths, components, shadows, -} from 'netlify-cms-ui-default'; - +} from '../../ui'; import { createNewEntry } from '../../actions/collections'; import { loadUnpublishedEntries, @@ -28,7 +28,7 @@ import WorkflowList from './WorkflowList'; const WorkflowContainer = styled.div` padding: ${lengths.pageMargin} 0; - height: 100vh; + height: calc(100vh - 56px); `; const WorkflowTop = styled.div` diff --git a/packages/netlify-cms-core/src/components/Workflow/WorkflowCard.js b/packages/netlify-cms-core/src/components/Workflow/WorkflowCard.js index 7d091ca2..ebfa5a4a 100644 --- a/packages/netlify-cms-core/src/components/Workflow/WorkflowCard.js +++ b/packages/netlify-cms-core/src/components/Workflow/WorkflowCard.js @@ -4,7 +4,8 @@ import { css } from '@emotion/react'; import styled from '@emotion/styled'; import { translate } from 'react-polyglot'; import { Link } from 'react-router-dom'; -import { components, colors, colorsRaw, transitions, buttons } from 'netlify-cms-ui-default'; + +import { components, colors, colorsRaw, transitions, buttons } from '../../ui'; const styles = { text: css` diff --git a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js index 2e7aed77..63243afa 100644 --- a/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js +++ b/packages/netlify-cms-core/src/components/Workflow/WorkflowList.js @@ -1,16 +1,18 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; import moment from 'moment'; +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; import { translate } from 'react-polyglot'; -import { colors, lengths } from 'netlify-cms-ui-default'; import { status } from '../../constants/publishModes'; -import { DragSource, DropTarget, HTML5DragDrop } from '../UI'; -import WorkflowCard from './WorkflowCard'; import { selectEntryCollectionTitle } from '../../reducers/collections'; +import { colors, lengths } from '../../ui'; +import { DragSource, DropTarget, HTML5DragDrop } from '../UI'; +import alert from '../UI/Alert'; +import confirm from '../UI/Confirm'; +import WorkflowCard from './WorkflowCard'; const WorkflowListContainer = styled.div` min-height: 60%; @@ -146,17 +148,30 @@ class WorkflowList extends React.Component { this.props.handleChangeStatus(collection, slug, oldStatus, newStatus); }; - requestDelete = (collection, slug, ownStatus) => { - if (window.confirm(this.props.t('workflow.workflowList.onDeleteEntry'))) { + requestDelete = async (collection, slug, ownStatus) => { + if ( + await confirm({ + title: 'workflow.workflowList.onDeleteEntryTitle', + body: 'workflow.workflowList.onDeleteEntryBody', + }) + ) { this.props.handleDelete(collection, slug, ownStatus); } }; - requestPublish = (collection, slug, ownStatus) => { + requestPublish = async (collection, slug, ownStatus) => { if (ownStatus !== status.last()) { - window.alert(this.props.t('workflow.workflowList.onPublishingNotReadyEntry')); + alert({ + title: 'workflow.workflowList.onPublishingNotReadyEntryTitle', + body: 'workflow.workflowList.onPublishingNotReadyEntryBody', + }); return; - } else if (!window.confirm(this.props.t('workflow.workflowList.onPublishEntry'))) { + } else if ( + !(await confirm({ + title: 'workflow.workflowList.onPublishEntryTitle', + body: 'workflow.workflowList.onPublishEntryBody', + })) + ) { return; } this.props.handlePublish(collection, slug); diff --git a/packages/netlify-cms-core/src/components/page/Page.tsx b/packages/netlify-cms-core/src/components/page/Page.tsx new file mode 100644 index 00000000..6b76ea87 --- /dev/null +++ b/packages/netlify-cms-core/src/components/page/Page.tsx @@ -0,0 +1,106 @@ +import { styled } from '@mui/material/styles'; +import React, { useMemo } from 'react'; +import { translate } from 'react-polyglot'; +import { connect } from 'react-redux'; + +import { getAdditionalLink } from '../../lib/registry'; +import { Collections, State } from '../../types/redux'; +import { lengths } from '../../ui'; +import Sidebar from '../Collection/Sidebar'; + +const StylePage = styled('div')` + margin: ${lengths.pageMargin}; +`; + +const StyledPageContent = styled('div')` + width: 100%; + display: flex; + align-items: center; + justify-content: center; +`; + +interface PageProps { + match: any; +} + +interface ConnectedPageProps extends PageProps { + collections: Collections; + isSearchEnabled: boolean; + searchTerm: string; + filterTerm: string; +} + +const Page = ({ + match, + collections, + isSearchEnabled, + searchTerm, + filterTerm, +}: ConnectedPageProps) => { + const { id } = match.params; + const Content = useMemo(() => { + const page = getAdditionalLink(id); + if (!page) { + return ''; + } + + return page.data; + }, []); + + const pageContent = useMemo(() => { + if (!Content) { + return Page not found; + } + + return ( + + + + ); + }, [Content]); + + return ( + + + {pageContent} + + ); +}; + +function mapStateToProps(state: State, ownProps: PageProps) { + const { collections } = state; + const isSearchEnabled = state.config && state.config.search != false; + const { match } = ownProps; + const { searchTerm = '', filterTerm = '' } = match.params; + + return { + collections, + isSearchEnabled, + searchTerm, + filterTerm, + }; +} + +const mapDispatchToProps = {}; + +function mergeProps( + stateProps: ReturnType, + dispatchProps: typeof mapDispatchToProps, + ownProps: PageProps, +) { + return { + ...stateProps, + ...dispatchProps, + ...ownProps, + }; +} + +const ConnectedPage = connect(mapStateToProps, mapDispatchToProps, mergeProps)(Page); + +export default translate()(ConnectedPage); diff --git a/packages/netlify-cms-core/src/components/snackbar/Snackbars.tsx b/packages/netlify-cms-core/src/components/snackbar/Snackbars.tsx new file mode 100644 index 00000000..d83ee9f7 --- /dev/null +++ b/packages/netlify-cms-core/src/components/snackbar/Snackbars.tsx @@ -0,0 +1,84 @@ +import CloseIcon from '@mui/icons-material/Close'; +import Alert from '@mui/material/Alert'; +import IconButton from '@mui/material/IconButton'; +import Snackbar from '@mui/material/Snackbar'; +import React, { useCallback, useEffect, useState } from 'react'; +import { translate } from 'react-polyglot'; + +import { useAppDispatch, useAppSelector } from '../../store/hooks'; +import { removeSnackbarById, selectSnackbars } from '../../store/slices/snackbars'; + +import type { TranslatedProps } from '../../interface'; +import type { SnackbarMessage } from '../../store/slices/snackbars'; + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface SnackbarsProps {} + +const Snackbars = ({ t }: TranslatedProps) => { + const [open, setOpen] = React.useState(false); + const [messageInfo, setMessageInfo] = useState(undefined); + + const snackbars = useAppSelector(selectSnackbars); + const dispatch = useAppDispatch(); + + useEffect(() => { + if (snackbars.length && !messageInfo) { + // Set a new snack when we don't have an active one + const snackbar = { ...snackbars[0] }; + setMessageInfo(snackbar); + dispatch(removeSnackbarById(snackbar.id)); + setOpen(true); + } else if (snackbars.length && messageInfo && open) { + // Close an active snack when a new one is added + setOpen(false); + } + }, [snackbars, messageInfo, open]); + + const handleClose = useCallback((_event?: React.SyntheticEvent | Event, reason?: string) => { + if (reason === 'clickaway') { + return; + } + + setOpen(false); + }, []); + + const handleExited = () => { + setMessageInfo(undefined); + }; + + const renderAlert = useCallback( + (data: SnackbarMessage) => { + const { + type, + message: { key, ...options }, + } = data; + + return ( + + {t(key, options)} + + ); + }, + [handleClose, t], + ); + + return ( + + + + } + > + {messageInfo ? renderAlert(messageInfo) : undefined} + + ); +}; + +export default translate()(Snackbars); diff --git a/packages/netlify-cms-core/src/constants/collectionTypes.ts b/packages/netlify-cms-core/src/constants/collectionTypes.ts index c660c9bc..df9c9467 100644 --- a/packages/netlify-cms-core/src/constants/collectionTypes.ts +++ b/packages/netlify-cms-core/src/constants/collectionTypes.ts @@ -1,2 +1,4 @@ export const FILES = 'file_based_collection'; export const FOLDER = 'folder_based_collection'; + +export type CollectionType = typeof FILES | typeof FOLDER; diff --git a/packages/netlify-cms-core/src/constants/configSchema.js b/packages/netlify-cms-core/src/constants/configSchema.js index c8780b85..efb8465f 100644 --- a/packages/netlify-cms-core/src/constants/configSchema.js +++ b/packages/netlify-cms-core/src/constants/configSchema.js @@ -4,7 +4,7 @@ import { uniqueItemProperties, instanceof as instanceOf, prohibited, -} from 'ajv-keywords/dist/keywords'; +} from 'ajv-keywords/keywords'; import ajvErrors from 'ajv-errors'; import uuid from 'uuid/v4'; @@ -249,16 +249,28 @@ function getConfigSchema() { }, fields: fieldsConfig(), sortable_fields: { - type: 'array', - items: { - type: 'string', - }, - }, - sortableFields: { - type: 'array', - items: { - type: 'string', + type: 'object', + properties: { + default: { + type: 'object', + properties: { + field: { + type: 'string', + }, + direction: { + type: 'string', + }, + }, + required: ['field'], + }, + fields: { + type: 'array', + items: { + type: 'string', + }, + }, }, + required: ['fields'], }, view_filters: viewFilters, view_groups: viewGroups, @@ -290,9 +302,6 @@ function getConfigSchema() { }, required: ['name', 'label'], oneOf: [{ required: ['files'] }, { required: ['folder', 'fields'] }], - not: { - required: ['sortable_fields', 'sortableFields'], - }, if: { required: ['extension'] }, then: { // Cannot infer format from extension. @@ -334,8 +343,8 @@ function getWidgetSchemas() { class ConfigError extends Error { constructor(errors, ...args) { const message = errors - .map(({ message, instancePath }) => { - const dotPath = instancePath + .map(({ message, dataPath }) => { + const dotPath = dataPath .slice(1) .split('/') .map(seg => (seg.match(/^\d+$/) ? `[${seg}]` : `.${seg}`)) @@ -360,7 +369,7 @@ class ConfigError extends Error { * the config that is passed in. */ export function validateConfig(config) { - const ajv = new AJV({ allErrors: true, $data: true, strict: false }); + const ajv = new AJV({ allErrors: true, $data: true }); uniqueItemProperties(ajv); select(ajv); instanceOf(ajv); @@ -373,7 +382,7 @@ export function validateConfig(config) { switch (e.keyword) { // TODO: remove after https://github.com/ajv-validator/ajv-keywords/pull/123 is merged case 'uniqueItemProperties': { - const path = e.instancePath || ''; + const path = e.dataPath || ''; let newError = e; if (path.endsWith('/fields')) { newError = { ...e, message: 'fields names must be unique' }; @@ -385,12 +394,12 @@ export function validateConfig(config) { return newError; } case 'instanceof': { - const path = e.instancePath || ''; + const path = e.dataPath || ''; let newError = e; if (/fields\/\d+\/pattern\/\d+/.test(path)) { newError = { ...e, - message: 'must be a regular expression', + message: 'should be a regular expression', }; } return newError; diff --git a/packages/netlify-cms-editor-component-image/src/index.js b/packages/netlify-cms-core/src/editor-components/image/index.js similarity index 100% rename from packages/netlify-cms-editor-component-image/src/index.js rename to packages/netlify-cms-core/src/editor-components/image/index.js diff --git a/packages/netlify-cms-core/src/editor-components/index.tsx b/packages/netlify-cms-core/src/editor-components/index.tsx new file mode 100644 index 00000000..8b4cbe43 --- /dev/null +++ b/packages/netlify-cms-core/src/editor-components/index.tsx @@ -0,0 +1,3 @@ +import imageEditorComponent from './image'; + +export { imageEditorComponent }; diff --git a/packages/netlify-cms-core/src/index.js b/packages/netlify-cms-core/src/index.js deleted file mode 100644 index 439218fc..00000000 --- a/packages/netlify-cms-core/src/index.js +++ /dev/null @@ -1,8 +0,0 @@ -import bootstrap from './bootstrap'; -import Registry from './lib/registry'; - -export const NetlifyCmsCore = { - ...Registry, - init: bootstrap, -}; -export default NetlifyCmsCore; diff --git a/packages/netlify-cms-core/src/index.jsx b/packages/netlify-cms-core/src/index.jsx new file mode 100644 index 00000000..9a9909e5 --- /dev/null +++ b/packages/netlify-cms-core/src/index.jsx @@ -0,0 +1,40 @@ +import createReactClass from 'create-react-class'; +import React from 'react'; + +import bootstrap from './bootstrap'; +import Registry from './lib/registry'; +import * as backends from './backends'; +import * as widgets from './widgets'; +import * as mediaLibraries from './media-libraries'; +import * as editorComponents from './editor-components'; +import * as locales from './locales'; +import * as lib from './lib'; +import * as ui from './ui'; + +export * from './backends'; +export * from './widgets'; +export * from './media-libraries'; +export * from './editor-components'; +export * from './locales'; +export * from './lib'; +export * from './ui'; + +export const CMS = { + ...Registry, + ...backends, + ...widgets, + ...mediaLibraries, + ...editorComponents, + ...locales, + ...lib, + ...ui, + init: bootstrap, +}; + +if (typeof window !== 'undefined') { + window.CMS = CMS; + window.createClass = window.createClass || createReactClass; + window.h = window.h || React.createElement; +} + +export default CMS; diff --git a/packages/netlify-cms-core/src/integrations/providers/algolia/implementation.js b/packages/netlify-cms-core/src/integrations/providers/algolia/implementation.js index 9d4331b3..205beab7 100644 --- a/packages/netlify-cms-core/src/integrations/providers/algolia/implementation.js +++ b/packages/netlify-cms-core/src/integrations/providers/algolia/implementation.js @@ -1,6 +1,6 @@ import _ from 'lodash'; -import { unsentRequest } from 'netlify-cms-lib-util'; +import { unsentRequest } from '../../../lib/util'; import { createEntry } from '../../../valueObjects/Entry'; import { selectEntrySlug } from '../../../reducers/collections'; diff --git a/packages/netlify-cms-core/src/integrations/providers/assetStore/implementation.js b/packages/netlify-cms-core/src/integrations/providers/assetStore/implementation.js index 52929498..a53ad601 100644 --- a/packages/netlify-cms-core/src/integrations/providers/assetStore/implementation.js +++ b/packages/netlify-cms-core/src/integrations/providers/assetStore/implementation.js @@ -1,6 +1,6 @@ import { pickBy, trimEnd } from 'lodash'; -import { unsentRequest } from 'netlify-cms-lib-util'; +import { unsentRequest } from '../../../lib/util'; import { addParams } from '../../../lib/urlHelper'; const { fetchWithTimeout: fetch } = unsentRequest; diff --git a/packages/netlify-cms-core/src/interface.ts b/packages/netlify-cms-core/src/interface.ts new file mode 100644 index 00000000..cbe1c5a4 --- /dev/null +++ b/packages/netlify-cms-core/src/interface.ts @@ -0,0 +1,778 @@ +import type { List, Map } from 'immutable'; +import type { ComponentType, FocusEventHandler, ReactNode } from 'react'; +import type { t, TranslateProps as ReactPolyglotTranslateProps } from 'react-polyglot'; +import type { Pluggable } from 'unified'; +import type Cursor from './lib/util/Cursor'; +import type { CollectionType } from './constants/collectionTypes'; + +export type TranslatedProps = T & ReactPolyglotTranslateProps; + +export type GetAssetFunction = (asset: string) => { + url: string; + path: string; + field?: any; + fileObj: File; +}; + +export interface CmsWidgetControlProps { + value: T; + field: Map; + onChange: (value: T) => void; + forID: string; + classNameWrapper: string; + setActiveStyle: FocusEventHandler; + setInactiveStyle: FocusEventHandler; + t: t; +} + +export interface CmsWidgetPreviewProps { + value: T; + field: Map; + metadata: Map; + getAsset: GetAssetFunction; + entry: Map; + fieldsMetaData: Map; +} + +export interface CmsWidgetParam { + name: string; + controlComponent: ComponentType>; + previewComponent?: ComponentType>; + validator?: (props: { + field: Map; + value: T | undefined | null; + t: t; + }) => boolean | { error: any } | Promise; + globalStyles?: any; +} + +export interface CmsWidget { + control: ComponentType>; + preview?: ComponentType>; + globalStyles?: any; +} + +export type PreviewTemplateComponentProps = { + entry: Map; + collection: Map; + widgetFor: (name: any, fields?: any, values?: any, fieldsMetaData?: any) => JSX.Element | null; + widgetsFor: (name: any) => any; + getAsset: GetAssetFunction; + boundGetAsset: (collection: any, path: any) => GetAssetFunction; + fieldsMetaData: Map; + config: Map; + fields: List>; + isLoadingAsset: boolean; + window: Window; + document: Document; +}; +export type DisplayURLObject = { id: string; path: string }; + +export type DisplayURL = DisplayURLObject | string; + +export type DataFile = { + path: string; + slug: string; + raw: string; + newPath?: string; +}; + +export type AssetProxy = { + path: string; + fileObj?: File; + toBase64?: () => Promise; +}; + +export type Entry = { + dataFiles: DataFile[]; + assets: AssetProxy[]; +}; + +export type PersistOptions = { + newEntry?: boolean; + commitMessage: string; + collectionName?: string; + useWorkflow?: boolean; + unpublished?: boolean; + status?: string; +}; + +export type DeleteOptions = {}; + +export type Credentials = { token: string | {}; refresh_token?: string }; + +export type User = Credentials & { + backendName?: string; + login?: string; + name: string; + useOpenAuthoring?: boolean; +}; + +export interface ImplementationEntry { + data: string; + file: { path: string; label?: string; id?: string | null; author?: string; updatedOn?: string }; +} + +export type ImplementationFile = { + id?: string | null | undefined; + label?: string; + path: string; +}; +export interface ImplementationMediaFile { + name: string; + id: string; + size?: number; + displayURL?: DisplayURL; + path: string; + draft?: boolean; + url?: string; + file?: File; +} + +export interface UnpublishedEntryMediaFile { + id: string; + path: string; +} + +export interface UnpublishedEntryDiff { + id: string; + path: string; + newFile: boolean; +} + +export interface UnpublishedEntry { + pullRequestAuthor?: string; + slug: string; + collection: string; + status: string; + diffs: UnpublishedEntryDiff[]; + updatedAt: string; +} + +export type CursorStoreObject = { + actions: Set; + data: Map; + meta: Map; +}; + +export type CursorStore = { + get( + key: K, + defaultValue?: CursorStoreObject[K], + ): CursorStoreObject[K]; + getIn(path: string[]): V; + set( + key: K, + value: V, + ): CursorStoreObject[K]; + setIn(path: string[], value: unknown): CursorStore; + hasIn(path: string[]): boolean; + mergeIn(path: string[], value: unknown): CursorStore; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + update: (...args: any[]) => CursorStore; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + updateIn: (...args: any[]) => CursorStore; +}; + +export interface Implementation { + authComponent: () => void; + restoreUser: (user: User) => Promise; + + authenticate: (credentials: Credentials) => Promise; + logout: () => Promise | void | null; + getToken: () => Promise; + + getEntry: (path: string) => Promise; + entriesByFolder: ( + folder: string, + extension: string, + depth: number, + ) => Promise; + entriesByFiles: (files: ImplementationFile[]) => Promise; + + getMediaDisplayURL?: (displayURL: DisplayURL) => Promise; + getMedia: (folder?: string) => Promise; + getMediaFile: (path: string) => Promise; + + persistEntry: (entry: Entry, opts: PersistOptions) => Promise; + persistMedia: (file: AssetProxy, opts: PersistOptions) => Promise; + deleteFiles: (paths: string[], commitMessage: string) => Promise; + + unpublishedEntries: () => Promise; + unpublishedEntry: (args: { + id?: string; + collection?: string; + slug?: string; + }) => Promise; + unpublishedEntryDataFile: ( + collection: string, + slug: string, + path: string, + id: string, + ) => Promise; + unpublishedEntryMediaFile: ( + collection: string, + slug: string, + path: string, + id: string, + ) => Promise; + updateUnpublishedEntryStatus: ( + collection: string, + slug: string, + newStatus: string, + ) => Promise; + publishUnpublishedEntry: (collection: string, slug: string) => Promise; + deleteUnpublishedEntry: (collection: string, slug: string) => Promise; + getDeployPreview: ( + collectionName: string, + slug: string, + ) => Promise<{ url: string; status: string } | null>; + + allEntriesByFolder?: ( + folder: string, + extension: string, + depth: number, + ) => Promise; + traverseCursor?: ( + cursor: Cursor, + action: string, + ) => Promise<{ entries: ImplementationEntry[]; cursor: Cursor }>; + + isGitBackend?: () => boolean; + status: () => Promise<{ + auth: { status: boolean }; + api: { status: boolean; statusPage: string }; + }>; +} + +export interface CmsRegistryBackend { + init: (args: any) => Implementation; +} + +export type CmsLocalePhrases = Record; // TODO: type properly + +export type CmsWidgetValueSerializer = any; // TODO: type properly + +export type CmsMediaLibraryOptions = any; // TODO: type properly + +export interface CmsMediaLibrary { + name: string; + config?: CmsMediaLibraryOptions; +} + +export interface PreviewStyleOptions { + raw: boolean; +} + +export interface PreviewStyle extends PreviewStyleOptions { + value: string; +} + +export type CmsBackendType = + | 'azure' + | 'git-gateway' + | 'github' + | 'gitlab' + | 'bitbucket' + | 'test-repo' + | 'proxy'; + +export type CmsMapWidgetType = 'Point' | 'LineString' | 'Polygon'; + +export type CmsMarkdownWidgetButton = + | 'bold' + | 'italic' + | 'code' + | 'link' + | 'heading-one' + | 'heading-two' + | 'heading-three' + | 'heading-four' + | 'heading-five' + | 'heading-six' + | 'quote' + | 'code-block' + | 'bulleted-list' + | 'numbered-list'; + +export interface CmsSelectWidgetOptionObject { + label: string; + value: any; +} + +export type CmsCollectionFormatType = + | 'yml' + | 'yaml' + | 'toml' + | 'json' + | 'frontmatter' + | 'yaml-frontmatter' + | 'toml-frontmatter' + | 'json-frontmatter'; + +export type CmsAuthScope = 'repo' | 'public_repo'; + +export type CmsPublishMode = 'simple' | 'editorial_workflow'; + +export type CmsSlugEncoding = 'unicode' | 'ascii'; + +export interface CmsI18nConfig { + structure: 'multiple_folders' | 'multiple_files' | 'single_file'; + locales: string[]; + default_locale?: string; +} + +export interface CmsFieldBase { + name: string; + label?: string; + required?: boolean; + hint?: string; + pattern?: [string, string]; + i18n?: boolean | 'translate' | 'duplicate' | 'none'; + media_folder?: string; + public_folder?: string; + comment?: string; +} + +export interface CmsFieldBoolean { + widget: 'boolean'; + default?: boolean; +} + +export interface CmsFieldCode { + widget: 'code'; + default?: any; + + default_language?: string; + allow_language_selection?: boolean; + keys?: { code: string; lang: string }; + output_code_only?: boolean; +} + +export interface CmsFieldColor { + widget: 'color'; + default?: string; + + allowInput?: boolean; + enableAlpha?: boolean; +} + +export interface CmsFieldDateTime { + widget: 'datetime'; + default?: string; + + format?: string; + date_format?: boolean | string; + time_format?: boolean | string; + picker_utc?: boolean; + + /** + * @deprecated Use date_format instead + */ + dateFormat?: boolean | string; + /** + * @deprecated Use time_format instead + */ + timeFormat?: boolean | string; + /** + * @deprecated Use picker_utc instead + */ + pickerUtc?: boolean; +} + +export interface CmsFieldFileOrImage { + widget: 'file' | 'image'; + default?: string; + + media_library?: CmsMediaLibrary; + allow_multiple?: boolean; + config?: any; +} + +export interface CmsFieldObject { + widget: 'object'; + default?: any; + + collapsed?: boolean; + summary?: string; + fields: CmsField[]; +} + +export interface CmsFieldList { + widget: 'list'; + default?: any; + + allow_add?: boolean; + collapsed?: boolean; + summary?: string; + minimize_collapsed?: boolean; + label_singular?: string; + field?: CmsField; + fields?: CmsField[]; + max?: number; + min?: number; + add_to_top?: boolean; + types?: (CmsFieldBase & CmsFieldObject)[]; +} + +export interface CmsFieldMap { + widget: 'map'; + default?: string; + + decimals?: number; + type?: CmsMapWidgetType; +} + +export interface CmsFieldMarkdown { + widget: 'markdown'; + default?: string; + + minimal?: boolean; + buttons?: CmsMarkdownWidgetButton[]; + editor_components?: string[]; + modes?: ('raw' | 'rich_text')[]; + + /** + * @deprecated Use editor_components instead + */ + editorComponents?: string[]; +} + +export interface CmsFieldNumber { + widget: 'number'; + default?: string | number; + + value_type?: 'int' | 'float' | string; + min?: number; + max?: number; + + step?: number; + + /** + * @deprecated Use valueType instead + */ + valueType?: 'int' | 'float' | string; +} + +export interface CmsFieldSelect { + widget: 'select'; + default?: string | string[]; + + options: string[] | CmsSelectWidgetOptionObject[]; + multiple?: boolean; + min?: number; + max?: number; +} + +export interface CmsFieldRelation { + widget: 'relation'; + default?: string | string[]; + + collection: string; + value_field: string; + search_fields: string[]; + file?: string; + display_fields?: string[]; + multiple?: boolean; + options_length?: number; + + /** + * @deprecated Use value_field instead + */ + valueField?: string; + /** + * @deprecated Use search_fields instead + */ + searchFields?: string[]; + /** + * @deprecated Use display_fields instead + */ + displayFields?: string[]; + /** + * @deprecated Use options_length instead + */ + optionsLength?: number; +} + +export interface CmsFieldHidden { + widget: 'hidden'; + default?: any; +} + +export interface CmsFieldStringOrText { + // This is the default widget, so declaring its type is optional. + widget?: 'string' | 'text'; + default?: string; +} + +export interface CmsFieldMeta { + name: string; + label: string; + widget: string; + required: boolean; + index_file: string; + meta: boolean; +} + +export type CmsField = CmsFieldBase & + ( + | CmsFieldBoolean + | CmsFieldCode + | CmsFieldColor + | CmsFieldDateTime + | CmsFieldFileOrImage + | CmsFieldList + | CmsFieldMap + | CmsFieldMarkdown + | CmsFieldNumber + | CmsFieldObject + | CmsFieldRelation + | CmsFieldSelect + | CmsFieldHidden + | CmsFieldStringOrText + | CmsFieldMeta + ); + +export interface CmsCollectionFile { + name: string; + label: string; + file: string; + fields: CmsField[]; + label_singular?: string; + description?: string; + preview_path?: string; + preview_path_date_field?: string; + i18n?: boolean | CmsI18nConfig; + media_folder?: string; + public_folder?: string; + editor?: { + preview?: boolean; + }; +} + +export interface ViewFilter { + id: string; + label: string; + field: string; + pattern: string; +} + +export interface ViewGroup { + id: string; + label: string; + field: string; + pattern?: string; +} + +export enum SortDirection { + Ascending = 'Ascending', + Descending = 'Descending', + None = 'None', +} + +export interface CmsSortableFieldsDefault { + field: string; + direction: SortDirection; +} + +export interface CmsSortableFields { + default?: CmsSortableFieldsDefault; + fields: string[]; +} + +export interface CmsCollection { + name: string; + type?: CollectionType; + icon?: string; + label: string; + label_singular?: string; + description?: string; + folder?: string; + files?: CmsCollectionFile[]; + identifier_field?: string; + summary?: string; + slug?: string; + preview_path?: string; + preview_path_date_field?: string; + create?: boolean; + delete?: boolean; + hide?: boolean; + editor?: { + preview?: boolean; + }; + publish?: boolean; + nested?: { + depth: number; + }; + meta?: { path?: { label: string; widget: string; index_file: string } }; + + /** + * It accepts the following values: yml, yaml, toml, json, md, markdown, html + * + * You may also specify a custom extension not included in the list above, by specifying the format value. + */ + extension?: string; + format?: CmsCollectionFormatType; + + frontmatter_delimiter?: string[] | string; + fields?: CmsField[]; + filter?: { field: string; value: any }; + path?: string; + media_folder?: string; + public_folder?: string; + sortable_fields?: CmsSortableFields; + view_filters?: ViewFilter[]; + view_groups?: ViewGroup[]; + i18n?: boolean | CmsI18nConfig; +} + +export interface CmsBackend { + name: CmsBackendType; + auth_scope?: CmsAuthScope; + open_authoring?: boolean; + always_fork?: boolean; + repo?: string; + branch?: string; + api_root?: string; + site_domain?: string; + base_url?: string; + auth_endpoint?: string; + app_id?: string; + auth_type?: 'implicit' | 'pkce'; + cms_label_prefix?: string; + squash_merges?: boolean; + proxy_url?: string; + commit_messages?: { + create?: string; + update?: string; + delete?: string; + uploadMedia?: string; + deleteMedia?: string; + openAuthoring?: string; + }; +} + +export interface CmsSlug { + encoding?: CmsSlugEncoding; + clean_accents?: boolean; + sanitize_replacement?: string; +} + +export interface CmsLocalBackend { + url?: string; + allowed_hosts?: string[]; +} + +export interface CmsConfig { + backend: CmsBackend; + collections: CmsCollection[]; + locale?: string; + site_url?: string; + display_url?: string; + logo_url?: string; + show_preview_links?: boolean; + media_folder?: string; + public_folder?: string; + media_folder_relative?: boolean; + media_library?: CmsMediaLibrary; + publish_mode?: CmsPublishMode; + load_config_file?: boolean; + integrations?: { + hooks: string[]; + provider: string; + collections?: '*' | string[]; + applicationID?: string; + apiKey?: string; + getSignedFormURL?: string; + }[]; + slug?: CmsSlug; + i18n?: CmsI18nConfig; + local_backend?: boolean | CmsLocalBackend; + editor?: { + preview?: boolean; + }; + search?: boolean; +} + +export interface InitOptions { + config: CmsConfig; +} + +export type CmsBackendClass = Implementation; + +export interface EditorComponentField { + name: string; + label: string; + widget: string; +} + +export interface EditorComponentWidgetOptions { + id: string; + label: string; + widget: string; + type: string; +} + +export interface EditorComponentManualOptions { + id: string; + label: string; + fields: EditorComponentField[]; + pattern: RegExp; + allow_add?: boolean; + fromBlock: (match: RegExpMatchArray) => any; + toBlock: (data: any) => string; + toPreview: (data: any) => string; +} + +export type EditorComponentOptions = EditorComponentManualOptions | EditorComponentWidgetOptions; + +export interface CmsEventListener { + name: 'prePublish' | 'postPublish' | 'preUnpublish' | 'postUnpublish' | 'preSave' | 'postSave'; + handler: ({ + entry, + author, + }: { + entry: Map; + author: { login: string; name: string }; + }) => any; +} + +export type CmsEventListenerOptions = any; // TODO: type properly + +export interface CMSApi { + getBackend: (name: string) => CmsRegistryBackend | undefined; + getEditorComponents: () => Map>; + getRemarkPlugins: () => Array; + getLocale: (locale: string) => CmsLocalePhrases | undefined; + getMediaLibrary: (name: string) => CmsMediaLibrary | undefined; + resolveWidget: (name: string) => CmsWidget | undefined; + getPreviewStyles: () => PreviewStyle[]; + getPreviewTemplate: (name: string) => ComponentType | undefined; + getWidget: (name: string) => CmsWidget | undefined; + getWidgetValueSerializer: (widgetName: string) => CmsWidgetValueSerializer | undefined; + init: (options?: InitOptions) => void; + registerBackend: (name: string, backendClass: T) => void; + registerEditorComponent: (options: EditorComponentOptions) => void; + registerRemarkPlugin: (plugin: Pluggable) => void; + registerEventListener: ( + eventListener: CmsEventListener, + options?: CmsEventListenerOptions, + ) => void; + registerLocale: (locale: string, phrases: CmsLocalePhrases) => void; + registerMediaLibrary: (mediaLibrary: CmsMediaLibrary, options?: CmsMediaLibraryOptions) => void; + registerPreviewStyle: (filePath: string, options?: PreviewStyleOptions) => void; + registerPreviewTemplate: ( + name: string, + component: ComponentType, + ) => void; + registerWidget: ( + widget: string | CmsWidgetParam | CmsWidgetParam[], + control?: ComponentType | string, + preview?: ComponentType, + ) => void; + registerWidgetValueSerializer: (widgetName: string, serializer: CmsWidgetValueSerializer) => void; + registerIcon: (iconName: string, icon: ReactNode) => void; + getIcon: (iconName: string) => ReactNode; + registerAdditionalLink: (id: string, title: string, link: string, iconName?: string) => void; + getAdditionalLinks: () => { title: string; link: string; iconName?: string }[]; +} diff --git a/packages/netlify-cms-core/src/lib/__tests__/formatters.spec.js b/packages/netlify-cms-core/src/lib/__tests__/formatters.spec.js deleted file mode 100644 index 283f5d49..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/formatters.spec.js +++ /dev/null @@ -1,723 +0,0 @@ -import { List, Map, fromJS } from 'immutable'; - -import { - commitMessageFormatter, - prepareSlug, - slugFormatter, - previewUrlFormatter, - summaryFormatter, - folderFormatter, -} from '../formatters'; - -jest.spyOn(console, 'warn').mockImplementation(() => {}); -jest.mock('../../reducers/collections'); - -describe('formatters', () => { - describe('commitMessageFormatter', () => { - const config = { - backend: { - name: 'git-gateway', - }, - }; - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should return default commit message on create, label_singular', () => { - const collection = Map({ label_singular: 'Collection' }); - - expect( - commitMessageFormatter('create', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Create Collection “doc-slug”'); - }); - - it('should return default commit message on create, label', () => { - const collection = Map({ label: 'Collections' }); - - expect( - commitMessageFormatter('update', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Update Collections “doc-slug”'); - }); - - it('should return default commit message on delete', () => { - const collection = Map({ label_singular: 'Collection' }); - - expect( - commitMessageFormatter('delete', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Delete Collection “doc-slug”'); - }); - - it('should return default commit message on uploadMedia', () => { - const collection = Map({}); - - expect( - commitMessageFormatter('uploadMedia', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Upload “file-path”'); - }); - - it('should return default commit message on deleteMedia', () => { - const collection = Map({}); - - expect( - commitMessageFormatter('deleteMedia', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Delete “file-path”'); - }); - - it('should log warning on unknown variable', () => { - const config = { - backend: { - commit_messages: { - create: 'Create {{collection}} “{{slug}}” with "{{unknown variable}}"', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - expect( - commitMessageFormatter('create', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Create Collection “doc-slug” with ""'); - expect(console.warn).toHaveBeenCalledTimes(1); - expect(console.warn).toHaveBeenCalledWith( - 'Ignoring unknown variable “unknown variable” in commit message template.', - ); - }); - - it('should return custom commit message on update', () => { - const config = { - backend: { - commit_messages: { - update: 'Custom commit message', - }, - }, - }; - const collection = Map({}); - expect( - commitMessageFormatter('update', config, { - slug: 'doc-slug', - path: 'file-path', - collection, - }), - ).toEqual('Custom commit message'); - }); - - it('should use empty values if "authorLogin" and "authorName" are missing in commit message', () => { - const config = { - backend: { - commit_messages: { - update: '{{author-login}} - {{author-name}}: Create {{collection}} “{{slug}}”', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - expect( - commitMessageFormatter( - 'update', - config, - { - slug: 'doc-slug', - path: 'file-path', - collection, - }, - true, - ), - ).toEqual(' - : Create Collection “doc-slug”'); - }); - - it('should return custom create message with author information', () => { - const config = { - backend: { - commit_messages: { - create: '{{author-login}} - {{author-name}}: Create {{collection}} “{{slug}}”', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - expect( - commitMessageFormatter( - 'create', - config, - { - slug: 'doc-slug', - path: 'file-path', - collection, - authorLogin: 'user-login', - authorName: 'Test User', - }, - true, - ), - ).toEqual('user-login - Test User: Create Collection “doc-slug”'); - }); - - it('should return custom open authoring message', () => { - const config = { - backend: { - commit_messages: { - openAuthoring: '{{author-login}} - {{author-name}}: {{message}}', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - expect( - commitMessageFormatter( - 'create', - config, - { - slug: 'doc-slug', - path: 'file-path', - collection, - authorLogin: 'user-login', - authorName: 'Test User', - }, - true, - ), - ).toEqual('user-login - Test User: Create Collection “doc-slug”'); - }); - - it('should use empty values if "authorLogin" and "authorName" are missing in open authoring message', () => { - const config = { - backend: { - commit_messages: { - openAuthoring: '{{author-login}} - {{author-name}}: {{message}}', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - expect( - commitMessageFormatter( - 'create', - config, - { - slug: 'doc-slug', - path: 'file-path', - collection, - }, - true, - ), - ).toEqual(' - : Create Collection “doc-slug”'); - }); - - it('should log warning on unknown variable in open authoring template', () => { - const config = { - backend: { - commit_messages: { - openAuthoring: '{{author-email}}: {{message}}', - }, - }, - }; - const collection = Map({ label_singular: 'Collection' }); - commitMessageFormatter( - 'create', - config, - { - slug: 'doc-slug', - path: 'file-path', - collection, - authorLogin: 'user-login', - authorName: 'Test User', - }, - true, - ); - - expect(console.warn).toHaveBeenCalledTimes(1); - expect(console.warn).toHaveBeenCalledWith( - 'Ignoring unknown variable “author-email” in open authoring message template.', - ); - }); - }); - - describe('prepareSlug', () => { - it('should trim slug', () => { - expect(prepareSlug(' slug ')).toBe('slug'); - }); - - it('should lowercase slug', () => { - expect(prepareSlug('Slug')).toBe('slug'); - }); - - it('should remove single quotes', () => { - expect(prepareSlug(`sl'ug`)).toBe('slug'); - }); - - it('should replace periods with slashes', () => { - expect(prepareSlug(`sl.ug`)).toBe('sl-ug'); - }); - }); - - const slugConfig = { - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', - }; - - describe('slugFormatter', () => { - const date = new Date('2020-01-01'); - jest.spyOn(global, 'Date').mockImplementation(() => date); - - const { selectIdentifier } = require('../../reducers/collections'); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should format with default pattern', () => { - selectIdentifier.mockReturnValueOnce('title'); - expect(slugFormatter(Map(), Map({ title: 'Post Title' }), slugConfig)).toBe('post-title'); - }); - - it('should format with date', () => { - selectIdentifier.mockReturnValueOnce('title'); - - expect( - slugFormatter( - Map({ slug: '{{year}}-{{month}}-{{day}}_{{slug}}' }), - Map({ title: 'Post Title' }), - slugConfig, - ), - ).toBe('2020-01-01_post-title'); - }); - - it('should format with entry field', () => { - selectIdentifier.mockReturnValueOnce('slug'); - - expect( - slugFormatter( - Map({ slug: '{{fields.slug}}' }), - Map({ title: 'Post Title', slug: 'entry-slug' }), - slugConfig, - ), - ).toBe('entry-slug'); - }); - - it('should return slug', () => { - selectIdentifier.mockReturnValueOnce('title'); - - expect( - slugFormatter(Map({ slug: '{{slug}}' }), Map({ title: 'Post Title' }), slugConfig), - ).toBe('post-title'); - }); - - it('should return slug with path', () => { - selectIdentifier.mockReturnValueOnce('title'); - - expect( - slugFormatter( - Map({ slug: '{{year}}-{{month}}-{{day}}-{{slug}}', path: 'sub_dir/{{year}}/{{slug}}' }), - Map({ title: 'Post Title' }), - slugConfig, - ), - ).toBe('sub_dir/2020/2020-01-01-post-title'); - }); - - it('should only sanitize template variables', () => { - selectIdentifier.mockReturnValueOnce('title'); - - expect( - slugFormatter( - Map({ - slug: '{{year}}-{{month}}-{{day}}-{{slug}}.en', - path: 'sub_dir/{{year}}/{{slug}}', - }), - Map({ title: 'Post Title' }), - slugConfig, - ), - ).toBe('sub_dir/2020/2020-01-01-post-title.en'); - }); - - it(`should replace '.' in path with -`, () => { - selectIdentifier.mockReturnValueOnce('title'); - - expect( - slugFormatter( - Map({ - slug: '{{slug}}.en', - path: '../dir/{{slug}}', - }), - Map({ title: 'Post Title' }), - slugConfig, - ), - ).toBe('--/dir/post-title.en'); - }); - }); - - describe('previewUrlFormatter', () => { - it('should return undefined when missing baseUrl', () => { - expect(previewUrlFormatter('')).toBeUndefined(); - }); - - it('should return baseUrl for collection with no preview_path', () => { - expect(previewUrlFormatter('https://www.example.com', Map({}))).toBe( - 'https://www.example.com', - ); - }); - - it('should return preview url based on preview_path and preview_path_date_field', () => { - const date = new Date('2020-01-02T13:28:27.679Z'); - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - preview_path: '{{year}}/{{slug}}/{{title}}/{{fields.slug}}', - preview_path_date_field: 'customDateField', - }), - 'backendSlug', - Map({ data: Map({ customDateField: date, slug: 'entrySlug', title: 'title' }) }), - slugConfig, - ), - ).toBe('https://www.example.com/2020/backendslug/title/entryslug'); - }); - - it('should return preview url for files in file collection', () => { - const file = Map({ name: 'about-file', preview_path: '{{slug}}/{{fields.slug}}/{{title}}' }); - - const { getFileFromSlug } = require('../../reducers/collections'); - getFileFromSlug.mockReturnValue(file); - - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - preview_path: '{{slug}}/{{title}}/{{fields.slug}}', - type: 'file_based_collection', - files: List([file]), - }), - 'backendSlug', - Map({ data: Map({ slug: 'about-the-project', title: 'title' }), slug: 'about-file' }), - slugConfig, - ), - ).toBe('https://www.example.com/backendslug/about-the-project/title'); - }); - - it('should return preview url for files in file collection when defined on file-level only', () => { - const file = Map({ name: 'about-file', preview_path: '{{slug}}/{{fields.slug}}/{{title}}' }); - - const { getFileFromSlug } = require('../../reducers/collections'); - getFileFromSlug.mockReturnValue(file); - - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - type: 'file_based_collection', - files: List([file]), - }), - 'backendSlug', - Map({ data: Map({ slug: 'about-the-project', title: 'title' }), slug: 'about-file' }), - slugConfig, - ), - ).toBe('https://www.example.com/backendslug/about-the-project/title'); - }); - - it('should fall back to collection preview url for files in file collection', () => { - const file = Map({ name: 'about-file' }); - - const { getFileFromSlug } = require('../../reducers/collections'); - getFileFromSlug.mockReturnValue(file); - - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - preview_path: '{{slug}}/{{title}}/{{fields.slug}}', - type: 'file_based_collection', - files: List([file]), - }), - 'backendSlug', - Map({ data: Map({ slug: 'about-the-project', title: 'title' }), slug: 'about-file' }), - slugConfig, - ), - ).toBe('https://www.example.com/backendslug/title/about-the-project'); - }); - - it('should infer date field when preview_path_date_field is not configured', () => { - const { selectInferedField } = require('../../reducers/collections'); - selectInferedField.mockReturnValue('date'); - - const date = new Date('2020-01-02T13:28:27.679Z'); - expect( - previewUrlFormatter( - 'https://www.example.com', - fromJS({ - name: 'posts', - preview_path: '{{year}}/{{month}}/{{slug}}/{{title}}/{{fields.slug}}', - }), - 'backendSlug', - Map({ data: Map({ date, slug: 'entrySlug', title: 'title' }) }), - slugConfig, - ), - ).toBe('https://www.example.com/2020/01/backendslug/title/entryslug'); - }); - - it('should compile filename and extension template values', () => { - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - preview_path: 'posts/{{filename}}.{{extension}}', - }), - 'backendSlug', - Map({ data: Map({}), path: 'src/content/posts/title.md' }), - slugConfig, - ), - ).toBe('https://www.example.com/posts/title.md'); - }); - - it('should compile the dirname template value to empty in a regular collection', () => { - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - folder: '_portfolio', - preview_path: 'portfolio/{{dirname}}', - }), - 'backendSlug', - Map({ data: Map({}), path: '_portfolio/i-am-the-slug.md' }), - slugConfig, - ), - ).toBe('https://www.example.com/portfolio/'); - }); - - it('should compile dirname template value when in a nested collection', () => { - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - folder: '_portfolio', - preview_path: 'portfolio/{{dirname}}', - nested: { depth: 100 }, - meta: { path: { widget: 'string', label: 'Path', index_file: 'index' } }, - }), - 'backendSlug', - Map({ data: Map({}), path: '_portfolio/drawing/i-am-the-slug/index.md' }), - slugConfig, - ), - ).toBe('https://www.example.com/portfolio/drawing/i-am-the-slug'); - }); - - it('should log error and ignore preview_path when date is missing', () => { - jest.spyOn(console, 'error').mockImplementation(() => {}); - expect( - previewUrlFormatter( - 'https://www.example.com', - Map({ - name: 'posts', - preview_path: '{{year}}', - preview_path_date_field: 'date', - }), - 'backendSlug', - Map({ data: Map({}) }), - slugConfig, - ), - ).toBe('https://www.example.com'); - - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledWith( - 'Collection "posts" configuration error:\n `preview_path_date_field` must be a field with a valid date. Ignoring `preview_path`.', - ); - }); - }); - - describe('summaryFormatter', () => { - it('should return summary from template', () => { - const { selectInferedField } = require('../../reducers/collections'); - selectInferedField.mockReturnValue('date'); - - const date = new Date('2020-01-02T13:28:27.679Z'); - const entry = fromJS({ data: { date, title: 'title' } }); - const collection = fromJS({ fields: [{ name: 'date', widget: 'date' }] }); - - expect(summaryFormatter('{{title}}-{{year}}', entry, collection)).toBe('title-2020'); - }); - - it('should handle filename and extension variables', () => { - const { selectInferedField } = require('../../reducers/collections'); - selectInferedField.mockReturnValue('date'); - - const date = new Date('2020-01-02T13:28:27.679Z'); - const entry = fromJS({ path: 'post.md', data: { date, title: 'title' } }); - const collection = fromJS({ fields: [{ name: 'date', widget: 'date' }] }); - - expect( - summaryFormatter('{{title}}-{{year}}-{{filename}}.{{extension}}', entry, collection), - ).toBe('title-2020-post.md'); - }); - - it('should handle the dirname variable in a regular collection', () => { - const { selectInferedField } = require('../../reducers/collections'); - selectInferedField.mockReturnValue('date'); - - const date = new Date('2020-01-02T13:28:27.679Z'); - const entry = fromJS({ - path: '_portfolio/drawing.md', - data: { date, title: 'title' }, - }); - const collection = fromJS({ - folder: '_portfolio', - fields: [{ name: 'date', widget: 'date' }], - }); - - expect(summaryFormatter('{{dirname}}/{{title}}-{{year}}', entry, collection)).toBe( - '/title-2020', - ); - }); - - it('should handle the dirname variable in a nested collection', () => { - const { selectInferedField } = require('../../reducers/collections'); - selectInferedField.mockReturnValue('date'); - - const date = new Date('2020-01-02T13:28:27.679Z'); - const entry = fromJS({ - path: '_portfolio/drawing/index.md', - data: { date, title: 'title' }, - }); - const collection = fromJS({ - folder: '_portfolio', - nested: { depth: 100 }, - meta: { path: { widget: 'string', label: 'Path', index_file: 'index' } }, - fields: [{ name: 'date', widget: 'date' }], - }); - - expect(summaryFormatter('{{dirname}}/{{title}}-{{year}}', entry, collection)).toBe( - 'drawing/title-2020', - ); - }); - }); - - describe('folderFormatter', () => { - it('should return folder is entry is undefined', () => { - expect(folderFormatter('static/images', undefined)).toBe('static/images'); - }); - - it('should return folder is entry data is undefined', () => { - expect(folderFormatter('static/images', Map({}))).toBe('static/images'); - }); - - it('should return formatted folder', () => { - const { selectIdentifier } = require('../../reducers/collections'); - selectIdentifier.mockReturnValue('title'); - - const entry = fromJS({ - path: 'content/en/hosting-and-deployment/deployment-with-nanobox.md', - data: { title: 'Deployment With NanoBox', category: 'Hosting And Deployment' }, - }); - const collection = fromJS({}); - - expect( - folderFormatter( - '../../../{{media_folder}}/{{category}}/{{slug}}', - entry, - collection, - 'static/images', - 'media_folder', - slugConfig, - ), - ).toBe('../../../static/images/hosting-and-deployment/deployment-with-nanobox'); - }); - - it('should compile filename template value', () => { - const entry = fromJS({ - path: 'content/en/hosting-and-deployment/deployment-with-nanobox.md', - data: { category: 'Hosting And Deployment' }, - }); - const collection = fromJS({}); - - expect( - folderFormatter( - '../../../{{media_folder}}/{{category}}/{{filename}}', - entry, - collection, - 'static/images', - 'media_folder', - slugConfig, - ), - ).toBe('../../../static/images/hosting-and-deployment/deployment-with-nanobox'); - }); - - it('should compile extension template value', () => { - const entry = fromJS({ - path: 'content/en/hosting-and-deployment/deployment-with-nanobox.md', - data: { category: 'Hosting And Deployment' }, - }); - const collection = fromJS({}); - - expect( - folderFormatter( - '{{extension}}', - entry, - collection, - 'static/images', - 'media_folder', - slugConfig, - ), - ).toBe('md'); - }); - - it('should compile dirname template value in a regular collection', () => { - const entry = fromJS({ - path: 'content/en/hosting-and-deployment/deployment-with-nanobox.md', - data: { category: 'Hosting And Deployment' }, - }); - const collection = fromJS({ - folder: 'content/en/', - }); - - expect( - folderFormatter( - '{{dirname}}', - entry, - collection, - 'static/images', - 'media_folder', - slugConfig, - ), - ).toBe('hosting-and-deployment'); - }); - - it('should compile dirname template value in a nested collection', () => { - const entry = fromJS({ - path: '_portfolio/drawing/i-am-the-slug/index.md', - data: { category: 'Hosting And Deployment' }, - }); - const collection = fromJS({ - folder: '_portfolio', - nested: { depth: 100 }, - meta: { path: { widget: 'string', label: 'Path', index_file: 'index' } }, - fields: [{ name: 'date', widget: 'date' }], - }); - - expect( - folderFormatter( - '{{dirname}}', - entry, - collection, - 'static/images', - 'media_folder', - slugConfig, - ), - ).toBe('drawing/i-am-the-slug'); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/lib/__tests__/i18n.spec.js b/packages/netlify-cms-core/src/lib/__tests__/i18n.spec.js deleted file mode 100644 index 7a8c01b7..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/i18n.spec.js +++ /dev/null @@ -1,792 +0,0 @@ -import { fromJS } from 'immutable'; - -import * as i18n from '../i18n'; - -jest.mock('../../reducers/collections', () => { - return { - selectEntrySlug: () => 'index', - }; -}); - -describe('i18n', () => { - describe('hasI18n', () => { - it('should return false for collection with no i18n', () => { - expect(i18n.hasI18n(fromJS({}))).toBe(false); - }); - - it('should return true for collection with i18n', () => { - expect(i18n.hasI18n(fromJS({ i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE } }))).toBe( - true, - ); - }); - }); - - describe('getI18nInfo', () => { - it('should return empty object for collection with no i18n', () => { - expect(i18n.getI18nInfo(fromJS({}))).toEqual({}); - }); - - it('should return i18n object for collection with i18n', () => { - const i18nObject = { - locales: ['en', 'de'], - default_locale: 'en', - structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, - }; - expect(i18n.getI18nInfo(fromJS({ i18n: i18nObject }))).toEqual({ - locales: ['en', 'de'], - defaultLocale: 'en', - structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, - }); - }); - }); - - describe('getI18nFilesDepth', () => { - it('should increase depth when i18n structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.getI18nFilesDepth( - fromJS({ i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS } }), - 5, - ), - ).toBe(6); - }); - - it('should return current depth when i18n structure is not I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.getI18nFilesDepth( - fromJS({ i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES } }), - 5, - ), - ).toBe(5); - expect( - i18n.getI18nFilesDepth(fromJS({ i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE } }), 5), - ).toBe(5); - expect(i18n.getI18nFilesDepth(fromJS({}), 5)).toBe(5); - }); - }); - - describe('isFieldTranslatable', () => { - it('should return true when not default locale and has I18N_FIELD.TRANSLATE', () => { - expect( - i18n.isFieldTranslatable(fromJS({ i18n: i18n.I18N_FIELD.TRANSLATE }), 'en', 'de'), - ).toBe(true); - }); - - it('should return false when default locale and has I18N_FIELD.TRANSLATE', () => { - expect( - i18n.isFieldTranslatable(fromJS({ i18n: i18n.I18N_FIELD.TRANSLATE }), 'en', 'en'), - ).toBe(false); - }); - - it("should return false when doesn't have i18n", () => { - expect(i18n.isFieldTranslatable(fromJS({}), 'en', 'en')).toBe(false); - }); - }); - - describe('isFieldDuplicate', () => { - it('should return true when not default locale and has I18N_FIELD.TRANSLATE', () => { - expect(i18n.isFieldDuplicate(fromJS({ i18n: i18n.I18N_FIELD.DUPLICATE }), 'en', 'de')).toBe( - true, - ); - }); - - it('should return false when default locale and has I18N_FIELD.TRANSLATE', () => { - expect(i18n.isFieldDuplicate(fromJS({ i18n: i18n.I18N_FIELD.DUPLICATE }), 'en', 'en')).toBe( - false, - ); - }); - - it("should return false when doesn't have i18n", () => { - expect(i18n.isFieldDuplicate(fromJS({}), 'en', 'en')).toBe(false); - }); - }); - - describe('isFieldHidden', () => { - it('should return true when not default locale and has I18N_FIELD.NONE', () => { - expect(i18n.isFieldHidden(fromJS({ i18n: i18n.I18N_FIELD.NONE }), 'en', 'de')).toBe(true); - }); - - it('should return false when default locale and has I18N_FIELD.NONE', () => { - expect(i18n.isFieldHidden(fromJS({ i18n: i18n.I18N_FIELD.NONE }), 'en', 'en')).toBe(false); - }); - - it("should return false when doesn't have i18n", () => { - expect(i18n.isFieldHidden(fromJS({}), 'en', 'en')).toBe(false); - }); - }); - - describe('getLocaleDataPath', () => { - it('should return string array with locale as part of the data path', () => { - expect(i18n.getLocaleDataPath('de')).toEqual(['i18n', 'de', 'data']); - }); - }); - - describe('getDataPath', () => { - it('should not include locale in path for default locale', () => { - expect(i18n.getDataPath('en', 'en')).toEqual(['data']); - }); - - it('should include locale in path for non default locale', () => { - expect(i18n.getDataPath('de', 'en')).toEqual(['i18n', 'de', 'data']); - }); - }); - - describe('getFilePath', () => { - it('should return directory path based on locale when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.getFilePath( - i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, - 'md', - 'src/content/index.md', - 'index', - 'de', - ), - ).toEqual('src/content/de/index.md'); - }); - - it('should return file path based on locale when structure is I18N_STRUCTURE.MULTIPLE_FILES', () => { - expect( - i18n.getFilePath( - i18n.I18N_STRUCTURE.MULTIPLE_FILES, - 'md', - 'src/content/file-with-md-in-the-name.md', - 'file-with-md-in-the-name', - 'de', - ), - ).toEqual('src/content/file-with-md-in-the-name.de.md'); - }); - - it('should not modify path when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - expect( - i18n.getFilePath( - i18n.I18N_STRUCTURE.SINGLE_FILE, - 'md', - 'src/content/index.md', - 'index', - 'de', - ), - ).toEqual('src/content/index.md'); - }); - }); - - describe('getFilePaths', () => { - const args = ['md', 'src/content/index.md', 'index']; - - it('should return file paths for all locales', () => { - expect( - i18n.getFilePaths( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, locales: ['en', 'de'] }, - }), - ...args, - ), - ).toEqual(['src/content/en/index.md', 'src/content/de/index.md']); - }); - - it('should return array with single path when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - expect( - i18n.getFilePaths( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales: ['en', 'de'] }, - }), - ...args, - ), - ).toEqual(['src/content/index.md']); - }); - }); - - describe('normalizeFilePath', () => { - it('should remove locale folder from path when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.normalizeFilePath( - i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, - 'src/content/en/index.md', - 'en', - ), - ).toEqual('src/content/index.md'); - }); - - it('should remove locale extension from path when structure is I18N_STRUCTURE.MULTIPLE_FILES', () => { - expect( - i18n.normalizeFilePath(i18n.I18N_STRUCTURE.MULTIPLE_FILES, 'src/content/index.en.md', 'en'), - ).toEqual('src/content/index.md'); - }); - - it('should not modify path when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - expect( - i18n.normalizeFilePath(i18n.I18N_STRUCTURE.SINGLE_FILE, 'src/content/index.md', 'en'), - ).toEqual('src/content/index.md'); - }); - }); - - describe('getLocaleFromPath', () => { - it('should return the locale from folder name in the path when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.getLocaleFromPath( - i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, - 'md', - 'src/content/en/index.md', - ), - ).toEqual('en'); - }); - - it('should return the locale extension from the file name when structure is I18N_STRUCTURE.MULTIPLE_FILES', () => { - expect( - i18n.getLocaleFromPath(i18n.I18N_STRUCTURE.MULTIPLE_FILES, 'md', 'src/content/index.en.md'), - ).toEqual('en'); - }); - - it('issue #5909: return the correct locale extension for language gd', () => { - expect( - i18n.getLocaleFromPath(i18n.I18N_STRUCTURE.MULTIPLE_FILES, 'md', 'src/content/index.gd.md'), - ).toEqual('gd'); - }); - - it('should return an empty string when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - expect( - i18n.getLocaleFromPath(i18n.I18N_STRUCTURE.SINGLE_FILE, 'md', 'src/content/index.md'), - ).toEqual(''); - }); - }); - - describe('getI18nFiles', () => { - const locales = ['en', 'de', 'fr']; - const default_locale = 'en'; - const args = [ - 'md', - fromJS({ - data: { title: 'en_title' }, - i18n: { de: { data: { title: 'de_title' } }, fr: { data: { title: 'fr_title' } } }, - }), - map => map.get('data').toJS(), - 'src/content/index.md', - 'index', - ]; - it('should return a single file when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - expect( - i18n.getI18nFiles( - fromJS({ i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale } }), - ...args, - ), - ).toEqual([ - { - path: 'src/content/index.md', - raw: { - en: { title: 'en_title' }, - de: { title: 'de_title' }, - fr: { title: 'fr_title' }, - }, - slug: 'index', - }, - ]); - }); - - it('should return a folder based files when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - expect( - i18n.getI18nFiles( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, locales, default_locale }, - }), - ...args, - ), - ).toEqual([ - { - path: 'src/content/en/index.md', - raw: { title: 'en_title' }, - slug: 'index', - }, - { - path: 'src/content/de/index.md', - raw: { title: 'de_title' }, - slug: 'index', - }, - { - path: 'src/content/fr/index.md', - raw: { title: 'fr_title' }, - slug: 'index', - }, - ]); - }); - - it('should return a extension based files when structure is I18N_STRUCTURE.MULTIPLE_FILES', () => { - expect( - i18n.getI18nFiles( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES, locales, default_locale }, - }), - ...args, - ), - ).toEqual([ - { - path: 'src/content/index.en.md', - raw: { title: 'en_title' }, - slug: 'index', - }, - { - path: 'src/content/index.de.md', - raw: { title: 'de_title' }, - slug: 'index', - }, - { - path: 'src/content/index.fr.md', - raw: { title: 'fr_title' }, - slug: 'index', - }, - ]); - }); - }); - - describe('getI18nEntry', () => { - const locales = ['en', 'de', 'fr', 'es']; - const default_locale = 'en'; - const args = ['md', 'src/content/index.md', 'index']; - - it('should return i18n entry content when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', async () => { - const data = { - 'src/content/en/index.md': { - slug: 'index', - path: 'src/content/en/index.md', - data: { title: 'en_title' }, - }, - 'src/content/de/index.md': { - slug: 'index', - path: 'src/content/de/index.md', - data: { title: 'de_title' }, - }, - 'src/content/fr/index.md': { - slug: 'index', - path: 'src/content/fr/index.md', - data: { title: 'fr_title' }, - }, - }; - const getEntryValue = jest.fn(path => - data[path] ? Promise.resolve(data[path]) : Promise.reject('Not found'), - ); - - await expect( - i18n.getI18nEntry( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, locales, default_locale }, - }), - ...args, - getEntryValue, - ), - ).resolves.toEqual({ - slug: 'index', - path: 'src/content/index.md', - data: { title: 'en_title' }, - i18n: { - de: { data: { title: 'de_title' } }, - fr: { data: { title: 'fr_title' } }, - }, - raw: '', - }); - }); - - it('should return i18n entry content when structure is I18N_STRUCTURE.MULTIPLE_FILES', async () => { - const data = { - 'src/content/index.en.md': { - slug: 'index', - path: 'src/content/index.en.md', - data: { title: 'en_title' }, - }, - 'src/content/index.de.md': { - slug: 'index', - path: 'src/content/index.de.md', - data: { title: 'de_title' }, - }, - 'src/content/index.fr.md': { - slug: 'index', - path: 'src/content/index.fr.md', - data: { title: 'fr_title' }, - }, - }; - const getEntryValue = jest.fn(path => - data[path] ? Promise.resolve(data[path]) : Promise.reject('Not found'), - ); - - await expect( - i18n.getI18nEntry( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES, locales, default_locale }, - }), - ...args, - getEntryValue, - ), - ).resolves.toEqual({ - slug: 'index', - path: 'src/content/index.md', - data: { title: 'en_title' }, - i18n: { - de: { data: { title: 'de_title' } }, - fr: { data: { title: 'fr_title' } }, - }, - raw: '', - }); - }); - - it('should return single entry content when structure is I18N_STRUCTURE.SINGLE_FILE', async () => { - const data = { - 'src/content/index.md': { - slug: 'index', - path: 'src/content/index.md', - data: { - en: { title: 'en_title' }, - de: { title: 'de_title' }, - fr: { title: 'fr_title' }, - }, - }, - }; - const getEntryValue = jest.fn(path => Promise.resolve(data[path])); - - await expect( - i18n.getI18nEntry( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale }, - }), - ...args, - getEntryValue, - ), - ).resolves.toEqual({ - slug: 'index', - path: 'src/content/index.md', - data: { - title: 'en_title', - }, - i18n: { - de: { data: { title: 'de_title' } }, - fr: { data: { title: 'fr_title' } }, - }, - raw: '', - }); - }); - - it('should default to empty data object when file is empty and structure is I18N_STRUCTURE.SINGLE_FILE', async () => { - const data = { - 'src/content/index.md': { - slug: 'index', - path: 'src/content/index.md', - data: {}, - }, - }; - const getEntryValue = jest.fn(path => Promise.resolve(data[path])); - - await expect( - i18n.getI18nEntry( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale }, - }), - ...args, - getEntryValue, - ), - ).resolves.toEqual({ - slug: 'index', - path: 'src/content/index.md', - data: {}, - i18n: {}, - raw: '', - }); - }); - }); - - describe('groupEntries', () => { - const locales = ['en', 'de', 'fr']; - const default_locale = 'en'; - const extension = 'md'; - - it('should group entries array when structure is I18N_STRUCTURE.MULTIPLE_FOLDERS', () => { - const entries = [ - { - slug: 'index', - path: 'src/content/en/index.md', - data: { title: 'en_title' }, - }, - { - slug: 'index', - path: 'src/content/de/index.md', - data: { title: 'de_title' }, - }, - { - slug: 'index', - path: 'src/content/fr/index.md', - data: { title: 'fr_title' }, - }, - ]; - - expect( - i18n.groupEntries( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, locales, default_locale }, - }), - extension, - entries, - ), - ).toEqual([ - { - slug: 'index', - path: 'src/content/index.md', - data: { title: 'en_title' }, - i18n: { de: { data: { title: 'de_title' } }, fr: { data: { title: 'fr_title' } } }, - raw: '', - }, - ]); - }); - - it('should group entries array when structure is I18N_STRUCTURE.MULTIPLE_FILES', () => { - const entries = [ - { - slug: 'index', - path: 'src/content/index.en.md', - data: { title: 'en_title' }, - }, - { - slug: 'index', - path: 'src/content/index.de.md', - data: { title: 'de_title' }, - }, - { - slug: 'index', - path: 'src/content/index.fr.md', - data: { title: 'fr_title' }, - }, - ]; - - expect( - i18n.groupEntries( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES, locales, default_locale }, - }), - extension, - entries, - ), - ).toEqual([ - { - slug: 'index', - path: 'src/content/index.md', - data: { title: 'en_title' }, - i18n: { de: { data: { title: 'de_title' } }, fr: { data: { title: 'fr_title' } } }, - raw: '', - }, - ]); - }); - - it('should return entries array as is when structure is I18N_STRUCTURE.SINGLE_FILE', () => { - const entries = [ - { - slug: 'index', - path: 'src/content/index.md', - data: { - en: { title: 'en_title' }, - de: { title: 'de_title' }, - fr: { title: 'fr_title' }, - }, - }, - ]; - - expect( - i18n.groupEntries( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale }, - }), - extension, - entries, - ), - ).toEqual([ - { - slug: 'index', - path: 'src/content/index.md', - data: { - title: 'en_title', - }, - i18n: { de: { data: { title: 'de_title' } }, fr: { data: { title: 'fr_title' } } }, - raw: '', - }, - ]); - }); - }); - - describe('getI18nDataFiles', () => { - const locales = ['en', 'de', 'fr']; - const default_locale = 'en'; - - const args = ['md', 'src/content/index.md', 'index']; - - it('should add missing locale files to diff files when structure is MULTIPLE_FOLDERS', () => { - expect( - i18n.getI18nDataFiles( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FOLDERS, locales, default_locale }, - }), - ...args, - [{ path: 'src/content/fr/index.md', id: 'id', newFile: false }], - ), - ).toEqual([ - { path: 'src/content/en/index.md', id: '', newFile: false }, - { path: 'src/content/de/index.md', id: '', newFile: false }, - { path: 'src/content/fr/index.md', id: 'id', newFile: false }, - ]); - }); - - it('should add missing locale files to diff files when structure is MULTIPLE_FILES', () => { - expect( - i18n.getI18nDataFiles( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES, locales, default_locale }, - }), - ...args, - [{ path: 'src/content/index.fr.md', id: 'id', newFile: false }], - ), - ).toEqual([ - { path: 'src/content/index.en.md', id: '', newFile: false }, - { path: 'src/content/index.de.md', id: '', newFile: false }, - { path: 'src/content/index.fr.md', id: 'id', newFile: false }, - ]); - }); - - it('should return a single file when structure is SINGLE_FILE', () => { - expect( - i18n.getI18nDataFiles( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.SINGLE_FILE, locales, default_locale }, - }), - ...args, - [{ path: 'src/content/index.md', id: 'id', newFile: false }], - ), - ).toEqual([{ path: 'src/content/index.md', id: 'id', newFile: false }]); - }); - }); - - describe('getI18nBackup', () => { - it('should return i18n with raw data', () => { - const locales = ['en', 'de', 'fr']; - const default_locale = 'en'; - - expect( - i18n.getI18nBackup( - fromJS({ - i18n: { structure: i18n.I18N_STRUCTURE.MULTIPLE_FILES, locales, default_locale }, - }), - fromJS({ - data: 'raw_en', - i18n: { - de: { data: 'raw_de' }, - fr: { data: 'raw_fr' }, - }, - }), - e => e.get('data'), - ), - ).toEqual({ de: { raw: 'raw_de' }, fr: { raw: 'raw_fr' } }); - }); - }); - - describe('formatI18nBackup', () => { - it('should return i18n with formatted data', () => { - expect( - i18n.formatI18nBackup({ de: { raw: 'raw_de' }, fr: { raw: 'raw_fr' } }, raw => ({ - data: raw, - })), - ).toEqual({ de: { data: 'raw_de' }, fr: { data: 'raw_fr' } }); - }); - }); - - describe('duplicateI18nFields', () => { - it('should duplicate non nested field when field i18n is DUPLICATE', () => { - const date = new Date('2020/01/01'); - expect( - i18n - .duplicateI18nFields( - fromJS({ entry: { data: { date } } }), - fromJS({ name: 'date', i18n: i18n.I18N_FIELD.DUPLICATE }), - ['en', 'de', 'fr'], - 'en', - ) - .toJS(), - ).toEqual({ - entry: { - data: { date }, - i18n: { - de: { data: { date } }, - fr: { data: { date } }, - }, - }, - }); - }); - - it('should not duplicate field when field i18n is not DUPLICATE', () => { - const date = new Date('2020/01/01'); - [i18n.I18N_FIELD.TRANSLATE, i18n.I18N_FIELD.TRANSLATE.DUPLICATE].forEach(fieldI18n => { - expect( - i18n - .duplicateI18nFields( - fromJS({ entry: { data: { date } } }), - fromJS({ name: 'date', i18n: fieldI18n }), - ['en', 'de', 'fr'], - 'en', - ) - .toJS(), - ).toEqual({ - entry: { - data: { date }, - }, - }); - }); - }); - - it('should duplicate nested field when nested fields i18n is DUPLICATE', () => { - const date = new Date('2020/01/01'); - const value = fromJS({ title: 'title', date, boolean: true }); - expect( - i18n - .duplicateI18nFields( - fromJS({ entry: { data: { object: value } } }), - fromJS({ - name: 'object', - fields: [ - { name: 'string', i18n: i18n.I18N_FIELD.TRANSLATE }, - { name: 'date', i18n: i18n.I18N_FIELD.DUPLICATE }, - { name: 'boolean', i18n: i18n.I18N_FIELD.NONE }, - ], - i18n: i18n.I18N_FIELD.TRANSLATE, - }), - ['en', 'de', 'fr'], - 'en', - ) - .toJS(), - ).toEqual({ - entry: { - data: { object: value.toJS() }, - i18n: { - de: { data: { object: { date } } }, - fr: { data: { object: { date } } }, - }, - }, - }); - }); - }); - - describe('getPreviewEntry', () => { - it('should set data to i18n data when locale is not default', () => { - expect( - i18n - .getPreviewEntry( - fromJS({ - data: { title: 'en', body: 'markdown' }, - i18n: { de: { data: { title: 'de' } } }, - }), - 'de', - ) - .toJS(), - ).toEqual({ - data: { title: 'de' }, - i18n: { de: { data: { title: 'de' } } }, - }); - }); - - it('should not change entry for default locale', () => { - const entry = fromJS({ - data: { title: 'en', body: 'markdown' }, - i18n: { de: { data: { title: 'de' } } }, - }); - expect(i18n.getPreviewEntry(entry, 'en', 'en')).toBe(entry); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/lib/__tests__/phrases.spec.js b/packages/netlify-cms-core/src/lib/__tests__/phrases.spec.js deleted file mode 100644 index 2adcd3fb..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/phrases.spec.js +++ /dev/null @@ -1,119 +0,0 @@ -import { getPhrases } from '../phrases'; - -jest.mock('../registry'); - -describe('defaultPhrases', () => { - it('should merge en locale with given locale', () => { - const { getLocale } = require('../registry'); - - const locales = { - en: { - app: { - header: { - content: 'Contents', - workflow: 'Workflow', - media: 'Media', - quickAdd: 'Quick add', - }, - app: { - errorHeader: 'Error loading the CMS configuration', - configErrors: 'Config Errors', - checkConfigYml: 'Check your config.yml file.', - loadingConfig: 'Loading configuration...', - waitingBackend: 'Waiting for backend...', - }, - notFoundPage: { - header: 'Not Found', - }, - }, - collection: { - sidebar: { - collections: 'Collections', - searchAll: 'Search all', - }, - collectionTop: { - viewAs: 'View as', - newButton: 'New %{collectionLabel}', - }, - entries: { - loadingEntries: 'Loading Entries', - cachingEntries: 'Caching Entries', - longerLoading: 'This might take several minutes', - }, - }, - }, - de: { - app: { - header: { - content: 'Inhalt', - }, - }, - }, - }; - - getLocale.mockImplementation(locale => locales[locale]); - - expect(getPhrases('de')).toEqual({ - app: { - header: { - content: 'Inhalt', - workflow: 'Workflow', - media: 'Media', - quickAdd: 'Quick add', - }, - app: { - errorHeader: 'Error loading the CMS configuration', - configErrors: 'Config Errors', - checkConfigYml: 'Check your config.yml file.', - loadingConfig: 'Loading configuration...', - waitingBackend: 'Waiting for backend...', - }, - notFoundPage: { - header: 'Not Found', - }, - }, - collection: { - sidebar: { - collections: 'Collections', - searchAll: 'Search all', - }, - collectionTop: { - viewAs: 'View as', - newButton: 'New %{collectionLabel}', - }, - entries: { - loadingEntries: 'Loading Entries', - cachingEntries: 'Caching Entries', - longerLoading: 'This might take several minutes', - }, - }, - }); - }); - - it('should not mutate default phrases', () => { - const { getLocale } = require('../registry'); - - const locales = { - en: { - app: { - header: { - content: 'Contents', - }, - }, - }, - de: { - app: { - header: { - content: 'Inhalt', - }, - }, - }, - }; - - getLocale.mockImplementation(locale => locales[locale]); - - const result = getPhrases('de'); - - expect(result === locales['en']).toBe(false); - }); -}); diff --git a/packages/netlify-cms-core/src/lib/__tests__/registry.spec.js b/packages/netlify-cms-core/src/lib/__tests__/registry.spec.js deleted file mode 100644 index d751d347..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/registry.spec.js +++ /dev/null @@ -1,246 +0,0 @@ -import { fromJS } from 'immutable'; - -jest.spyOn(console, 'error').mockImplementation(() => {}); - -describe('registry', () => { - beforeEach(() => { - jest.clearAllMocks(); - jest.resetModules(); - }); - - describe('registerLocale', () => { - it('should log error when name is empty', () => { - const { registerLocale } = require('../registry'); - - registerLocale(); - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledWith( - "Locale parameters invalid. example: CMS.registerLocale('locale', phrases)", - ); - }); - - it('should log error when phrases are undefined', () => { - const { registerLocale } = require('../registry'); - - registerLocale('fr'); - expect(console.error).toHaveBeenCalledTimes(1); - expect(console.error).toHaveBeenCalledWith( - "Locale parameters invalid. example: CMS.registerLocale('locale', phrases)", - ); - }); - - it('should register locale', () => { - const { registerLocale, getLocale } = require('../registry'); - - const phrases = { - app: { - header: { - content: 'Inhalt', - }, - }, - }; - - registerLocale('de', phrases); - - expect(getLocale('de')).toBe(phrases); - }); - }); - - describe('eventHandlers', () => { - const events = [ - 'prePublish', - 'postPublish', - 'preUnpublish', - 'postUnpublish', - 'preSave', - 'postSave', - ]; - - describe('registerEventListener', () => { - it('should throw error on invalid event', () => { - const { registerEventListener } = require('../registry'); - - expect(() => registerEventListener({ name: 'unknown' })).toThrow( - new Error("Invalid event name 'unknown'"), - ); - }); - - events.forEach(name => { - it(`should register '${name}' event`, () => { - const { registerEventListener, getEventListeners } = require('../registry'); - - const handler = jest.fn(); - registerEventListener({ name, handler }); - - expect(getEventListeners(name)).toEqual([{ handler, options: {} }]); - }); - }); - }); - - describe('removeEventListener', () => { - it('should throw error on invalid event', () => { - const { removeEventListener } = require('../registry'); - - expect(() => removeEventListener({ name: 'unknown' })).toThrow( - new Error("Invalid event name 'unknown'"), - ); - }); - - events.forEach(name => { - it(`should remove '${name}' event by handler`, () => { - const { - registerEventListener, - getEventListeners, - removeEventListener, - } = require('../registry'); - - const handler1 = jest.fn(); - const handler2 = jest.fn(); - registerEventListener({ name, handler: handler1 }); - registerEventListener({ name, handler: handler2 }); - - expect(getEventListeners(name)).toHaveLength(2); - - removeEventListener({ name, handler: handler1 }); - - expect(getEventListeners(name)).toEqual([{ handler: handler2, options: {} }]); - }); - }); - - events.forEach(name => { - it(`should remove '${name}' event by name`, () => { - const { - registerEventListener, - getEventListeners, - removeEventListener, - } = require('../registry'); - - const handler1 = jest.fn(); - const handler2 = jest.fn(); - registerEventListener({ name, handler: handler1 }); - registerEventListener({ name, handler: handler2 }); - - expect(getEventListeners(name)).toHaveLength(2); - - removeEventListener({ name }); - - expect(getEventListeners(name)).toHaveLength(0); - }); - }); - }); - - describe('invokeEvent', () => { - it('should throw error on invalid event', async () => { - const { invokeEvent } = require('../registry'); - - await expect(invokeEvent({ name: 'unknown', data: {} })).rejects.toThrow( - new Error("Invalid event name 'unknown'"), - ); - }); - - events.forEach(name => { - it(`should invoke '${name}' event with data`, async () => { - const { registerEventListener, invokeEvent } = require('../registry'); - - const options = { hello: 'world' }; - const handler = jest.fn(); - - registerEventListener({ name, handler }, options); - - const data = { entry: fromJS({ data: {} }) }; - await invokeEvent({ name, data }); - - expect(handler).toHaveBeenCalledTimes(1); - expect(handler).toHaveBeenCalledWith(data, options); - }); - - it(`should invoke multiple handlers on '${name}`, async () => { - const { registerEventListener, invokeEvent } = require('../registry'); - - const options1 = { hello: 'test1' }; - const options2 = { hello: 'test2' }; - const handler = jest.fn(({ entry }) => entry.get('data')); - - registerEventListener({ name, handler }, options1); - registerEventListener({ name, handler }, options2); - - const data = { entry: fromJS({ data: {} }) }; - await invokeEvent({ name, data }); - - expect(handler).toHaveBeenCalledTimes(2); - expect(handler).toHaveBeenLastCalledWith(data, options2); - }); - - it(`should throw error when '${name}' handler throws error`, async () => { - const { registerEventListener, invokeEvent } = require('../registry'); - - const handler = jest.fn(() => { - throw new Error('handler failed!'); - }); - - registerEventListener({ name, handler }); - const data = { entry: fromJS({ data: {} }) }; - - await expect(invokeEvent({ name, data })).rejects.toThrow('handler failed!'); - }); - }); - - it(`should return an updated entry's DataMap`, async () => { - const { registerEventListener, invokeEvent } = require('../registry'); - - const event = 'preSave'; - const options = { hello: 'world' }; - const handler1 = jest.fn(({ entry }) => { - const data = entry.get('data'); - return data.set('a', 'test1'); - }); - const handler2 = jest.fn(({ entry }) => { - const data = entry.get('data'); - return data.set('c', 'test2'); - }); - - registerEventListener({ name: event, handler: handler1 }, options); - registerEventListener({ name: event, handler: handler2 }, options); - - const data = { - entry: fromJS({ data: { a: 'foo', b: 'bar' } }), - }; - - const dataAfterFirstHandlerExecution = { - entry: fromJS({ data: { a: 'test1', b: 'bar' } }), - }; - const dataAfterSecondHandlerExecution = { - entry: fromJS({ data: { a: 'test1', b: 'bar', c: 'test2' } }), - }; - - const result = await invokeEvent({ name: event, data }); - - expect(handler1).toHaveBeenCalledWith(data, options); - expect(handler2).toHaveBeenCalledWith(dataAfterFirstHandlerExecution, options); - - expect(result).toEqual(dataAfterSecondHandlerExecution.entry.get('data')); - }); - - it('should allow multiple events to not return a value', async () => { - const { registerEventListener, invokeEvent } = require('../registry'); - - const event = 'prePublish'; - const options = { hello: 'world' }; - const handler1 = jest.fn(); - const handler2 = jest.fn(); - - registerEventListener({ name: event, handler: handler1 }, options); - registerEventListener({ name: event, handler: handler2 }, options); - - const data = { - entry: fromJS({ data: { a: 'foo', b: 'bar' } }), - }; - const result = await invokeEvent({ name: event, data }); - - expect(handler1).toHaveBeenCalledWith(data, options); - expect(handler2).toHaveBeenCalledWith(data, options); - expect(result).toEqual(data.entry.get('data')); - }); - }); - }); -}); diff --git a/packages/netlify-cms-core/src/lib/__tests__/serializeEntryValues.spec.js b/packages/netlify-cms-core/src/lib/__tests__/serializeEntryValues.spec.js deleted file mode 100644 index 755ce698..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/serializeEntryValues.spec.js +++ /dev/null @@ -1,22 +0,0 @@ -import { fromJS } from 'immutable'; - -import { serializeValues, deserializeValues } from '../serializeEntryValues'; - -const values = fromJS({ title: 'New Post', unknown: 'Unknown Field' }); -const fields = fromJS([{ name: 'title', widget: 'string' }]); - -describe('serializeValues', () => { - it('should retain unknown fields', () => { - expect(serializeValues(values, fields)).toEqual( - fromJS({ title: 'New Post', unknown: 'Unknown Field' }), - ); - }); -}); - -describe('deserializeValues', () => { - it('should retain unknown fields', () => { - expect(deserializeValues(values, fields)).toEqual( - fromJS({ title: 'New Post', unknown: 'Unknown Field' }), - ); - }); -}); diff --git a/packages/netlify-cms-core/src/lib/__tests__/urlHelper.spec.js b/packages/netlify-cms-core/src/lib/__tests__/urlHelper.spec.js deleted file mode 100644 index abcdc9c9..00000000 --- a/packages/netlify-cms-core/src/lib/__tests__/urlHelper.spec.js +++ /dev/null @@ -1,138 +0,0 @@ -import { sanitizeURI, sanitizeSlug, sanitizeChar } from '../urlHelper'; - -describe('sanitizeURI', () => { - // `sanitizeURI` tests from RFC 3987 - it('should keep valid URI chars (letters digits _ - . ~)', () => { - expect(sanitizeURI('This, that-one_or.the~other 123!')).toEqual('Thisthat-one_or.the~other123'); - }); - - it('should not remove accents', () => { - expect(sanitizeURI('ěščřžý')).toEqual('ěščřžý'); - }); - - it('should keep valid non-latin chars (ucschars in RFC 3987)', () => { - expect(sanitizeURI('日本語のタイトル')).toEqual('日本語のタイトル'); - }); - - it('should not keep valid non-latin chars (ucschars in RFC 3987) if set to ASCII mode', () => { - expect(sanitizeURI('ěščřžý日本語のタイトル', { encoding: 'ascii' })).toEqual(''); - }); - - it('should not normalize Unicode strings', () => { - expect(sanitizeURI('\u017F\u0323\u0307')).toEqual('\u017F\u0323\u0307'); - expect(sanitizeURI('\u017F\u0323\u0307')).not.toEqual('\u1E9B\u0323'); - }); - - it('should allow a custom replacement character', () => { - expect(sanitizeURI('duck\\goose.elephant', { replacement: '-' })).toEqual( - 'duck-goose.elephant', - ); - }); - - it('should not allow an improper replacement character', () => { - expect(() => { - sanitizeURI('I! like! dollars!', { replacement: '$' }); - }).toThrow(); - }); - - it('should not actually URI-encode the characters', () => { - expect(sanitizeURI('🎉')).toEqual('🎉'); - expect(sanitizeURI('🎉')).not.toEqual('%F0%9F%8E%89'); - }); -}); - -const slugConfig = { - encoding: 'unicode', - clean_accents: false, - sanitize_replacement: '-', -}; - -describe('sanitizeSlug', () => { - it('throws an error for non-strings', () => { - expect(() => sanitizeSlug({})).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug([])).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug(false)).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug(null)).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug(11234)).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug(undefined)).toThrowError('The input slug must be a string.'); - expect(() => sanitizeSlug(() => {})).toThrowError('The input slug must be a string.'); - }); - - it('throws an error for non-string replacements', () => { - expect(() => sanitizeSlug('test', { sanitize_replacement: {} })).toThrowError( - '`options.replacement` must be a string.', - ); - expect(() => sanitizeSlug('test', { sanitize_replacement: [] })).toThrowError( - '`options.replacement` must be a string.', - ); - expect(() => sanitizeSlug('test', { sanitize_replacement: false })).toThrowError( - '`options.replacement` must be a string.', - ); - expect(() => sanitizeSlug('test', { sanitize_replacement: null })).toThrowError( - '`options.replacement` must be a string.', - ); - expect(() => sanitizeSlug('test', { sanitize_replacement: 11232 })).toThrowError( - '`options.replacement` must be a string.', - ); - // do not test undefined for this variant since a default is set in the constructor. - //expect(() => sanitizeSlug('test', { sanitize_replacement: undefined })).toThrowError("`options.replacement` must be a string."); - expect(() => sanitizeSlug('test', { sanitize_replacement: () => {} })).toThrowError( - '`options.replacement` must be a string.', - ); - }); - - it('should keep valid URI chars (letters digits _ - . ~)', () => { - expect(sanitizeSlug('This, that-one_or.the~other 123!', slugConfig)).toEqual( - 'This-that-one_or.the~other-123', - ); - }); - - it('should remove accents with `clean_accents` set', () => { - expect(sanitizeSlug('ěščřžý', { ...slugConfig, clean_accents: true })).toEqual('escrzy'); - }); - - it('should remove non-latin chars in "ascii" mode', () => { - expect(sanitizeSlug('ěščřžý日本語のタイトル', { ...slugConfig, encoding: 'ascii' })).toEqual( - '', - ); - }); - - it('should clean accents and strip non-latin chars in "ascii" mode with `clean_accents` set', () => { - expect( - sanitizeSlug('ěščřžý日本語のタイトル', { - ...slugConfig, - encoding: 'ascii', - clean_accents: true, - }), - ).toEqual('escrzy'); - }); - - it('removes double replacements', () => { - expect(sanitizeSlug('test--test', slugConfig)).toEqual('test-test'); - expect(sanitizeSlug('test test', slugConfig)).toEqual('test-test'); - }); - - it('removes trailing replacements', () => { - expect(sanitizeSlug('test test ', slugConfig)).toEqual('test-test'); - }); - - it('removes leading replacements', () => { - expect(sanitizeSlug('"test" test', slugConfig)).toEqual('test-test'); - }); - - it('uses alternate replacements', () => { - expect(sanitizeSlug('test test ', { ...slugConfig, sanitize_replacement: '_' })).toEqual( - 'test_test', - ); - }); -}); - -describe('sanitizeChar', () => { - it('should sanitize whitespace with default replacement', () => { - expect(sanitizeChar(' ', slugConfig)).toBe('-'); - }); - - it('should sanitize whitespace with custom replacement', () => { - expect(sanitizeChar(' ', { ...slugConfig, sanitize_replacement: '_' })).toBe('_'); - }); -}); diff --git a/packages/netlify-cms-lib-auth/src/implicit-oauth.js b/packages/netlify-cms-core/src/lib/auth/implicit-oauth.js similarity index 100% rename from packages/netlify-cms-lib-auth/src/implicit-oauth.js rename to packages/netlify-cms-core/src/lib/auth/implicit-oauth.js diff --git a/packages/netlify-cms-core/src/lib/auth/index.d.ts b/packages/netlify-cms-core/src/lib/auth/index.d.ts new file mode 100644 index 00000000..37784845 --- /dev/null +++ b/packages/netlify-cms-core/src/lib/auth/index.d.ts @@ -0,0 +1,9 @@ +class NetlifyAuthenticator { + constructor(config = {}); + + refresh: (args: { + provider: string; + refresh_token: string; + }) => Promise<{ token: string; refresh_token: string }>; +} +export { NetlifyAuthenticator }; diff --git a/packages/netlify-cms-lib-auth/src/index.js b/packages/netlify-cms-core/src/lib/auth/index.js similarity index 100% rename from packages/netlify-cms-lib-auth/src/index.js rename to packages/netlify-cms-core/src/lib/auth/index.js diff --git a/packages/netlify-cms-lib-auth/src/netlify-auth.js b/packages/netlify-cms-core/src/lib/auth/netlify-auth.js similarity index 100% rename from packages/netlify-cms-lib-auth/src/netlify-auth.js rename to packages/netlify-cms-core/src/lib/auth/netlify-auth.js diff --git a/packages/netlify-cms-lib-auth/src/pkce-oauth.js b/packages/netlify-cms-core/src/lib/auth/pkce-oauth.js similarity index 100% rename from packages/netlify-cms-lib-auth/src/pkce-oauth.js rename to packages/netlify-cms-core/src/lib/auth/pkce-oauth.js diff --git a/packages/netlify-cms-lib-auth/src/utils.js b/packages/netlify-cms-core/src/lib/auth/utils.js similarity index 100% rename from packages/netlify-cms-lib-auth/src/utils.js rename to packages/netlify-cms-core/src/lib/auth/utils.js diff --git a/packages/netlify-cms-core/src/lib/formatters.ts b/packages/netlify-cms-core/src/lib/formatters.ts index 369268d6..b10ebba4 100644 --- a/packages/netlify-cms-core/src/lib/formatters.ts +++ b/packages/netlify-cms-core/src/lib/formatters.ts @@ -1,19 +1,20 @@ -import { flow, partialRight, trimEnd, trimStart } from 'lodash'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; import { stripIndent } from 'common-tags'; +import { flow, partialRight, trimEnd, trimStart } from 'lodash'; -import { - selectIdentifier, - selectField, - selectInferedField, - getFileFromSlug, -} from '../reducers/collections'; -import { sanitizeSlug } from './urlHelper'; import { FILES } from '../constants/collectionTypes'; import { COMMIT_AUTHOR, COMMIT_DATE } from '../constants/commitProps'; +import { stringTemplate } from '../lib/widgets'; +import { + getFileFromSlug, + selectField, + selectIdentifier, + selectInferedField, +} from '../reducers/collections'; +import { sanitizeSlug } from './urlHelper'; -import type { Collection, CmsConfig, CmsSlug, EntryMap } from '../types/redux'; import type { Map } from 'immutable'; +import { CmsConfig } from '../interface'; +import type { CmsSlug, Collection, EntryMap } from '../types/redux'; const { compileStringTemplate, @@ -193,7 +194,7 @@ export function previewUrlFormatter( try { compiledPath = compileStringTemplate(pathTemplate, date, slug, fields, processSegment); - } catch (err) { + } catch (err: any) { // Print an error and ignore `preview_path` if both: // 1. Date is invalid (according to Moment), and // 2. A date expression (eg. `{{year}}`) is used in `preview_path` diff --git a/packages/netlify-cms-core/src/lib/index.tsx b/packages/netlify-cms-core/src/lib/index.tsx new file mode 100644 index 00000000..9902acc0 --- /dev/null +++ b/packages/netlify-cms-core/src/lib/index.tsx @@ -0,0 +1,3 @@ +export * from './auth'; +export * from './util'; +export * from './widgets'; diff --git a/packages/netlify-cms-core/src/lib/registry.js b/packages/netlify-cms-core/src/lib/registry.js index dfe21807..eb36c109 100644 --- a/packages/netlify-cms-core/src/lib/registry.js +++ b/packages/netlify-cms-core/src/lib/registry.js @@ -92,7 +92,7 @@ export function getPreviewTemplate(name) { /** * Editor Widgets */ -export function registerWidget(name, control, preview, schema = {}) { +export function registerWidget(name, control, preview, validtor = () => {}, schema = {}) { if (Array.isArray(name)) { name.forEach(widget => { if (typeof widget !== 'object') { @@ -105,12 +105,13 @@ export function registerWidget(name, control, preview, schema = {}) { // A registered widget control can be reused by a new widget, allowing // multiple copies with different previews. const newControl = typeof control === 'string' ? registry.widgets[control].control : control; - registry.widgets[name] = { control: newControl, preview, schema }; + registry.widgets[name] = { control: newControl, preview, validtor, schema }; } else if (typeof name === 'object') { const { name: widgetName, controlComponent: control, previewComponent: preview, + validtor = () => {}, schema = {}, allowMapValue, globalStyles, @@ -128,6 +129,7 @@ export function registerWidget(name, control, preview, schema = {}) { registry.widgets[widgetName] = { control, preview, + validtor, schema, globalStyles, allowMapValue, @@ -304,9 +306,12 @@ export function getIcon(name) { /** * Icons */ -export function registerAdditionalLink(id, title, url, iconName) { - registry.additionalLinks[id] = { title, url, iconName }; +export function registerAdditionalLink(id, title, data, iconName) { + registry.additionalLinks[id] = { id, title, data, iconName }; } export function getAdditionalLinks() { return registry.additionalLinks; } +export function getAdditionalLink(id) { + return registry.additionalLinks[id]; +} diff --git a/packages/netlify-cms-lib-util/src/API.ts b/packages/netlify-cms-core/src/lib/util/API.ts similarity index 98% rename from packages/netlify-cms-lib-util/src/API.ts rename to packages/netlify-cms-core/src/lib/util/API.ts index f328cf78..a7481936 100644 --- a/packages/netlify-cms-lib-util/src/API.ts +++ b/packages/netlify-cms-core/src/lib/util/API.ts @@ -71,13 +71,13 @@ export async function requestWithBackoff( response.json = () => Promise.resolve(json); } return response; - } catch (err) { + } catch (err: any) { if (attempt > 5 || err.message === "Can't refresh access token when using implicit auth") { throw err; } else { if (!api.rateLimiter) { const timeout = err.resetSeconds || attempt * attempt; - console.log( + console.info( `Pausing requests for ${timeout} ${ attempt === 1 ? 'second' : 'seconds' } due to fetch failures:`, @@ -88,7 +88,7 @@ export async function requestWithBackoff( setTimeout(() => { api.rateLimiter?.release(); api.rateLimiter = undefined; - console.log(`Done pausing requests`); + console.info(`Done pausing requests`); }, 1000 * timeout); } return requestWithBackoff(api, req, attempt + 1); diff --git a/packages/netlify-cms-lib-util/src/APIError.ts b/packages/netlify-cms-core/src/lib/util/APIError.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/APIError.ts rename to packages/netlify-cms-core/src/lib/util/APIError.ts diff --git a/packages/netlify-cms-lib-util/src/APIUtils.ts b/packages/netlify-cms-core/src/lib/util/APIUtils.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/APIUtils.ts rename to packages/netlify-cms-core/src/lib/util/APIUtils.ts diff --git a/packages/netlify-cms-lib-util/src/AccessTokenError.ts b/packages/netlify-cms-core/src/lib/util/AccessTokenError.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/AccessTokenError.ts rename to packages/netlify-cms-core/src/lib/util/AccessTokenError.ts diff --git a/packages/netlify-cms-lib-util/src/Cursor.ts b/packages/netlify-cms-core/src/lib/util/Cursor.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/Cursor.ts rename to packages/netlify-cms-core/src/lib/util/Cursor.ts diff --git a/packages/netlify-cms-lib-util/src/EditorialWorkflowError.ts b/packages/netlify-cms-core/src/lib/util/EditorialWorkflowError.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/EditorialWorkflowError.ts rename to packages/netlify-cms-core/src/lib/util/EditorialWorkflowError.ts diff --git a/packages/netlify-cms-lib-util/src/asyncLock.ts b/packages/netlify-cms-core/src/lib/util/asyncLock.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/asyncLock.ts rename to packages/netlify-cms-core/src/lib/util/asyncLock.ts diff --git a/packages/netlify-cms-lib-util/src/backendUtil.ts b/packages/netlify-cms-core/src/lib/util/backendUtil.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/backendUtil.ts rename to packages/netlify-cms-core/src/lib/util/backendUtil.ts diff --git a/packages/netlify-cms-core/src/lib/util/events/AlertEvent.ts b/packages/netlify-cms-core/src/lib/util/events/AlertEvent.ts new file mode 100644 index 00000000..bd2144a1 --- /dev/null +++ b/packages/netlify-cms-core/src/lib/util/events/AlertEvent.ts @@ -0,0 +1,7 @@ +import { AlertDialogProps } from '../../../components/UI/Alert'; + +export default class AlertEvent extends CustomEvent { + constructor(detail: AlertDialogProps) { + super('alert', { detail }); + } +} diff --git a/packages/netlify-cms-core/src/lib/util/events/ConfirmEvent.ts b/packages/netlify-cms-core/src/lib/util/events/ConfirmEvent.ts new file mode 100644 index 00000000..969a69eb --- /dev/null +++ b/packages/netlify-cms-core/src/lib/util/events/ConfirmEvent.ts @@ -0,0 +1,7 @@ +import { ConfirmDialogProps } from '../../../components/UI/Confirm'; + +export default class ConfirmEvent extends CustomEvent { + constructor(detail: ConfirmDialogProps) { + super('confirm', { detail }); + } +} diff --git a/packages/netlify-cms-lib-util/src/getBlobSHA.ts b/packages/netlify-cms-core/src/lib/util/getBlobSHA.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/getBlobSHA.ts rename to packages/netlify-cms-core/src/lib/util/getBlobSHA.ts diff --git a/packages/netlify-cms-lib-util/src/git-lfs.ts b/packages/netlify-cms-core/src/lib/util/git-lfs.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/git-lfs.ts rename to packages/netlify-cms-core/src/lib/util/git-lfs.ts diff --git a/packages/netlify-cms-lib-util/src/implementation.ts b/packages/netlify-cms-core/src/lib/util/implementation.ts similarity index 83% rename from packages/netlify-cms-lib-util/src/implementation.ts rename to packages/netlify-cms-core/src/lib/util/implementation.ts index 45542382..f598d2ed 100644 --- a/packages/netlify-cms-lib-util/src/implementation.ts +++ b/packages/netlify-cms-core/src/lib/util/implementation.ts @@ -1,12 +1,12 @@ +import { sortBy, unionBy } from 'lodash'; import semaphore from 'semaphore'; -import { unionBy, sortBy } from 'lodash'; import { basename } from './path'; import type { Semaphore } from 'semaphore'; -import type Cursor from './Cursor'; -import type { AsyncLock } from './asyncLock'; +import type { Implementation as I } from '../../interface'; import type { FileMetadata } from './API'; +import type { AsyncLock } from './asyncLock'; export type DisplayURLObject = { id: string; path: string }; @@ -119,76 +119,7 @@ export type Config = { site_id?: string; }; -export interface Implementation { - authComponent: () => void; - restoreUser: (user: User) => Promise; - - authenticate: (credentials: Credentials) => Promise; - logout: () => Promise | void | null; - getToken: () => Promise; - - getEntry: (path: string) => Promise; - entriesByFolder: ( - folder: string, - extension: string, - depth: number, - ) => Promise; - entriesByFiles: (files: ImplementationFile[]) => Promise; - - getMediaDisplayURL?: (displayURL: DisplayURL) => Promise; - getMedia: (folder?: string) => Promise; - getMediaFile: (path: string) => Promise; - - persistEntry: (entry: Entry, opts: PersistOptions) => Promise; - persistMedia: (file: AssetProxy, opts: PersistOptions) => Promise; - deleteFiles: (paths: string[], commitMessage: string) => Promise; - - unpublishedEntries: () => Promise; - unpublishedEntry: (args: { - id?: string; - collection?: string; - slug?: string; - }) => Promise; - unpublishedEntryDataFile: ( - collection: string, - slug: string, - path: string, - id: string, - ) => Promise; - unpublishedEntryMediaFile: ( - collection: string, - slug: string, - path: string, - id: string, - ) => Promise; - updateUnpublishedEntryStatus: ( - collection: string, - slug: string, - newStatus: string, - ) => Promise; - publishUnpublishedEntry: (collection: string, slug: string) => Promise; - deleteUnpublishedEntry: (collection: string, slug: string) => Promise; - getDeployPreview: ( - collectionName: string, - slug: string, - ) => Promise<{ url: string; status: string } | null>; - - allEntriesByFolder?: ( - folder: string, - extension: string, - depth: number, - ) => Promise; - traverseCursor?: ( - cursor: Cursor, - action: string, - ) => Promise<{ entries: ImplementationEntry[]; cursor: Cursor }>; - - isGitBackend?: () => boolean; - status: () => Promise<{ - auth: { status: boolean }; - api: { status: boolean; statusPage: string }; - }>; -} +export type Implementation = I; const MAX_CONCURRENT_DOWNLOADS = 10; @@ -264,7 +195,7 @@ export async function unpublishedEntries(listEntriesKeys: () => Promise { - console.log('Failed getting diff from local tree:', e); + console.info('Failed getting diff from local tree:', e); return null; }); if (!diff) { - console.log(`Diff is null, rebuilding local tree`); + console.info(`Diff is null, rebuilding local tree`); return listAllFilesAndPersist(); } diff --git a/packages/netlify-cms-lib-util/src/index.ts b/packages/netlify-cms-core/src/lib/util/index.ts similarity index 99% rename from packages/netlify-cms-lib-util/src/index.ts rename to packages/netlify-cms-core/src/lib/util/index.ts index 2e18957f..dc2cd9cf 100644 --- a/packages/netlify-cms-lib-util/src/index.ts +++ b/packages/netlify-cms-core/src/lib/util/index.ts @@ -152,6 +152,7 @@ export const NetlifyCmsLibUtil = { allEntriesByFolder, AccessTokenError, throwOnConflictingBranches, + transientOptions }; export { APIError, diff --git a/packages/netlify-cms-lib-util/src/loadScript.js b/packages/netlify-cms-core/src/lib/util/loadScript.js similarity index 100% rename from packages/netlify-cms-lib-util/src/loadScript.js rename to packages/netlify-cms-core/src/lib/util/loadScript.js diff --git a/packages/netlify-cms-lib-util/src/localForage.ts b/packages/netlify-cms-core/src/lib/util/localForage.ts similarity index 94% rename from packages/netlify-cms-lib-util/src/localForage.ts rename to packages/netlify-cms-core/src/lib/util/localForage.ts index 2871a9b7..c7589caf 100644 --- a/packages/netlify-cms-lib-util/src/localForage.ts +++ b/packages/netlify-cms-core/src/lib/util/localForage.ts @@ -12,7 +12,7 @@ function localForageTest() { const message = 'Unable to set localStorage key. Quota exceeded! Full disk?'; console.warn(message); } - console.log(err); + console.info(err); }); } diff --git a/packages/netlify-cms-lib-util/src/path.ts b/packages/netlify-cms-core/src/lib/util/path.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/path.ts rename to packages/netlify-cms-core/src/lib/util/path.ts diff --git a/packages/netlify-cms-lib-util/src/promise.ts b/packages/netlify-cms-core/src/lib/util/promise.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/promise.ts rename to packages/netlify-cms-core/src/lib/util/promise.ts diff --git a/packages/netlify-cms-lib-util/src/transientOptions.ts b/packages/netlify-cms-core/src/lib/util/transientOptions.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/transientOptions.ts rename to packages/netlify-cms-core/src/lib/util/transientOptions.ts diff --git a/packages/netlify-cms-lib-util/src/types/semaphore.d.ts b/packages/netlify-cms-core/src/lib/util/types/semaphore.d.ts similarity index 100% rename from packages/netlify-cms-lib-util/src/types/semaphore.d.ts rename to packages/netlify-cms-core/src/lib/util/types/semaphore.d.ts diff --git a/packages/netlify-cms-lib-util/src/unsentRequest.js b/packages/netlify-cms-core/src/lib/util/unsentRequest.js similarity index 100% rename from packages/netlify-cms-lib-util/src/unsentRequest.js rename to packages/netlify-cms-core/src/lib/util/unsentRequest.js diff --git a/packages/netlify-cms-core/src/lib/util/window.util.ts b/packages/netlify-cms-core/src/lib/util/window.util.ts new file mode 100644 index 00000000..5a7f760e --- /dev/null +++ b/packages/netlify-cms-core/src/lib/util/window.util.ts @@ -0,0 +1,23 @@ +import { useEffect } from 'react'; +import AlertEvent from './events/AlertEvent'; +import ConfirmEvent from './events/ConfirmEvent'; + +interface EventMap { + alert: AlertEvent; + confirm: ConfirmEvent; +} + +export function useWindowEvent( + eventName: K, + callback: (event: WindowEventMap[K]) => void +): void; +export function useWindowEvent(eventName: K, callback: (event: EventMap[K]) => void): void; +export function useWindowEvent(eventName: string, callback: EventListenerOrEventListenerObject): void { + useEffect(() => { + window.addEventListener(eventName, callback); + + return () => { + window.removeEventListener(eventName, callback); + }; + }, []); +} diff --git a/packages/netlify-cms-lib-widgets/src/index.ts b/packages/netlify-cms-core/src/lib/widgets/index.ts similarity index 100% rename from packages/netlify-cms-lib-widgets/src/index.ts rename to packages/netlify-cms-core/src/lib/widgets/index.ts diff --git a/packages/netlify-cms-lib-widgets/src/stringTemplate.ts b/packages/netlify-cms-core/src/lib/widgets/stringTemplate.ts similarity index 93% rename from packages/netlify-cms-lib-widgets/src/stringTemplate.ts rename to packages/netlify-cms-core/src/lib/widgets/stringTemplate.ts index 43f16a16..3c0afd75 100644 --- a/packages/netlify-cms-lib-widgets/src/stringTemplate.ts +++ b/packages/netlify-cms-core/src/lib/widgets/stringTemplate.ts @@ -33,6 +33,26 @@ const filters = [ }); }, }, + { + pattern: /^split\('(.+)',\s*'(.+)'\)$/, + transform: (str: string, match: RegExpMatchArray) => { + if (!str || str.trim().length === 0) { + return ''; + } + + const parts = str.split(match[1]); + if (parts.length === 0) { + return ''; + } + + let output = match[2]; + for (let i = 0; i < match[2].length; i++) { + output = output.replace(new RegExp(`\\$${i + 1}`, 'g'), parts[i]); + } + + return output; + }, + }, ]; const FIELD_PREFIX = 'fields.'; diff --git a/packages/netlify-cms-lib-widgets/src/validations.ts b/packages/netlify-cms-core/src/lib/widgets/validations.ts similarity index 100% rename from packages/netlify-cms-lib-widgets/src/validations.ts rename to packages/netlify-cms-core/src/lib/widgets/validations.ts diff --git a/packages/netlify-cms-locales/src/en/index.js b/packages/netlify-cms-core/src/locales/en/index.js similarity index 77% rename from packages/netlify-cms-locales/src/en/index.js rename to packages/netlify-cms-core/src/locales/en/index.js index 400eaf6b..9cb3f2f4 100644 --- a/packages/netlify-cms-locales/src/en/index.js +++ b/packages/netlify-cms-core/src/locales/en/index.js @@ -10,10 +10,17 @@ const en = { errors: { email: 'Make sure to enter your email.', password: 'Please enter your password.', + authTitle: 'Error logging in', + authBody: '%{details}', identitySettings: 'Unable to access identity settings. When using git-gateway backend make sure to enable Identity service and Git Gateway.', }, }, + api: { + labelsMigrationTitle: 'Labels Migration', + labelsMigrationBody: + 'Netlify CMS is adding labels to %{pullRequests} of your Editorial Workflow entries. The "Workflow" tab will be unavailable during this migration. You may use other areas of the CMS during this time. Note that closing the CMS will pause the migration.', + }, app: { header: { content: 'Contents', @@ -93,26 +100,41 @@ const en = { i18n: { writingInLocale: 'Writing in %{locale}', copyFromLocale: 'Fill in from another locale', - copyFromLocaleConfirm: + copyFromLocaleConfirmTitle: + 'Fill in data from locale', + copyFromLocaleConfirmBody: 'Do you want to fill in data from %{locale} locale?\nAll existing content will be overwritten.', }, }, editor: { onLeavePage: 'Are you sure you want to leave this page?', - onUpdatingWithUnsavedChanges: 'You have unsaved changes, please save before updating status.', - onPublishingNotReady: 'Please update status to "Ready" before publishing.', - onPublishingWithUnsavedChanges: 'You have unsaved changes, please save before publishing.', - onPublishing: 'Are you sure you want to publish this entry?', - onUnpublishing: 'Are you sure you want to unpublish this entry?', - onDeleteWithUnsavedChanges: + onUpdatingWithUnsavedChangesTitle: 'Unsaved changes', + onUpdatingWithUnsavedChangesBody: + 'You have unsaved changes, please save before updating status.', + onPublishingNotReadyTitle: 'Publishing unavailable', + onPublishingNotReadyBody: 'Please update status to "Ready" before publishing.', + onPublishingWithUnsavedChangesTitle: 'Unsaved changes', + onPublishingWithUnsavedChangesBody: + 'You have unsaved changes, please save before publishing.', + onPublishingTitle: 'Publish this entry?', + onPublishingBody: 'Are you sure you want to publish this entry?', + onUnpublishingTitle: 'Unpublish this entry?', + onUnpublishingBody: 'Are you sure you want to unpublish this entry?', + onDeleteWithUnsavedChangesTitle: 'Delete this published entry?', + onDeleteWithUnsavedChangesBody: 'Are you sure you want to delete this published entry, as well as your unsaved changes from the current session?', - onDeletePublishedEntry: 'Are you sure you want to delete this published entry?', - onDeleteUnpublishedChangesWithUnsavedChanges: + onDeletePublishedEntryTitle: 'Delete this published entry?', + onDeletePublishedEntryBody: 'Are you sure you want to delete this published entry?', + onDeleteUnpublishedChangesWithUnsavedChangesTitle: 'Delete this entry?', + onDeleteUnpublishedChangesWithUnsavedChangesBody: 'This will delete all unpublished changes to this entry, as well as your unsaved changes from the current session. Do you still want to delete?', - onDeleteUnpublishedChanges: + onDeleteUnpublishedChangesTitle: 'Delete this entry?', + onDeleteUnpublishedChangesBody: 'All unpublished changes to this entry will be deleted. Do you still want to delete?', loadingEntry: 'Loading entry...', - confirmLoadBackup: 'A local backup was recovered for this entry, would you like to use it?', + confirmLoadBackupTitle: 'Use local backup?', + confirmLoadBackupBody: + 'A local backup was recovered for this entry, would you like to use it?', }, editorInterface: { toggleI18n: 'Toggle i18n', @@ -205,6 +227,8 @@ const en = { }, datetime: { now: 'Now', + invalidDateTitle: 'Invalid date', + invalidDateBody: 'The date you entered is invalid.', }, list: { add: 'Add %{item}', @@ -222,8 +246,12 @@ const en = { copied: 'Copied', }, mediaLibrary: { - onDelete: 'Are you sure you want to delete selected media?', - fileTooLarge: 'File too large.\nConfigured to not allow files greater than %{size} kB.', + onDeleteTitle: 'Delete selected media?', + onDeleteBody: 'Are you sure you want to delete selected media?', + fileTooLargeTitle: 'File too large', + fileTooLargeBody: 'File too large.\nConfigured to not allow files greater than %{size} kB.', + alreadyExistsTitle: 'File already exists', + alreadyExistsBody: `%{filename} already exists. Do you want to replace it?` }, mediaLibraryModal: { loading: 'Loading...', @@ -243,6 +271,11 @@ const en = { }, }, ui: { + common: { + yes: 'Yes', + no: 'No', + okay: 'OK', + }, default: { goBackToSite: 'Go back to site', }, @@ -266,7 +299,9 @@ const en = { onFailToLoadEntries: 'Failed to load entry: %{details}', onFailToLoadDeployPreview: 'Failed to load preview: %{details}', onFailToPersist: 'Failed to persist entry: %{details}', + onFailToPersistMedia: 'Failed to persist media: %{details}', onFailToDelete: 'Failed to delete entry: %{details}', + onFailToDeleteMedia: 'Failed to delete media: %{details}', onFailToUpdateStatus: 'Failed to update status: %{details}', missingRequiredField: "Oops, you've missed a required field. Please complete before saving.", entrySaved: 'Entry saved', @@ -301,10 +336,13 @@ const en = { publishNewEntry: 'Publish new entry', }, workflowList: { - onDeleteEntry: 'Are you sure you want to delete this entry?', - onPublishingNotReadyEntry: + onDeleteEntryTitle: 'Delete this entry?', + onDeleteEntryBody: 'Are you sure you want to delete this entry?', + onPublishingNotReadyEntryTitle: 'Not ready to be published', + onPublishingNotReadyEntryBody: 'Only items with a "Ready" status can be published. Please drag the card to the "Ready" column to enable publishing.', - onPublishEntry: 'Are you sure you want to publish this entry?', + onPublishEntryTitle: 'Publish this entry?', + onPublishEntryBody: 'Are you sure you want to publish this entry?', draftHeader: 'Drafts', inReviewHeader: 'In Review', readyHeader: 'Ready', diff --git a/packages/netlify-cms-core/src/locales/index.ts b/packages/netlify-cms-core/src/locales/index.ts new file mode 100644 index 00000000..a78c7854 --- /dev/null +++ b/packages/netlify-cms-core/src/locales/index.ts @@ -0,0 +1,5 @@ +import en from './en'; + +export const locales: Record> = { + en, +}; diff --git a/packages/netlify-cms-media-library-cloudinary/src/index.js b/packages/netlify-cms-core/src/media-libraries/cloudinary/index.js similarity index 97% rename from packages/netlify-cms-media-library-cloudinary/src/index.js rename to packages/netlify-cms-core/src/media-libraries/cloudinary/index.js index bd1cd306..8367618e 100644 --- a/packages/netlify-cms-media-library-cloudinary/src/index.js +++ b/packages/netlify-cms-core/src/media-libraries/cloudinary/index.js @@ -1,5 +1,6 @@ import { pick } from 'lodash'; -import { loadScript } from 'netlify-cms-lib-util'; + +import { loadScript } from '../../lib/util'; const defaultOptions = { use_secure_url: true, @@ -14,7 +15,7 @@ const enforcedConfig = { button_class: undefined, inline_container: undefined, insert_transformation: false, - z_index: '99999', + z_index: '1003', }; const defaultConfig = { diff --git a/packages/netlify-cms-core/src/media-libraries/index.tsx b/packages/netlify-cms-core/src/media-libraries/index.tsx new file mode 100644 index 00000000..d8023220 --- /dev/null +++ b/packages/netlify-cms-core/src/media-libraries/index.tsx @@ -0,0 +1,4 @@ +import MediaLibraryCloudinary from './cloudinary'; +import MediaLibraryUploadcare from './uploadcare'; + +export { MediaLibraryCloudinary, MediaLibraryUploadcare }; diff --git a/packages/netlify-cms-media-library-uploadcare/src/index.js b/packages/netlify-cms-core/src/media-libraries/uploadcare/index.js similarity index 100% rename from packages/netlify-cms-media-library-uploadcare/src/index.js rename to packages/netlify-cms-core/src/media-libraries/uploadcare/index.js diff --git a/packages/netlify-cms-core/src/mediaLibrary.ts b/packages/netlify-cms-core/src/mediaLibrary.ts index 461d1928..8a419e39 100644 --- a/packages/netlify-cms-core/src/mediaLibrary.ts +++ b/packages/netlify-cms-core/src/mediaLibrary.ts @@ -5,7 +5,7 @@ import { once } from 'lodash'; import { getMediaLibrary } from './lib/registry'; -import { store } from './redux'; +import { store } from './store'; import { configFailed } from './actions/config'; import { createMediaLibrary, insertMedia } from './actions/mediaLibrary'; diff --git a/packages/netlify-cms-core/src/reducers/auth.ts b/packages/netlify-cms-core/src/reducers/auth.ts index 559398a7..2ce7b873 100644 --- a/packages/netlify-cms-core/src/reducers/auth.ts +++ b/packages/netlify-cms-core/src/reducers/auth.ts @@ -8,7 +8,7 @@ import { LOGOUT, } from '../actions/auth'; -import type { User } from 'netlify-cms-lib-util'; +import type { User } from '../lib/util'; import type { AuthAction } from '../actions/auth'; export type Auth = { diff --git a/packages/netlify-cms-core/src/reducers/collections.ts b/packages/netlify-cms-core/src/reducers/collections.ts index 0bd045d5..160c21c1 100644 --- a/packages/netlify-cms-core/src/reducers/collections.ts +++ b/packages/netlify-cms-core/src/reducers/collections.ts @@ -1,28 +1,26 @@ -import { List, Set, fromJS, OrderedMap } from 'immutable'; -import { get, escapeRegExp } from 'lodash'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; +import { fromJS, List, OrderedMap, Set } from 'immutable'; +import { escapeRegExp, get } from 'lodash'; -import consoleError from '../lib/consoleError'; import { CONFIG_SUCCESS } from '../actions/config'; import { FILES, FOLDER } from '../constants/collectionTypes'; -import { COMMIT_DATE, COMMIT_AUTHOR } from '../constants/commitProps'; -import { INFERABLE_FIELDS, IDENTIFIER_FIELDS, SORTABLE_FIELDS } from '../constants/fieldInference'; +import { COMMIT_AUTHOR, COMMIT_DATE } from '../constants/commitProps'; +import { IDENTIFIER_FIELDS, INFERABLE_FIELDS, SORTABLE_FIELDS } from '../constants/fieldInference'; import { formatExtensions } from '../formats/formats'; -import { selectMediaFolder } from './entries'; +import consoleError from '../lib/consoleError'; import { summaryFormatter } from '../lib/formatters'; +import { stringTemplate } from '../lib/widgets'; +import { selectMediaFolder } from './entries'; -import type { - Collection, - Collections, - CollectionFiles, - EntryField, - EntryMap, - ViewFilter, - ViewGroup, - CmsConfig, -} from '../types/redux'; import type { ConfigAction } from '../actions/config'; import type { Backend } from '../backend'; +import type { CmsConfig, ViewFilter, ViewGroup } from '../interface'; +import type { + Collection, + CollectionFiles, + Collections, + EntryField, + EntryMap, +} from '../types/redux'; const { keyToPathArray } = stringTemplate; @@ -411,8 +409,7 @@ export function selectDefaultSortableFields( } export function selectSortableFields(collection: Collection, t: (key: string) => string) { - const fields = collection - .get('sortable_fields') + const fields = (collection.getIn(['sortable_fields', 'fields']) as List) .toArray() .map(key => { if (key === COMMIT_DATE) { diff --git a/packages/netlify-cms-core/src/reducers/combinedReducer.ts b/packages/netlify-cms-core/src/reducers/combinedReducer.ts index 3bcbeb98..2e65cd82 100644 --- a/packages/netlify-cms-core/src/reducers/combinedReducer.ts +++ b/packages/netlify-cms-core/src/reducers/combinedReducer.ts @@ -1,12 +1,12 @@ import { combineReducers } from 'redux'; -import { reducer as notifReducer } from 'redux-notifications'; +import snackbarReducer from '../store/slices/snackbars'; import reducers from './index'; function createRootReducer() { return combineReducers({ ...reducers, - notifs: notifReducer, + snackbar: snackbarReducer, }); } diff --git a/packages/netlify-cms-core/src/reducers/config.ts b/packages/netlify-cms-core/src/reducers/config.ts index d98546a4..b1b85390 100644 --- a/packages/netlify-cms-core/src/reducers/config.ts +++ b/packages/netlify-cms-core/src/reducers/config.ts @@ -1,16 +1,21 @@ import { produce } from 'immer'; -import { CONFIG_REQUEST, CONFIG_SUCCESS, CONFIG_FAILURE } from '../actions/config'; +import { CONFIG_FAILURE, CONFIG_REQUEST, CONFIG_SUCCESS } from '../actions/config'; import { EDITORIAL_WORKFLOW } from '../constants/publishModes'; import type { ConfigAction } from '../actions/config'; -import type { CmsConfig } from '../types/redux'; +import { CmsConfig } from '../interface'; -const defaultState = { +interface ConfigState extends Partial { + isFetching: boolean; + error?: string; +} + +const defaultState: ConfigState = { isFetching: true, }; -const config = produce((state: CmsConfig, action: ConfigAction) => { +const config = produce((state: ConfigState, action: ConfigAction) => { switch (action.type) { case CONFIG_REQUEST: state.isFetching = true; diff --git a/packages/netlify-cms-core/src/reducers/cursors.js b/packages/netlify-cms-core/src/reducers/cursors.js index c3f596be..7cc0c8b3 100644 --- a/packages/netlify-cms-core/src/reducers/cursors.js +++ b/packages/netlify-cms-core/src/reducers/cursors.js @@ -1,6 +1,6 @@ import { fromJS } from 'immutable'; -import { Cursor } from 'netlify-cms-lib-util'; +import { Cursor } from '../lib/util'; import { ENTRIES_SUCCESS, SORT_ENTRIES_SUCCESS, diff --git a/packages/netlify-cms-core/src/reducers/entries.ts b/packages/netlify-cms-core/src/reducers/entries.ts index 5983f774..5bd32184 100644 --- a/packages/netlify-cms-core/src/reducers/entries.ts +++ b/packages/netlify-cms-core/src/reducers/entries.ts @@ -1,66 +1,66 @@ -import { Map, List, fromJS, OrderedMap, Set } from 'immutable'; +import { fromJS, List, Map, OrderedMap, Set } from 'immutable'; +import { groupBy, once, orderBy, set, sortBy, trim } from 'lodash'; import { dirname, join } from 'path'; -import { isAbsolutePath, basename } from 'netlify-cms-lib-util'; -import { trim, once, sortBy, set, orderBy, groupBy } from 'lodash'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; -import { SortDirection } from '../types/redux'; -import { folderFormatter } from '../lib/formatters'; -import { selectSortDataPath } from './collections'; -import { SEARCH_ENTRIES_SUCCESS } from '../actions/search'; import { - ENTRY_REQUEST, - ENTRY_SUCCESS, - ENTRY_FAILURE, + CHANGE_VIEW_STYLE, + ENTRIES_FAILURE, ENTRIES_REQUEST, ENTRIES_SUCCESS, - ENTRIES_FAILURE, ENTRY_DELETE_SUCCESS, - SORT_ENTRIES_REQUEST, - SORT_ENTRIES_SUCCESS, - SORT_ENTRIES_FAILURE, + ENTRY_FAILURE, + ENTRY_REQUEST, + ENTRY_SUCCESS, + FILTER_ENTRIES_FAILURE, FILTER_ENTRIES_REQUEST, FILTER_ENTRIES_SUCCESS, - FILTER_ENTRIES_FAILURE, + GROUP_ENTRIES_FAILURE, GROUP_ENTRIES_REQUEST, GROUP_ENTRIES_SUCCESS, - GROUP_ENTRIES_FAILURE, - CHANGE_VIEW_STYLE, + SORT_ENTRIES_FAILURE, + SORT_ENTRIES_REQUEST, + SORT_ENTRIES_SUCCESS, } from '../actions/entries'; +import { SEARCH_ENTRIES_SUCCESS } from '../actions/search'; import { VIEW_STYLE_LIST } from '../constants/collectionViews'; +import { SortDirection } from '../interface'; +import { folderFormatter } from '../lib/formatters'; import { joinUrlPath } from '../lib/urlHelper'; +import { basename, isAbsolutePath } from '../lib/util'; +import { stringTemplate } from '../lib/widgets'; +import { selectSortDataPath } from './collections'; +import type { CmsConfig } from '../interface'; import type { + ChangeViewStylePayload, + Collection, + CollectionFiles, + Entries, EntriesAction, + EntriesFilterFailurePayload, + EntriesFilterRequestPayload, + EntriesGroupFailurePayload, + EntriesGroupRequestPayload, + EntriesRequestPayload, + EntriesSortFailurePayload, + EntriesSortRequestPayload, + EntriesSuccessPayload, + EntryDeletePayload, + EntryDraft, + EntryFailurePayload, + EntryField, + EntryMap, + EntryObject, EntryRequestPayload, EntrySuccessPayload, - EntriesSuccessPayload, - EntryObject, - Entries, - CmsConfig, - Collection, - EntryFailurePayload, - EntryDeletePayload, - EntriesRequestPayload, - EntryDraft, - EntryMap, - EntryField, - CollectionFiles, - EntriesSortRequestPayload, - EntriesSortFailurePayload, + Filter, + FilterMap, + Group, + GroupMap, + GroupOfEntries, + Sort, SortMap, SortObject, - Sort, - Filter, - Group, - FilterMap, - GroupMap, - EntriesFilterRequestPayload, - EntriesFilterFailurePayload, - ChangeViewStylePayload, - EntriesGroupRequestPayload, - EntriesGroupFailurePayload, - GroupOfEntries, } from '../types/redux'; const { keyToPathArray } = stringTemplate; @@ -459,7 +459,7 @@ function getGroup(entry: EntryMap, selectedGroup: GroupMap) { const dataAsString = String(fieldData); if (selectedGroup.has('pattern')) { - const pattern = selectedGroup.get('pattern'); + const pattern = selectedGroup.get('pattern') ?? ''; let value = ''; try { const regex = new RegExp(pattern); diff --git a/packages/netlify-cms-core/src/reducers/integrations.ts b/packages/netlify-cms-core/src/reducers/integrations.ts index b09a5aa8..e0a835f9 100644 --- a/packages/netlify-cms-core/src/reducers/integrations.ts +++ b/packages/netlify-cms-core/src/reducers/integrations.ts @@ -3,7 +3,8 @@ import { fromJS } from 'immutable'; import { CONFIG_SUCCESS } from '../actions/config'; import type { ConfigAction } from '../actions/config'; -import type { Integrations, CmsConfig } from '../types/redux'; +import { CmsConfig } from '../interface'; +import type { Integrations } from '../types/redux'; interface Acc { providers: Record; diff --git a/packages/netlify-cms-core/src/redux/index.ts b/packages/netlify-cms-core/src/redux/index.ts deleted file mode 100644 index cdb5ff63..00000000 --- a/packages/netlify-cms-core/src/redux/index.ts +++ /dev/null @@ -1,18 +0,0 @@ -import { createStore, applyMiddleware } from 'redux'; -import { composeWithDevTools } from 'redux-devtools-extension'; -import thunkMiddleware from 'redux-thunk'; - -import { waitUntilAction } from './middleware/waitUntilAction'; -import createRootReducer from '../reducers/combinedReducer'; - -import type { ThunkMiddleware } from 'redux-thunk'; -import type { AnyAction } from 'redux'; -import type { State } from '../types/redux'; -import type { Reducer } from 'react'; - -const store = createStore( - createRootReducer() as unknown as Reducer, - composeWithDevTools(applyMiddleware(thunkMiddleware as ThunkMiddleware, waitUntilAction)), -); - -export { store }; diff --git a/packages/netlify-cms-core/src/store/hooks.ts b/packages/netlify-cms-core/src/store/hooks.ts new file mode 100644 index 00000000..f4515ae0 --- /dev/null +++ b/packages/netlify-cms-core/src/store/hooks.ts @@ -0,0 +1,7 @@ +import { useDispatch, useSelector } from 'react-redux'; + +import type { RootState, AppDispatch } from './index'; +import type { TypedUseSelectorHook } from 'react-redux'; + +export const useAppDispatch = () => useDispatch(); +export const useAppSelector: TypedUseSelectorHook = useSelector; diff --git a/packages/netlify-cms-core/src/store/index.ts b/packages/netlify-cms-core/src/store/index.ts new file mode 100644 index 00000000..08231430 --- /dev/null +++ b/packages/netlify-cms-core/src/store/index.ts @@ -0,0 +1,17 @@ +import { configureStore } from '@reduxjs/toolkit'; + +import createRootReducer from '../reducers/combinedReducer'; +import { waitUntilAction } from './middleware/waitUntilAction'; + +const store = configureStore({ + reducer: createRootReducer(), + middleware: getDefaultMiddleware => + getDefaultMiddleware({ + immutableCheck: false, + serializableCheck: false, + }).concat(waitUntilAction), +}); + +export { store }; +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; diff --git a/packages/netlify-cms-core/src/redux/middleware/waitUntilAction.ts b/packages/netlify-cms-core/src/store/middleware/waitUntilAction.ts similarity index 84% rename from packages/netlify-cms-core/src/redux/middleware/waitUntilAction.ts rename to packages/netlify-cms-core/src/store/middleware/waitUntilAction.ts index 039c2b51..8312666c 100644 --- a/packages/netlify-cms-core/src/redux/middleware/waitUntilAction.ts +++ b/packages/netlify-cms-core/src/store/middleware/waitUntilAction.ts @@ -7,14 +7,13 @@ * action coming through the system. Think of it as a thunk that * blocks until the condition is met. */ -import type { Middleware, MiddlewareAPI, Dispatch, AnyAction } from 'redux'; -import type { State } from '../../types/redux'; +import type { AnyAction, Dispatch, Middleware, MiddlewareAPI } from '@reduxjs/toolkit'; export const WAIT_UNTIL_ACTION = 'WAIT_UNTIL_ACTION'; export interface WaitActionArgs { predicate: (action: AnyAction) => boolean; - run: (dispatch: Dispatch, getState: () => State, action: AnyAction) => void; + run: (dispatch: Dispatch, getState: () => any, action: AnyAction) => void; } interface WaitAction extends WaitActionArgs { @@ -22,10 +21,10 @@ interface WaitAction extends WaitActionArgs { } // eslint-disable-next-line func-style -export const waitUntilAction: Middleware<{}, State, Dispatch> = ({ +export const waitUntilAction: Middleware<{}, any, Dispatch> = ({ dispatch, getState, -}: MiddlewareAPI) => { +}: MiddlewareAPI) => { let pending: WaitAction[] = []; function checkPending(action: AnyAction): void { diff --git a/packages/netlify-cms-core/src/store/slices/snackbars.ts b/packages/netlify-cms-core/src/store/slices/snackbars.ts new file mode 100644 index 00000000..a197fc1f --- /dev/null +++ b/packages/netlify-cms-core/src/store/slices/snackbars.ts @@ -0,0 +1,52 @@ +import { createSlice } from '@reduxjs/toolkit'; +import { v4 as uuid } from 'uuid'; + +import type { PayloadAction } from '@reduxjs/toolkit'; +import type { RootState } from '..'; + +type MessageType = 'error' | 'warning' | 'info' | 'success'; + +export interface SnackbarMessage { + id: string; + type: MessageType; + message: { + key: string, + } & Record; +} + +// Define a type for the slice state +export interface SnackbarState { + messages: SnackbarMessage[]; +} + +// Define the initial state using that type +const initialState: SnackbarState = { + messages: [], +}; + +export const SnackbarSlice = createSlice({ + name: 'snackbar', + // `createSlice` will infer the state type from the `initialState` argument + initialState, + reducers: { + addSnackbar: (state, action: PayloadAction>) => { + const messages = [...state.messages]; + messages.push({ + id: uuid(), + ...action.payload, + }); + return { ...state, messages }; + }, + removeSnackbarById: (state, action: PayloadAction) => { + const messages = [...state.messages]; + const filteredMessages = messages.filter(message => message.id !== action.payload); + return { ...state, messages: filteredMessages }; + }, + }, +}); + +export const { addSnackbar, removeSnackbarById } = SnackbarSlice.actions; + +export const selectSnackbars = (state: RootState) => state.snackbar.messages; + +export default SnackbarSlice.reducer; diff --git a/packages/netlify-cms-core/src/types/global.d.ts b/packages/netlify-cms-core/src/types/global.d.ts index b06e3f55..ad2e4c4c 100644 --- a/packages/netlify-cms-core/src/types/global.d.ts +++ b/packages/netlify-cms-core/src/types/global.d.ts @@ -1,6 +1,6 @@ -import type { CmsConfig } from './redux'; - declare global { + import type { CmsConfig } from './interface'; + interface Window { CMS_CONFIG?: CmsConfig; CMS_ENV?: string; diff --git a/packages/netlify-cms-core/src/types/immutable.ts b/packages/netlify-cms-core/src/types/immutable.ts index 0afa58cd..0c482193 100644 --- a/packages/netlify-cms-core/src/types/immutable.ts +++ b/packages/netlify-cms-core/src/types/immutable.ts @@ -36,4 +36,5 @@ export interface StaticallyTypedRecord { ): StaticallyTypedRecord<{ [key: string]: V }>; keySeq(): { toArray: () => K[] }; withMutations(mutator: (mutable: StaticallyTypedRecord) => unknown): StaticallyTypedRecord; + first(): any; } diff --git a/packages/netlify-cms-core/src/types/redux-notifications.d.ts b/packages/netlify-cms-core/src/types/redux-notifications.d.ts deleted file mode 100644 index d7c532c9..00000000 --- a/packages/netlify-cms-core/src/types/redux-notifications.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare module 'redux-notifications'; diff --git a/packages/netlify-cms-core/src/types/redux.ts b/packages/netlify-cms-core/src/types/redux.ts index f0069f4d..b3f7815a 100644 --- a/packages/netlify-cms-core/src/types/redux.ts +++ b/packages/netlify-cms-core/src/types/redux.ts @@ -1,8 +1,8 @@ import type { List, Map, OrderedMap, Set } from 'immutable'; import type { Action } from 'redux'; import type { MediaFile as BackendMediaFile } from '../backend'; -import type { FILES, FOLDER } from '../constants/collectionTypes'; import type { formatExtensions } from '../formats/formats'; +import type { CmsConfig, CmsSortableFields, SortDirection, ViewFilter, ViewGroup } from '../interface'; import type { Auth } from '../reducers/auth'; import type { Deploys } from '../reducers/deploys'; import type { GlobalUI } from '../reducers/globalUI'; @@ -10,6 +10,7 @@ import type { Medias } from '../reducers/medias'; import type { ScrollState } from '../reducers/scroll'; import type { Search } from '../reducers/search'; import type { Status } from '../reducers/status'; +import type { SnackbarState } from '../store/slices/snackbars'; import type { StaticallyTypedRecord } from './immutable'; export type CmsBackendType = @@ -291,69 +292,6 @@ export interface CmsCollectionFile { public_folder?: string; } -export interface ViewFilter { - label: string; - field: string; - pattern: string; - id: string; -} - -export interface ViewGroup { - label: string; - field: string; - pattern: string; - id: string; -} - -export interface CmsCollection { - name: string; - label: string; - label_singular?: string; - description?: string; - folder?: string; - files?: CmsCollectionFile[]; - identifier_field?: string; - summary?: string; - slug?: string; - preview_path?: string; - preview_path_date_field?: string; - create?: boolean; - delete?: boolean; - editor?: { - preview?: boolean; - }; - publish?: boolean; - nested?: { - depth: number; - }; - type: typeof FOLDER | typeof FILES; - meta?: { path?: { label: string; widget: string; index_file: string } }; - - /** - * It accepts the following values: yml, yaml, toml, json, md, markdown, html - * - * You may also specify a custom extension not included in the list above, by specifying the format value. - */ - extension?: string; - format?: CmsCollectionFormatType; - - frontmatter_delimiter?: string[] | string; - fields?: CmsField[]; - filter?: { field: string; value: unknown }; - path?: string; - media_folder?: string; - public_folder?: string; - sortable_fields?: string[]; - view_filters?: ViewFilter[]; - view_groups?: ViewGroup[]; - i18n?: boolean | CmsI18nConfig; - - /** - * @deprecated Use sortable_fields instead - */ - sortableFields?: string[]; -} - export interface CmsBackend { name: CmsBackendType; auth_scope?: CmsAuthScope; @@ -388,38 +326,6 @@ export interface CmsLocalBackend { allowed_hosts?: string[]; } -export interface CmsConfig { - backend: CmsBackend; - collections: CmsCollection[]; - locale?: string; - site_url?: string; - display_url?: string; - logo_url?: string; - show_preview_links?: boolean; - media_folder?: string; - public_folder?: string; - media_folder_relative?: boolean; - media_library?: CmsMediaLibrary; - publish_mode?: CmsPublishMode; - load_config_file?: boolean; - integrations?: { - hooks: string[]; - provider: string; - collections?: '*' | string[]; - applicationID?: string; - apiKey?: string; - getSignedFormURL?: string; - }[]; - slug?: CmsSlug; - i18n?: CmsI18nConfig; - local_backend?: boolean | CmsLocalBackend; - editor?: { - preview?: boolean; - }; - error: string | undefined; - isFetching: boolean; -} - export type CmsMediaLibraryOptions = unknown; // TODO: type properly export interface CmsMediaLibrary { @@ -477,12 +383,6 @@ type Pages = StaticallyTypedRecord; type EntitiesObject = { [key: string]: EntryMap }; -export enum SortDirection { - Ascending = 'Ascending', - Descending = 'Descending', - None = 'None', -} - export type SortObject = { key: string; direction: SortDirection }; export type SortMap = OrderedMap>; @@ -625,7 +525,7 @@ type CollectionObject = { slug?: string; label_singular?: string; label: string; - sortable_fields: List; + sortable_fields: StaticallyTypedRecord; view_filters: List>; view_groups: List>; nested?: Nested; @@ -699,9 +599,9 @@ export interface State { medias: Medias; mediaLibrary: MediaLibrary; search: Search; - notifs: { message: { key: string }; kind: string; id: number }[]; status: Status; scroll: ScrollState; + snackbar: SnackbarState; } export interface Integration { diff --git a/packages/netlify-cms-ui-default/src/AuthenticationPage.js b/packages/netlify-cms-core/src/ui/AuthenticationPage.js similarity index 100% rename from packages/netlify-cms-ui-default/src/AuthenticationPage.js rename to packages/netlify-cms-core/src/ui/AuthenticationPage.js diff --git a/packages/netlify-cms-ui-default/src/Dropdown.js b/packages/netlify-cms-core/src/ui/Dropdown.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Dropdown.js rename to packages/netlify-cms-core/src/ui/Dropdown.js diff --git a/packages/netlify-cms-ui-default/src/FieldLabel.js b/packages/netlify-cms-core/src/ui/FieldLabel.js similarity index 100% rename from packages/netlify-cms-ui-default/src/FieldLabel.js rename to packages/netlify-cms-core/src/ui/FieldLabel.js diff --git a/packages/netlify-cms-ui-default/src/GoBackButton.js b/packages/netlify-cms-core/src/ui/GoBackButton.js similarity index 100% rename from packages/netlify-cms-ui-default/src/GoBackButton.js rename to packages/netlify-cms-core/src/ui/GoBackButton.js diff --git a/packages/netlify-cms-ui-default/src/Icon.js b/packages/netlify-cms-core/src/ui/Icon.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon.js rename to packages/netlify-cms-core/src/ui/Icon.js diff --git a/packages/netlify-cms-ui-default/src/Icon/icons.js b/packages/netlify-cms-core/src/ui/Icon/icons.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/icons.js rename to packages/netlify-cms-core/src/ui/Icon/icons.js diff --git a/packages/netlify-cms-ui-default/src/Icon/images/_index.js b/packages/netlify-cms-core/src/ui/Icon/images/_index.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/_index.js rename to packages/netlify-cms-core/src/ui/Icon/images/_index.js diff --git a/packages/netlify-cms-ui-default/src/Icon/images/add-with.svg b/packages/netlify-cms-core/src/ui/Icon/images/add-with.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/add-with.svg rename to packages/netlify-cms-core/src/ui/Icon/images/add-with.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/add.svg b/packages/netlify-cms-core/src/ui/Icon/images/add.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/add.svg rename to packages/netlify-cms-core/src/ui/Icon/images/add.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/arrow.svg b/packages/netlify-cms-core/src/ui/Icon/images/arrow.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/arrow.svg rename to packages/netlify-cms-core/src/ui/Icon/images/arrow.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/azure.svg b/packages/netlify-cms-core/src/ui/Icon/images/azure.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/azure.svg rename to packages/netlify-cms-core/src/ui/Icon/images/azure.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/bitbucket.svg b/packages/netlify-cms-core/src/ui/Icon/images/bitbucket.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/bitbucket.svg rename to packages/netlify-cms-core/src/ui/Icon/images/bitbucket.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/bold.svg b/packages/netlify-cms-core/src/ui/Icon/images/bold.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/bold.svg rename to packages/netlify-cms-core/src/ui/Icon/images/bold.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/check.svg b/packages/netlify-cms-core/src/ui/Icon/images/check.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/check.svg rename to packages/netlify-cms-core/src/ui/Icon/images/check.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/chevron-double.svg b/packages/netlify-cms-core/src/ui/Icon/images/chevron-double.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/chevron-double.svg rename to packages/netlify-cms-core/src/ui/Icon/images/chevron-double.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/chevron.svg b/packages/netlify-cms-core/src/ui/Icon/images/chevron.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/chevron.svg rename to packages/netlify-cms-core/src/ui/Icon/images/chevron.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/circle.svg b/packages/netlify-cms-core/src/ui/Icon/images/circle.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/circle.svg rename to packages/netlify-cms-core/src/ui/Icon/images/circle.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/close.svg b/packages/netlify-cms-core/src/ui/Icon/images/close.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/close.svg rename to packages/netlify-cms-core/src/ui/Icon/images/close.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/code-block.svg b/packages/netlify-cms-core/src/ui/Icon/images/code-block.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/code-block.svg rename to packages/netlify-cms-core/src/ui/Icon/images/code-block.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/code.svg b/packages/netlify-cms-core/src/ui/Icon/images/code.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/code.svg rename to packages/netlify-cms-core/src/ui/Icon/images/code.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/drag-handle.svg b/packages/netlify-cms-core/src/ui/Icon/images/drag-handle.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/drag-handle.svg rename to packages/netlify-cms-core/src/ui/Icon/images/drag-handle.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/eye.svg b/packages/netlify-cms-core/src/ui/Icon/images/eye.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/eye.svg rename to packages/netlify-cms-core/src/ui/Icon/images/eye.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/folder.svg b/packages/netlify-cms-core/src/ui/Icon/images/folder.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/folder.svg rename to packages/netlify-cms-core/src/ui/Icon/images/folder.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/github.svg b/packages/netlify-cms-core/src/ui/Icon/images/github.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/github.svg rename to packages/netlify-cms-core/src/ui/Icon/images/github.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/gitlab.svg b/packages/netlify-cms-core/src/ui/Icon/images/gitlab.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/gitlab.svg rename to packages/netlify-cms-core/src/ui/Icon/images/gitlab.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/grid.svg b/packages/netlify-cms-core/src/ui/Icon/images/grid.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/grid.svg rename to packages/netlify-cms-core/src/ui/Icon/images/grid.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/h-options.svg b/packages/netlify-cms-core/src/ui/Icon/images/h-options.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/h-options.svg rename to packages/netlify-cms-core/src/ui/Icon/images/h-options.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/h1.svg b/packages/netlify-cms-core/src/ui/Icon/images/h1.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/h1.svg rename to packages/netlify-cms-core/src/ui/Icon/images/h1.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/h2.svg b/packages/netlify-cms-core/src/ui/Icon/images/h2.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/h2.svg rename to packages/netlify-cms-core/src/ui/Icon/images/h2.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/home.svg b/packages/netlify-cms-core/src/ui/Icon/images/home.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/home.svg rename to packages/netlify-cms-core/src/ui/Icon/images/home.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/image.svg b/packages/netlify-cms-core/src/ui/Icon/images/image.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/image.svg rename to packages/netlify-cms-core/src/ui/Icon/images/image.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/info-circle.svg b/packages/netlify-cms-core/src/ui/Icon/images/info-circle.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/info-circle.svg rename to packages/netlify-cms-core/src/ui/Icon/images/info-circle.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/italic.svg b/packages/netlify-cms-core/src/ui/Icon/images/italic.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/italic.svg rename to packages/netlify-cms-core/src/ui/Icon/images/italic.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/link.svg b/packages/netlify-cms-core/src/ui/Icon/images/link.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/link.svg rename to packages/netlify-cms-core/src/ui/Icon/images/link.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/list-bulleted.svg b/packages/netlify-cms-core/src/ui/Icon/images/list-bulleted.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/list-bulleted.svg rename to packages/netlify-cms-core/src/ui/Icon/images/list-bulleted.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/list-numbered.svg b/packages/netlify-cms-core/src/ui/Icon/images/list-numbered.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/list-numbered.svg rename to packages/netlify-cms-core/src/ui/Icon/images/list-numbered.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/list.svg b/packages/netlify-cms-core/src/ui/Icon/images/list.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/list.svg rename to packages/netlify-cms-core/src/ui/Icon/images/list.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/markdown.svg b/packages/netlify-cms-core/src/ui/Icon/images/markdown.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/markdown.svg rename to packages/netlify-cms-core/src/ui/Icon/images/markdown.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/media-alt.svg b/packages/netlify-cms-core/src/ui/Icon/images/media-alt.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/media-alt.svg rename to packages/netlify-cms-core/src/ui/Icon/images/media-alt.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/media.svg b/packages/netlify-cms-core/src/ui/Icon/images/media.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/media.svg rename to packages/netlify-cms-core/src/ui/Icon/images/media.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/netlify-cms-logo.svg b/packages/netlify-cms-core/src/ui/Icon/images/netlify-cms-logo.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/netlify-cms-logo.svg rename to packages/netlify-cms-core/src/ui/Icon/images/netlify-cms-logo.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/netlify.svg b/packages/netlify-cms-core/src/ui/Icon/images/netlify.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/netlify.svg rename to packages/netlify-cms-core/src/ui/Icon/images/netlify.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/new-tab.svg b/packages/netlify-cms-core/src/ui/Icon/images/new-tab.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/new-tab.svg rename to packages/netlify-cms-core/src/ui/Icon/images/new-tab.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/page.svg b/packages/netlify-cms-core/src/ui/Icon/images/page.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/page.svg rename to packages/netlify-cms-core/src/ui/Icon/images/page.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/pages-alt.svg b/packages/netlify-cms-core/src/ui/Icon/images/pages-alt.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/pages-alt.svg rename to packages/netlify-cms-core/src/ui/Icon/images/pages-alt.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/pages.svg b/packages/netlify-cms-core/src/ui/Icon/images/pages.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/pages.svg rename to packages/netlify-cms-core/src/ui/Icon/images/pages.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/quote.svg b/packages/netlify-cms-core/src/ui/Icon/images/quote.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/quote.svg rename to packages/netlify-cms-core/src/ui/Icon/images/quote.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/refresh.svg b/packages/netlify-cms-core/src/ui/Icon/images/refresh.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/refresh.svg rename to packages/netlify-cms-core/src/ui/Icon/images/refresh.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/scroll.svg b/packages/netlify-cms-core/src/ui/Icon/images/scroll.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/scroll.svg rename to packages/netlify-cms-core/src/ui/Icon/images/scroll.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/search.svg b/packages/netlify-cms-core/src/ui/Icon/images/search.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/search.svg rename to packages/netlify-cms-core/src/ui/Icon/images/search.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/settings.svg b/packages/netlify-cms-core/src/ui/Icon/images/settings.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/settings.svg rename to packages/netlify-cms-core/src/ui/Icon/images/settings.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/user.svg b/packages/netlify-cms-core/src/ui/Icon/images/user.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/user.svg rename to packages/netlify-cms-core/src/ui/Icon/images/user.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/workflow.svg b/packages/netlify-cms-core/src/ui/Icon/images/workflow.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/workflow.svg rename to packages/netlify-cms-core/src/ui/Icon/images/workflow.svg diff --git a/packages/netlify-cms-ui-default/src/Icon/images/write.svg b/packages/netlify-cms-core/src/ui/Icon/images/write.svg similarity index 100% rename from packages/netlify-cms-ui-default/src/Icon/images/write.svg rename to packages/netlify-cms-core/src/ui/Icon/images/write.svg diff --git a/packages/netlify-cms-ui-default/src/IconButton.js b/packages/netlify-cms-core/src/ui/IconButton.js similarity index 100% rename from packages/netlify-cms-ui-default/src/IconButton.js rename to packages/netlify-cms-core/src/ui/IconButton.js diff --git a/packages/netlify-cms-ui-default/src/ListItemTopBar.js b/packages/netlify-cms-core/src/ui/ListItemTopBar.js similarity index 98% rename from packages/netlify-cms-ui-default/src/ListItemTopBar.js rename to packages/netlify-cms-core/src/ui/ListItemTopBar.js index 82658580..a80fa291 100644 --- a/packages/netlify-cms-ui-default/src/ListItemTopBar.js +++ b/packages/netlify-cms-core/src/ui/ListItemTopBar.js @@ -1,8 +1,8 @@ import styled from '@emotion/styled'; import PropTypes from 'prop-types'; import React from 'react'; -import { transientOptions } from 'netlify-cms-lib-util'; +import { transientOptions } from '../lib/util'; import Icon from './Icon'; import { buttons, colors, lengths } from './styles'; diff --git a/packages/netlify-cms-ui-default/src/Loader.js b/packages/netlify-cms-core/src/ui/Loader.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Loader.js rename to packages/netlify-cms-core/src/ui/Loader.js diff --git a/packages/netlify-cms-ui-default/src/ObjectWidgetTopBar.js b/packages/netlify-cms-core/src/ui/ObjectWidgetTopBar.js similarity index 100% rename from packages/netlify-cms-ui-default/src/ObjectWidgetTopBar.js rename to packages/netlify-cms-core/src/ui/ObjectWidgetTopBar.js diff --git a/packages/netlify-cms-ui-default/src/Toggle.js b/packages/netlify-cms-core/src/ui/Toggle.js similarity index 100% rename from packages/netlify-cms-ui-default/src/Toggle.js rename to packages/netlify-cms-core/src/ui/Toggle.js diff --git a/packages/netlify-cms-ui-default/src/WidgetPreviewContainer.js b/packages/netlify-cms-core/src/ui/WidgetPreviewContainer.js similarity index 100% rename from packages/netlify-cms-ui-default/src/WidgetPreviewContainer.js rename to packages/netlify-cms-core/src/ui/WidgetPreviewContainer.js diff --git a/packages/netlify-cms-ui-default/src/index.js b/packages/netlify-cms-core/src/ui/index.js similarity index 100% rename from packages/netlify-cms-ui-default/src/index.js rename to packages/netlify-cms-core/src/ui/index.js diff --git a/packages/netlify-cms-ui-default/src/styles.js b/packages/netlify-cms-core/src/ui/styles.js similarity index 99% rename from packages/netlify-cms-ui-default/src/styles.js rename to packages/netlify-cms-core/src/ui/styles.js index 450c54bb..71140558 100644 --- a/packages/netlify-cms-ui-default/src/styles.js +++ b/packages/netlify-cms-core/src/ui/styles.js @@ -485,8 +485,8 @@ const zIndex = { zIndex299: 299, zIndex300: 300, zIndex1000: 1000, - zIndex10000: 10000, - zIndex99999: 99999, + zIndex1001: 1001, + zIndex1002: 1002, }; function GlobalStyles() { diff --git a/packages/netlify-cms-widget-boolean/src/BooleanControl.js b/packages/netlify-cms-core/src/widgets/boolean/BooleanControl.js similarity index 94% rename from packages/netlify-cms-widget-boolean/src/BooleanControl.js rename to packages/netlify-cms-core/src/widgets/boolean/BooleanControl.js index da40f279..cb4482bd 100644 --- a/packages/netlify-cms-widget-boolean/src/BooleanControl.js +++ b/packages/netlify-cms-core/src/widgets/boolean/BooleanControl.js @@ -2,7 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { css } from '@emotion/react'; -import { Toggle, ToggleBackground, colors } from 'netlify-cms-ui-default'; + +import { Toggle, ToggleBackground, colors } from '../../ui'; function BooleanBackground({ isActive, ...props }) { return ( diff --git a/packages/netlify-cms-widget-boolean/src/index.js b/packages/netlify-cms-core/src/widgets/boolean/index.js similarity index 100% rename from packages/netlify-cms-widget-boolean/src/index.js rename to packages/netlify-cms-core/src/widgets/boolean/index.js diff --git a/packages/netlify-cms-widget-code/src/CodeControl.js b/packages/netlify-cms-core/src/widgets/code/CodeControl.js similarity index 99% rename from packages/netlify-cms-widget-code/src/CodeControl.js rename to packages/netlify-cms-core/src/widgets/code/CodeControl.js index 056fb0cb..e490ee61 100644 --- a/packages/netlify-cms-widget-code/src/CodeControl.js +++ b/packages/netlify-cms-core/src/widgets/code/CodeControl.js @@ -15,7 +15,7 @@ import materialTheme from 'codemirror/theme/material.css'; import SettingsPane from './SettingsPane'; import SettingsButton from './SettingsButton'; -import languageData from '../data/languages.json'; +import languageData from './data/languages.json'; // TODO: relocate as a utility function function getChangedProps(previous, next, keys) { diff --git a/packages/netlify-cms-widget-code/src/CodePreview.js b/packages/netlify-cms-core/src/widgets/code/CodePreview.js similarity index 90% rename from packages/netlify-cms-widget-code/src/CodePreview.js rename to packages/netlify-cms-core/src/widgets/code/CodePreview.js index 46da0983..77eabf80 100644 --- a/packages/netlify-cms-widget-code/src/CodePreview.js +++ b/packages/netlify-cms-core/src/widgets/code/CodePreview.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import { Map } from 'immutable'; import { isString } from 'lodash'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function toValue(value, field) { if (isString(value)) { diff --git a/packages/netlify-cms-widget-code/src/SettingsButton.js b/packages/netlify-cms-core/src/widgets/code/SettingsButton.js similarity index 89% rename from packages/netlify-cms-widget-code/src/SettingsButton.js rename to packages/netlify-cms-core/src/widgets/code/SettingsButton.js index a7a42db6..4f338a78 100644 --- a/packages/netlify-cms-widget-code/src/SettingsButton.js +++ b/packages/netlify-cms-core/src/widgets/code/SettingsButton.js @@ -1,6 +1,7 @@ import React from 'react'; import styled from '@emotion/styled'; -import { Icon, buttons, shadows, zIndex } from 'netlify-cms-ui-default'; + +import { Icon, buttons, shadows, zIndex } from '../../ui'; const StyledSettingsButton = styled.button` ${buttons.button}; diff --git a/packages/netlify-cms-widget-code/src/SettingsPane.js b/packages/netlify-cms-core/src/widgets/code/SettingsPane.js similarity index 97% rename from packages/netlify-cms-widget-code/src/SettingsPane.js rename to packages/netlify-cms-core/src/widgets/code/SettingsPane.js index c683afd9..e60a1f7d 100644 --- a/packages/netlify-cms-widget-code/src/SettingsPane.js +++ b/packages/netlify-cms-core/src/widgets/code/SettingsPane.js @@ -2,8 +2,8 @@ import React from 'react'; import styled from '@emotion/styled'; import Select from 'react-select'; import isHotkey from 'is-hotkey'; -import { text, shadows, zIndex } from 'netlify-cms-ui-default'; +import { text, shadows, zIndex } from '../../ui'; import SettingsButton from './SettingsButton'; import languageSelectStyles from './languageSelectStyles'; diff --git a/packages/netlify-cms-widget-code/data/languages-raw.yml b/packages/netlify-cms-core/src/widgets/code/data/languages-raw.yml similarity index 100% rename from packages/netlify-cms-widget-code/data/languages-raw.yml rename to packages/netlify-cms-core/src/widgets/code/data/languages-raw.yml diff --git a/packages/netlify-cms-widget-code/data/languages.json b/packages/netlify-cms-core/src/widgets/code/data/languages.json similarity index 100% rename from packages/netlify-cms-widget-code/data/languages.json rename to packages/netlify-cms-core/src/widgets/code/data/languages.json diff --git a/packages/netlify-cms-widget-code/src/index.js b/packages/netlify-cms-core/src/widgets/code/index.js similarity index 100% rename from packages/netlify-cms-widget-code/src/index.js rename to packages/netlify-cms-core/src/widgets/code/index.js diff --git a/packages/netlify-cms-widget-code/src/languageSelectStyles.js b/packages/netlify-cms-core/src/widgets/code/languageSelectStyles.js similarity index 91% rename from packages/netlify-cms-widget-code/src/languageSelectStyles.js rename to packages/netlify-cms-core/src/widgets/code/languageSelectStyles.js index 68680bf5..ae3ef3a0 100644 --- a/packages/netlify-cms-widget-code/src/languageSelectStyles.js +++ b/packages/netlify-cms-core/src/widgets/code/languageSelectStyles.js @@ -1,4 +1,4 @@ -import { reactSelectStyles, borders } from 'netlify-cms-ui-default'; +import { reactSelectStyles, borders } from '../../ui'; const languageSelectStyles = { ...reactSelectStyles, diff --git a/packages/netlify-cms-widget-code/src/schema.js b/packages/netlify-cms-core/src/widgets/code/schema.js similarity index 100% rename from packages/netlify-cms-widget-code/src/schema.js rename to packages/netlify-cms-core/src/widgets/code/schema.js diff --git a/packages/netlify-cms-widget-code/scripts/process-languages.js b/packages/netlify-cms-core/src/widgets/code/scripts/process-languages.js similarity index 100% rename from packages/netlify-cms-widget-code/scripts/process-languages.js rename to packages/netlify-cms-core/src/widgets/code/scripts/process-languages.js diff --git a/packages/netlify-cms-widget-colorstring/src/ColorControl.js b/packages/netlify-cms-core/src/widgets/colorstring/ColorControl.js similarity index 99% rename from packages/netlify-cms-widget-colorstring/src/ColorControl.js rename to packages/netlify-cms-core/src/widgets/colorstring/ColorControl.js index 78ed2bf9..d18f24c9 100644 --- a/packages/netlify-cms-widget-colorstring/src/ColorControl.js +++ b/packages/netlify-cms-core/src/widgets/colorstring/ColorControl.js @@ -3,7 +3,8 @@ import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import ChromePicker from 'react-color'; import validateColor from 'validate-color'; -import { zIndex } from 'netlify-cms-ui-default'; + +import { zIndex } from '../../ui'; function ClearIcon() { return ( diff --git a/packages/netlify-cms-widget-colorstring/src/ColorPreview.js b/packages/netlify-cms-core/src/widgets/colorstring/ColorPreview.js similarity index 79% rename from packages/netlify-cms-widget-colorstring/src/ColorPreview.js rename to packages/netlify-cms-core/src/widgets/colorstring/ColorPreview.js index 8ced4f59..2df3e474 100644 --- a/packages/netlify-cms-widget-colorstring/src/ColorPreview.js +++ b/packages/netlify-cms-core/src/widgets/colorstring/ColorPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function ColorPreview({ value }) { return {value}; diff --git a/packages/netlify-cms-widget-colorstring/src/index.js b/packages/netlify-cms-core/src/widgets/colorstring/index.js similarity index 100% rename from packages/netlify-cms-widget-colorstring/src/index.js rename to packages/netlify-cms-core/src/widgets/colorstring/index.js diff --git a/packages/netlify-cms-widget-datetime/src/DateTimeControl.js b/packages/netlify-cms-core/src/widgets/datetime/DateTimeControl.js similarity index 93% rename from packages/netlify-cms-widget-datetime/src/DateTimeControl.js rename to packages/netlify-cms-core/src/widgets/datetime/DateTimeControl.js index 6bb57bfe..4709251d 100644 --- a/packages/netlify-cms-widget-datetime/src/DateTimeControl.js +++ b/packages/netlify-cms-core/src/widgets/datetime/DateTimeControl.js @@ -1,11 +1,13 @@ /** @jsx jsx */ -import React from 'react'; -import PropTypes from 'prop-types'; -import { jsx, css } from '@emotion/react'; -import reactDateTimeStyles from 'react-datetime/css/react-datetime.css'; -import DateTime from 'react-datetime'; +import { css, jsx } from '@emotion/react'; import moment from 'moment'; -import { buttons } from 'netlify-cms-ui-default'; +import PropTypes from 'prop-types'; +import React from 'react'; +import DateTime from 'react-datetime'; +import reactDateTimeStyles from 'react-datetime/css/react-datetime.css'; + +import alert from '../../components/UI/Alert'; +import { buttons } from '../../ui'; function NowButton({ t, handleChange }) { return ( @@ -132,7 +134,10 @@ export default class DateTimeControl extends React.Component { if (parsedDate.isValid()) { this.handleChange(datetime); } else { - window.alert('The date you entered is invalid.'); + alert({ + title: 'editor.editorWidgets.datetime.invalidDateTitle', + body: 'editor.editorWidgets.datetime.invalidDateBody', + }); } } diff --git a/packages/netlify-cms-widget-datetime/src/DateTimePreview.js b/packages/netlify-cms-core/src/widgets/datetime/DateTimePreview.js similarity index 83% rename from packages/netlify-cms-widget-datetime/src/DateTimePreview.js rename to packages/netlify-cms-core/src/widgets/datetime/DateTimePreview.js index 6c97679f..9d51dc97 100644 --- a/packages/netlify-cms-widget-datetime/src/DateTimePreview.js +++ b/packages/netlify-cms-core/src/widgets/datetime/DateTimePreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function DatePreview({ value }) { return {value ? value.toString() : null}; diff --git a/packages/netlify-cms-widget-datetime/src/index.js b/packages/netlify-cms-core/src/widgets/datetime/index.js similarity index 100% rename from packages/netlify-cms-widget-datetime/src/index.js rename to packages/netlify-cms-core/src/widgets/datetime/index.js diff --git a/packages/netlify-cms-widget-datetime/src/schema.js b/packages/netlify-cms-core/src/widgets/datetime/schema.js similarity index 100% rename from packages/netlify-cms-widget-datetime/src/schema.js rename to packages/netlify-cms-core/src/widgets/datetime/schema.js diff --git a/packages/netlify-cms-widget-file/src/FilePreview.js b/packages/netlify-cms-core/src/widgets/file/FilePreview.js similarity index 94% rename from packages/netlify-cms-widget-file/src/FilePreview.js rename to packages/netlify-cms-core/src/widgets/file/FilePreview.js index fbf2e492..c79ac106 100644 --- a/packages/netlify-cms-widget-file/src/FilePreview.js +++ b/packages/netlify-cms-core/src/widgets/file/FilePreview.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import { List } from 'immutable'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; const FileLink = styled(({ href, path }) => ( diff --git a/packages/netlify-cms-widget-file/src/index.js b/packages/netlify-cms-core/src/widgets/file/index.js similarity index 100% rename from packages/netlify-cms-widget-file/src/index.js rename to packages/netlify-cms-core/src/widgets/file/index.js diff --git a/packages/netlify-cms-widget-file/src/schema.js b/packages/netlify-cms-core/src/widgets/file/schema.js similarity index 100% rename from packages/netlify-cms-widget-file/src/schema.js rename to packages/netlify-cms-core/src/widgets/file/schema.js diff --git a/packages/netlify-cms-widget-file/src/withFileControl.js b/packages/netlify-cms-core/src/widgets/file/withFileControl.js similarity index 99% rename from packages/netlify-cms-widget-file/src/withFileControl.js rename to packages/netlify-cms-core/src/widgets/file/withFileControl.js index 00a9a3b1..7782b68c 100644 --- a/packages/netlify-cms-widget-file/src/withFileControl.js +++ b/packages/netlify-cms-core/src/widgets/file/withFileControl.js @@ -7,6 +7,9 @@ import { Map, List } from 'immutable'; import { once } from 'lodash'; import uuid from 'uuid/v4'; import { oneLine } from 'common-tags'; +import { SortableContainer, SortableElement } from 'react-sortable-hoc'; +import { arrayMoveImmutable as arrayMove } from 'array-move'; + import { lengths, components, @@ -15,10 +18,8 @@ import { effects, shadows, IconButton, -} from 'netlify-cms-ui-default'; -import { basename } from 'netlify-cms-lib-util'; -import { SortableContainer, SortableElement } from 'react-sortable-hoc'; -import { arrayMoveImmutable as arrayMove } from 'array-move'; +} from '../../ui'; +import { basename } from '../../lib/util'; const MAX_DISPLAY_LENGTH = 50; diff --git a/packages/netlify-cms-widget-image/src/ImagePreview.js b/packages/netlify-cms-core/src/widgets/image/ImagePreview.js similarity index 93% rename from packages/netlify-cms-widget-image/src/ImagePreview.js rename to packages/netlify-cms-core/src/widgets/image/ImagePreview.js index 5bef284c..9e8e7965 100644 --- a/packages/netlify-cms-widget-image/src/ImagePreview.js +++ b/packages/netlify-cms-core/src/widgets/image/ImagePreview.js @@ -2,7 +2,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; import { List } from 'immutable'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; const StyledImage = styled(({ src }) => )` display: block; diff --git a/packages/netlify-cms-widget-image/src/index.js b/packages/netlify-cms-core/src/widgets/image/index.js similarity index 87% rename from packages/netlify-cms-widget-image/src/index.js rename to packages/netlify-cms-core/src/widgets/image/index.js index 2c34c221..559009bc 100644 --- a/packages/netlify-cms-widget-image/src/index.js +++ b/packages/netlify-cms-core/src/widgets/image/index.js @@ -1,5 +1,4 @@ -import NetlifyCmsWidgetFile from 'netlify-cms-widget-file'; - +import NetlifyCmsWidgetFile from '../file'; import previewComponent from './ImagePreview'; import schema from './schema'; diff --git a/packages/netlify-cms-widget-image/src/schema.js b/packages/netlify-cms-core/src/widgets/image/schema.js similarity index 100% rename from packages/netlify-cms-widget-image/src/schema.js rename to packages/netlify-cms-core/src/widgets/image/schema.js diff --git a/packages/netlify-cms-core/src/widgets/index.tsx b/packages/netlify-cms-core/src/widgets/index.tsx new file mode 100644 index 00000000..0eb79659 --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/index.tsx @@ -0,0 +1,33 @@ +import BooleanWidget from './boolean'; +import CodeWidget from './code'; +import ColorStringWidget from './colorstring'; +import DateTimeWidget from './datetime'; +import FileWidget from './file'; +import ImageWidget from './image'; +import ListWidget from './list'; +import MapWidget from './map'; +import MarkdownWidget from './markdown'; +import NumberWidget from './number'; +import ObjectWidget from './object'; +import RelationWidget from './relation'; +import SelectWidget from './select'; +import StringWidget from './string'; +import TextWidget from './text'; + +export { + BooleanWidget, + CodeWidget, + ColorStringWidget, + DateTimeWidget, + FileWidget, + ImageWidget, + ListWidget, + MapWidget, + MarkdownWidget, + NumberWidget, + ObjectWidget, + RelationWidget, + SelectWidget, + StringWidget, + TextWidget, +}; diff --git a/packages/netlify-cms-widget-list/src/ListControl.js b/packages/netlify-cms-core/src/widgets/list/ListControl.js similarity index 99% rename from packages/netlify-cms-widget-list/src/ListControl.js rename to packages/netlify-cms-core/src/widgets/list/ListControl.js index f5b8574b..9576bc72 100644 --- a/packages/netlify-cms-widget-list/src/ListControl.js +++ b/packages/netlify-cms-core/src/widgets/list/ListControl.js @@ -7,16 +7,16 @@ import { List, Map, fromJS } from 'immutable'; import { partial, isEmpty, uniqueId } from 'lodash'; import uuid from 'uuid/v4'; import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'; -import NetlifyCmsWidgetObject from 'netlify-cms-widget-object'; + import { ListItemTopBar, ObjectWidgetTopBar, colors, lengths, FieldLabel, -} from 'netlify-cms-ui-default'; -import { stringTemplate, validations } from 'netlify-cms-lib-widgets'; - +} from '../../ui'; +import { stringTemplate, validations } from '../../lib/widgets'; +import NetlifyCmsWidgetObject from '../object'; import { TYPES_KEY, getTypedFieldForValue, diff --git a/packages/netlify-cms-widget-list/src/index.js b/packages/netlify-cms-core/src/widgets/list/index.js similarity index 86% rename from packages/netlify-cms-widget-list/src/index.js rename to packages/netlify-cms-core/src/widgets/list/index.js index 57524dd7..f733e77d 100644 --- a/packages/netlify-cms-widget-list/src/index.js +++ b/packages/netlify-cms-core/src/widgets/list/index.js @@ -1,5 +1,4 @@ -import NetlifyCmsWidgetObject from 'netlify-cms-widget-object'; - +import NetlifyCmsWidgetObject from '../object'; import controlComponent from './ListControl'; import schema from './schema'; diff --git a/packages/netlify-cms-widget-list/src/schema.js b/packages/netlify-cms-core/src/widgets/list/schema.js similarity index 100% rename from packages/netlify-cms-widget-list/src/schema.js rename to packages/netlify-cms-core/src/widgets/list/schema.js diff --git a/packages/netlify-cms-widget-list/src/typedListHelpers.js b/packages/netlify-cms-core/src/widgets/list/typedListHelpers.js similarity index 100% rename from packages/netlify-cms-widget-list/src/typedListHelpers.js rename to packages/netlify-cms-core/src/widgets/list/typedListHelpers.js diff --git a/packages/netlify-cms-widget-map/src/MapPreview.js b/packages/netlify-cms-core/src/widgets/map/MapPreview.js similarity index 81% rename from packages/netlify-cms-widget-map/src/MapPreview.js rename to packages/netlify-cms-core/src/widgets/map/MapPreview.js index 31483c88..b76d34c0 100644 --- a/packages/netlify-cms-widget-map/src/MapPreview.js +++ b/packages/netlify-cms-core/src/widgets/map/MapPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function MapPreview({ value }) { return {value ? value.toString() : null}; diff --git a/packages/netlify-cms-widget-map/src/index.js b/packages/netlify-cms-core/src/widgets/map/index.js similarity index 100% rename from packages/netlify-cms-widget-map/src/index.js rename to packages/netlify-cms-core/src/widgets/map/index.js diff --git a/packages/netlify-cms-widget-map/src/schema.js b/packages/netlify-cms-core/src/widgets/map/schema.js similarity index 100% rename from packages/netlify-cms-widget-map/src/schema.js rename to packages/netlify-cms-core/src/widgets/map/schema.js diff --git a/packages/netlify-cms-widget-map/src/withMapControl.js b/packages/netlify-cms-core/src/widgets/map/withMapControl.js similarity index 100% rename from packages/netlify-cms-widget-map/src/withMapControl.js rename to packages/netlify-cms-core/src/widgets/map/withMapControl.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/RawEditor.js similarity index 98% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/RawEditor.js index cd0d616f..b7d67511 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/RawEditor.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/RawEditor.js @@ -8,8 +8,8 @@ import { Value } from 'slate'; import { Editor as Slate, setEventTransfer } from 'slate-react'; import Plain from 'slate-plain-serializer'; import isHotkey from 'is-hotkey'; -import { lengths, fonts } from 'netlify-cms-ui-default'; +import { lengths, fonts } from '../../../ui'; import { markdownToHtml } from '../serializers'; import { editorStyleVars, EditorControlBar } from '../styles'; import Toolbar from './Toolbar'; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/Toolbar.js similarity index 99% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/Toolbar.js index f1ed2d67..0a64ca0d 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/Toolbar.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/Toolbar.js @@ -4,6 +4,7 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import styled from '@emotion/styled'; import { css } from '@emotion/react'; import { List } from 'immutable'; + import { Toggle, Dropdown, @@ -12,8 +13,7 @@ import { colors, transitions, lengths, -} from 'netlify-cms-ui-default'; - +} from '../../../ui'; import ToolbarButton from './ToolbarButton'; const ToolbarContainer = styled.div` diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/ToolbarButton.js similarity index 94% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/ToolbarButton.js index 6234f927..f8cc2331 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/ToolbarButton.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/ToolbarButton.js @@ -1,7 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; import styled from '@emotion/styled'; -import { Icon, buttons } from 'netlify-cms-ui-default'; + +import { Icon, buttons } from '../../../ui'; const StyledToolbarButton = styled.button` ${buttons.button}; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/VisualEditor.js similarity index 98% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/VisualEditor.js index 94534443..2b19d84d 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/VisualEditor.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/VisualEditor.js @@ -7,11 +7,11 @@ import { css as coreCss, ClassNames } from '@emotion/react'; import { get, isEmpty, debounce } from 'lodash'; import { Value, Document, Block, Text } from 'slate'; import { Editor as Slate } from 'slate-react'; -import { lengths, fonts, zIndex } from 'netlify-cms-ui-default'; +import { lengths, fonts, zIndex } from '../../../ui'; import { editorStyleVars, EditorControlBar } from '../styles'; import { slateToMarkdown, markdownToSlate } from '../serializers'; -import Toolbar from '../MarkdownControl/Toolbar'; +import Toolbar from './Toolbar'; import { renderBlock, renderInline, renderMark } from './renderers'; import plugins from './plugins/visual'; import schema from './schema'; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/components/Shortcode.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/components/Shortcode.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/components/Shortcode.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/components/Shortcode.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/components/VoidBlock.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/components/VoidBlock.js similarity index 94% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/components/VoidBlock.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/components/VoidBlock.js index 21b613c4..e92e2c62 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/components/VoidBlock.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/components/VoidBlock.js @@ -1,7 +1,8 @@ /* eslint-disable react/prop-types */ import React from 'react'; import { css } from '@emotion/react'; -import { zIndex } from 'netlify-cms-ui-default'; + +import { zIndex } from '../../../../ui'; function InsertionPoint(props) { return ( diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/index.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/index.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/index.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/index.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/BreakToDefaultBlock.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/BreakToDefaultBlock.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/BreakToDefaultBlock.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/BreakToDefaultBlock.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CloseBlock.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CloseBlock.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CloseBlock.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CloseBlock.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CommandsAndQueries.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CommandsAndQueries.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CommandsAndQueries.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CommandsAndQueries.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CopyPasteVisual.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CopyPasteVisual.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/CopyPasteVisual.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/CopyPasteVisual.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/ForceInsert.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/ForceInsert.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/ForceInsert.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/ForceInsert.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Hotkey.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Hotkey.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Hotkey.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Hotkey.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/LineBreak.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/LineBreak.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/LineBreak.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/LineBreak.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Link.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Link.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Link.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Link.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/List.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/List.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/List.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/List.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/QuoteBlock.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/QuoteBlock.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/QuoteBlock.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/QuoteBlock.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/SelectAll.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/SelectAll.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/SelectAll.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/SelectAll.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Shortcode.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Shortcode.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/Shortcode.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/Shortcode.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/util.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/util.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/util.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/util.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/visual.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/visual.js similarity index 96% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/visual.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/visual.js index a55c1eab..0d53945d 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/plugins/visual.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/plugins/visual.js @@ -20,7 +20,7 @@ function plugins({ getAsset, resolveWidget, t, remarkPlugins }) { { onKeyDown(event, editor, next) { if (isHotkey('mod+j', event)) { - console.log(JSON.stringify(editor.value.document.toJS(), null, 2)); + console.info(JSON.stringify(editor.value.document.toJS(), null, 2)); } next(); }, diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/renderers.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/renderers.js similarity index 99% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/renderers.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/renderers.js index 363f01be..32938097 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/renderers.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/renderers.js @@ -2,8 +2,8 @@ import React from 'react'; import { css } from '@emotion/react'; import styled from '@emotion/styled'; -import { colors, lengths } from 'netlify-cms-ui-default'; +import { colors, lengths } from '../../../ui'; import VoidBlock from './components/VoidBlock'; import Shortcode from './components/Shortcode'; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/schema.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/schema.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/MarkdownControl/schema.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownControl/schema.js diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownPreview.js b/packages/netlify-cms-core/src/widgets/markdown/MarkdownPreview.js similarity index 92% rename from packages/netlify-cms-widget-markdown/src/MarkdownPreview.js rename to packages/netlify-cms-core/src/widgets/markdown/MarkdownPreview.js index 68bf8279..d1c7f8bf 100644 --- a/packages/netlify-cms-widget-markdown/src/MarkdownPreview.js +++ b/packages/netlify-cms-core/src/widgets/markdown/MarkdownPreview.js @@ -1,8 +1,8 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; import DOMPurify from 'dompurify'; +import { WidgetPreviewContainer } from '../../ui'; import { markdownToHtml } from './serializers'; class MarkdownPreview extends React.Component { static propTypes = { diff --git a/packages/netlify-cms-widget-markdown/src/index.js b/packages/netlify-cms-core/src/widgets/markdown/index.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/index.js rename to packages/netlify-cms-core/src/widgets/markdown/index.js diff --git a/packages/netlify-cms-widget-markdown/src/regexHelper.js b/packages/netlify-cms-core/src/widgets/markdown/regexHelper.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/regexHelper.js rename to packages/netlify-cms-core/src/widgets/markdown/regexHelper.js diff --git a/packages/netlify-cms-widget-markdown/src/schema.js b/packages/netlify-cms-core/src/widgets/markdown/schema.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/schema.js rename to packages/netlify-cms-core/src/widgets/markdown/schema.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/index.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/index.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/index.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/index.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/rehypePaperEmoji.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/rehypePaperEmoji.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/rehypePaperEmoji.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/rehypePaperEmoji.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkAllowHtmlEntities.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkAllowHtmlEntities.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkAllowHtmlEntities.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkAllowHtmlEntities.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkAssertParents.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkAssertParents.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkAssertParents.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkAssertParents.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkEscapeMarkdownEntities.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkEscapeMarkdownEntities.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkEscapeMarkdownEntities.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkEscapeMarkdownEntities.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkImagesToText.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkImagesToText.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkImagesToText.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkImagesToText.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkPaddedLinks.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkPaddedLinks.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkPaddedLinks.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkPaddedLinks.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkRehypeShortcodes.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkRehypeShortcodes.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkRehypeShortcodes.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkRehypeShortcodes.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkShortcodes.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkShortcodes.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkShortcodes.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkShortcodes.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkSlate.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkSlate.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkSlate.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkSlate.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkSquashReferences.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkSquashReferences.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkSquashReferences.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkSquashReferences.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkStripTrailingBreaks.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkStripTrailingBreaks.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkStripTrailingBreaks.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkStripTrailingBreaks.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/remarkWrapHtml.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/remarkWrapHtml.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/serializers/remarkWrapHtml.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/remarkWrapHtml.js diff --git a/packages/netlify-cms-widget-markdown/src/serializers/slateRemark.js b/packages/netlify-cms-core/src/widgets/markdown/serializers/slateRemark.js similarity index 99% rename from packages/netlify-cms-widget-markdown/src/serializers/slateRemark.js rename to packages/netlify-cms-core/src/widgets/markdown/serializers/slateRemark.js index a79cab07..7fca36a0 100644 --- a/packages/netlify-cms-widget-markdown/src/serializers/slateRemark.js +++ b/packages/netlify-cms-core/src/widgets/markdown/serializers/slateRemark.js @@ -68,7 +68,6 @@ export default function slateToRemark(raw, { voidCodeBlock }) { : convertInlineAndTextChildren(node.nodes); const output = convertBlockNode(node, children); - //console.log(JSON.stringify(output, null, 2)); return output; } diff --git a/packages/netlify-cms-widget-markdown/src/styles.js b/packages/netlify-cms-core/src/widgets/markdown/styles.js similarity index 84% rename from packages/netlify-cms-widget-markdown/src/styles.js rename to packages/netlify-cms-core/src/widgets/markdown/styles.js index 686f7cc7..9ca94b75 100644 --- a/packages/netlify-cms-widget-markdown/src/styles.js +++ b/packages/netlify-cms-core/src/widgets/markdown/styles.js @@ -1,5 +1,6 @@ import styled from '@emotion/styled'; -import { zIndex } from 'netlify-cms-ui-default'; + +import { zIndex } from '../../ui'; export const editorStyleVars = { stickyDistanceBottom: '100px', diff --git a/packages/netlify-cms-widget-markdown/src/types.js b/packages/netlify-cms-core/src/widgets/markdown/types.js similarity index 100% rename from packages/netlify-cms-widget-markdown/src/types.js rename to packages/netlify-cms-core/src/widgets/markdown/types.js diff --git a/packages/netlify-cms-widget-number/src/NumberControl.js b/packages/netlify-cms-core/src/widgets/number/NumberControl.js similarity index 87% rename from packages/netlify-cms-widget-number/src/NumberControl.js rename to packages/netlify-cms-core/src/widgets/number/NumberControl.js index 35606d9e..6e6ac4cd 100644 --- a/packages/netlify-cms-widget-number/src/NumberControl.js +++ b/packages/netlify-cms-core/src/widgets/number/NumberControl.js @@ -80,21 +80,6 @@ export default class NumberControl extends React.Component { } }; - isValid = () => { - const { field, value, t } = this.props; - const hasPattern = !!field.get('pattern', false); - const min = field.get('min', false); - const max = field.get('max', false); - - // Pattern overrides min/max logic always: - if (hasPattern) { - return true; - } - - const error = validateMinMax(value, min, max, field, t); - return error ? { error } : true; - }; - render() { const { field, value, classNameWrapper, forID, setActiveStyle, setInactiveStyle } = this.props; const min = field.get('min', ''); diff --git a/packages/netlify-cms-widget-number/src/NumberPreview.js b/packages/netlify-cms-core/src/widgets/number/NumberPreview.js similarity index 80% rename from packages/netlify-cms-widget-number/src/NumberPreview.js rename to packages/netlify-cms-core/src/widgets/number/NumberPreview.js index f1cdd305..1e7df36e 100644 --- a/packages/netlify-cms-widget-number/src/NumberPreview.js +++ b/packages/netlify-cms-core/src/widgets/number/NumberPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function NumberPreview({ value }) { return {value}; diff --git a/packages/netlify-cms-core/src/widgets/number/index.js b/packages/netlify-cms-core/src/widgets/number/index.js new file mode 100644 index 00000000..bc81108c --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/number/index.js @@ -0,0 +1,29 @@ +import controlComponent, { validateMinMax } from './NumberControl'; +import previewComponent from './NumberPreview'; +import schema from './schema'; + +function Widget(opts = {}) { + return { + name: 'number', + controlComponent, + previewComponent, + validator: ({ field, value, t }) => { + const hasPattern = !!field.get('pattern', false); + const min = field.get('min', false); + const max = field.get('max', false); + + // Pattern overrides min/max logic always: + if (hasPattern) { + return true; + } + + const error = validateMinMax(value, min, max, field, t); + return error ? { error } : true; + }, + schema, + ...opts, + }; +} + +export const NetlifyCmsWidgetNumber = { Widget, controlComponent, previewComponent }; +export default NetlifyCmsWidgetNumber; diff --git a/packages/netlify-cms-widget-number/src/schema.js b/packages/netlify-cms-core/src/widgets/number/schema.js similarity index 100% rename from packages/netlify-cms-widget-number/src/schema.js rename to packages/netlify-cms-core/src/widgets/number/schema.js diff --git a/packages/netlify-cms-widget-object/src/ObjectControl.js b/packages/netlify-cms-core/src/widgets/object/ObjectControl.js similarity index 97% rename from packages/netlify-cms-widget-object/src/ObjectControl.js rename to packages/netlify-cms-core/src/widgets/object/ObjectControl.js index 0ac3b301..3461920b 100644 --- a/packages/netlify-cms-widget-object/src/ObjectControl.js +++ b/packages/netlify-cms-core/src/widgets/object/ObjectControl.js @@ -4,8 +4,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { ClassNames } from '@emotion/react'; import styled from '@emotion/styled'; import { List, Map } from 'immutable'; -import { colors, lengths, ObjectWidgetTopBar } from 'netlify-cms-ui-default'; -import { stringTemplate } from 'netlify-cms-lib-widgets'; + +import { colors, lengths, ObjectWidgetTopBar } from '../../ui'; +import { stringTemplate } from '../../lib/widgets'; const styleStrings = { nestedObjectControl: ` diff --git a/packages/netlify-cms-widget-object/src/ObjectPreview.js b/packages/netlify-cms-core/src/widgets/object/ObjectPreview.js similarity index 83% rename from packages/netlify-cms-widget-object/src/ObjectPreview.js rename to packages/netlify-cms-core/src/widgets/object/ObjectPreview.js index 40847fac..8703c84a 100644 --- a/packages/netlify-cms-widget-object/src/ObjectPreview.js +++ b/packages/netlify-cms-core/src/widgets/object/ObjectPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function ObjectPreview({ field }) { return ( diff --git a/packages/netlify-cms-widget-object/src/index.js b/packages/netlify-cms-core/src/widgets/object/index.js similarity index 100% rename from packages/netlify-cms-widget-object/src/index.js rename to packages/netlify-cms-core/src/widgets/object/index.js diff --git a/packages/netlify-cms-widget-object/src/schema.js b/packages/netlify-cms-core/src/widgets/object/schema.js similarity index 100% rename from packages/netlify-cms-widget-object/src/schema.js rename to packages/netlify-cms-core/src/widgets/object/schema.js diff --git a/packages/netlify-cms-widget-relation/src/RelationControl.js b/packages/netlify-cms-core/src/widgets/relation/RelationControl.js similarity index 94% rename from packages/netlify-cms-widget-relation/src/RelationControl.js rename to packages/netlify-cms-core/src/widgets/relation/RelationControl.js index 54c9bb9a..71c58d85 100644 --- a/packages/netlify-cms-widget-relation/src/RelationControl.js +++ b/packages/netlify-cms-core/src/widgets/relation/RelationControl.js @@ -5,11 +5,12 @@ import { components } from 'react-select'; import AsyncSelect from 'react-select/async'; import { debounce, find, get, isEmpty, last, uniqBy } from 'lodash'; import { fromJS, List, Map } from 'immutable'; -import { reactSelectStyles } from 'netlify-cms-ui-default'; -import { stringTemplate, validations } from 'netlify-cms-lib-widgets'; import { FixedSizeList } from 'react-window'; import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc'; +import { reactSelectStyles } from '../../ui'; +import { stringTemplate, validations } from '../../lib/widgets'; + function arrayMove(array, from, to) { const slicedArray = array.slice(); slicedArray.splice(to < 0 ? array.length + to : to, 0, slicedArray.splice(from, 1)[0]); @@ -121,26 +122,6 @@ export default class RelationControl extends React.Component { locale: PropTypes.string, }; - isValid = () => { - const { field, value, t } = this.props; - const min = field.get('min'); - const max = field.get('max'); - - if (!this.isMultiple()) { - return { error: false }; - } - - const error = validations.validateMinMax( - t, - field.get('label', field.get('name')), - value, - min, - max, - ); - - return error ? { error } : { error: false }; - }; - shouldComponentUpdate(nextProps) { return ( this.props.value !== nextProps.value || diff --git a/packages/netlify-cms-widget-relation/src/RelationPreview.js b/packages/netlify-cms-core/src/widgets/relation/RelationPreview.js similarity index 80% rename from packages/netlify-cms-widget-relation/src/RelationPreview.js rename to packages/netlify-cms-core/src/widgets/relation/RelationPreview.js index da998273..e3e74be8 100644 --- a/packages/netlify-cms-widget-relation/src/RelationPreview.js +++ b/packages/netlify-cms-core/src/widgets/relation/RelationPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function RelationPreview({ value }) { return {value}; diff --git a/packages/netlify-cms-core/src/widgets/relation/index.js b/packages/netlify-cms-core/src/widgets/relation/index.js new file mode 100644 index 00000000..e733847e --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/relation/index.js @@ -0,0 +1,34 @@ +import controlComponent from './RelationControl'; +import previewComponent from './RelationPreview'; +import schema from './schema'; + +function Widget(opts = {}) { + return { + name: 'relation', + controlComponent, + previewComponent, + validator: ({ field, value, t }) => { + const min = field.get('min'); + const max = field.get('max'); + + if (!this.isMultiple()) { + return { error: false }; + } + + const error = validations.validateMinMax( + t, + field.get('label', field.get('name')), + value, + min, + max, + ); + + return error ? { error } : { error: false }; + }, + schema, + ...opts, + }; +} + +export const NetlifyCmsWidgetRelation = { Widget, controlComponent, previewComponent }; +export default NetlifyCmsWidgetRelation; diff --git a/packages/netlify-cms-widget-relation/src/schema.js b/packages/netlify-cms-core/src/widgets/relation/schema.js similarity index 100% rename from packages/netlify-cms-widget-relation/src/schema.js rename to packages/netlify-cms-core/src/widgets/relation/schema.js diff --git a/packages/netlify-cms-widget-select/src/SelectControl.js b/packages/netlify-cms-core/src/widgets/select/SelectControl.js similarity index 86% rename from packages/netlify-cms-widget-select/src/SelectControl.js rename to packages/netlify-cms-core/src/widgets/select/SelectControl.js index 1386a159..9591dac2 100644 --- a/packages/netlify-cms-widget-select/src/SelectControl.js +++ b/packages/netlify-cms-core/src/widgets/select/SelectControl.js @@ -4,8 +4,9 @@ import ImmutablePropTypes from 'react-immutable-proptypes'; import { Map, List, fromJS } from 'immutable'; import { find } from 'lodash'; import Select from 'react-select'; -import { reactSelectStyles } from 'netlify-cms-ui-default'; -import { validations } from 'netlify-cms-lib-widgets'; + +import { reactSelectStyles } from '../../ui'; +import { validations } from '../../lib/widgets'; function optionToString(option) { return option && option.value ? option.value : null; @@ -56,26 +57,6 @@ export default class SelectControl extends React.Component { }), }; - isValid = () => { - const { field, value, t } = this.props; - const min = field.get('min'); - const max = field.get('max'); - - if (!field.get('multiple')) { - return { error: false }; - } - - const error = validations.validateMinMax( - t, - field.get('label', field.get('name')), - value, - min, - max, - ); - - return error ? { error } : { error: false }; - }; - handleChange = selectedOption => { const { onChange, field } = this.props; const isMultiple = field.get('multiple', false); diff --git a/packages/netlify-cms-widget-select/src/SelectPreview.js b/packages/netlify-cms-core/src/widgets/select/SelectPreview.js similarity index 91% rename from packages/netlify-cms-widget-select/src/SelectPreview.js rename to packages/netlify-cms-core/src/widgets/select/SelectPreview.js index 17ccac63..850a0851 100644 --- a/packages/netlify-cms-widget-select/src/SelectPreview.js +++ b/packages/netlify-cms-core/src/widgets/select/SelectPreview.js @@ -2,7 +2,8 @@ import PropTypes from 'prop-types'; import React from 'react'; import { List } from 'immutable'; import ImmutablePropTypes from 'react-immutable-proptypes'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function ListPreview({ values }) { return ( diff --git a/packages/netlify-cms-core/src/widgets/select/index.js b/packages/netlify-cms-core/src/widgets/select/index.js new file mode 100644 index 00000000..47219216 --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/select/index.js @@ -0,0 +1,34 @@ +import controlComponent from './SelectControl'; +import previewComponent from './SelectPreview'; +import schema from './schema'; + +function Widget(opts = {}) { + return { + name: 'select', + controlComponent, + previewComponent, + validator: ({ field, value, t }) => { + const min = field.get('min'); + const max = field.get('max'); + + if (!field.get('multiple')) { + return { error: false }; + } + + const error = validations.validateMinMax( + t, + field.get('label', field.get('name')), + value, + min, + max, + ); + + return error ? { error } : { error: false }; + }, + schema, + ...opts, + }; +} + +export const NetlifyCmsWidgetSelect = { Widget, controlComponent, previewComponent }; +export default NetlifyCmsWidgetSelect; diff --git a/packages/netlify-cms-widget-select/src/schema.js b/packages/netlify-cms-core/src/widgets/select/schema.js similarity index 100% rename from packages/netlify-cms-widget-select/src/schema.js rename to packages/netlify-cms-core/src/widgets/select/schema.js diff --git a/packages/netlify-cms-core/src/widgets/string/StringControl.tsx b/packages/netlify-cms-core/src/widgets/string/StringControl.tsx new file mode 100644 index 00000000..bdac6191 --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/string/StringControl.tsx @@ -0,0 +1,52 @@ +import React, { forwardRef, useCallback, useEffect, useState } from 'react'; +import { CmsWidgetControlProps } from '../../interface'; + +const StringControl = forwardRef>( + ({ + onChange, + forID, + value = '', + classNameWrapper, + setActiveStyle, + setInactiveStyle, + }: CmsWidgetControlProps, _ref) => { + const [element, setElement] = useState(null); + const [selection, setSelection] = useState(null); + + const handleChange = useCallback((e: React.ChangeEvent) => { + setSelection(e.target.selectionStart); + onChange(e.target.value); + }, []); + + const handleSetElement = useCallback((el: HTMLInputElement) => { + setElement(el); + }, []); + + useEffect(() => { + if (!element) { + return; + } + + if (element.selectionStart !== selection) { + element.setSelectionRange(selection, selection); + } + }, [element, element?.selectionStart, selection]); + + return ( + + ); + }, +); + +StringControl.displayName = 'StringControl'; + +export default StringControl; diff --git a/packages/netlify-cms-core/src/widgets/string/StringPreview.tsx b/packages/netlify-cms-core/src/widgets/string/StringPreview.tsx new file mode 100644 index 00000000..483dd91d --- /dev/null +++ b/packages/netlify-cms-core/src/widgets/string/StringPreview.tsx @@ -0,0 +1,10 @@ +import React from 'react'; + +import { CmsWidgetPreviewProps } from '../../interface'; +import { WidgetPreviewContainer } from '../../ui'; + +function StringPreview({ value = '' }: CmsWidgetPreviewProps) { + return {value}; +} + +export default StringPreview; diff --git a/packages/netlify-cms-widget-string/src/index.js b/packages/netlify-cms-core/src/widgets/string/index.tsx similarity index 75% rename from packages/netlify-cms-widget-string/src/index.js rename to packages/netlify-cms-core/src/widgets/string/index.tsx index ddb84c98..95082e98 100644 --- a/packages/netlify-cms-widget-string/src/index.js +++ b/packages/netlify-cms-core/src/widgets/string/index.tsx @@ -1,7 +1,8 @@ +import { CmsWidgetParam } from '../../interface'; import controlComponent from './StringControl'; import previewComponent from './StringPreview'; -function Widget(opts = {}) { +function Widget(opts = {}): CmsWidgetParam { return { name: 'string', controlComponent, diff --git a/packages/netlify-cms-widget-text/src/TextControl.js b/packages/netlify-cms-core/src/widgets/text/TextControl.js similarity index 100% rename from packages/netlify-cms-widget-text/src/TextControl.js rename to packages/netlify-cms-core/src/widgets/text/TextControl.js diff --git a/packages/netlify-cms-widget-text/src/TextPreview.js b/packages/netlify-cms-core/src/widgets/text/TextPreview.js similarity index 79% rename from packages/netlify-cms-widget-text/src/TextPreview.js rename to packages/netlify-cms-core/src/widgets/text/TextPreview.js index ec5fb8f0..3a7d66f0 100644 --- a/packages/netlify-cms-widget-text/src/TextPreview.js +++ b/packages/netlify-cms-core/src/widgets/text/TextPreview.js @@ -1,6 +1,7 @@ import React from 'react'; import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; + +import { WidgetPreviewContainer } from '../../ui'; function TextPreview({ value }) { return {value}; diff --git a/packages/netlify-cms-widget-text/src/index.js b/packages/netlify-cms-core/src/widgets/text/index.js similarity index 100% rename from packages/netlify-cms-widget-text/src/index.js rename to packages/netlify-cms-core/src/widgets/text/index.js diff --git a/packages/netlify-cms-core/webpack.config.js b/packages/netlify-cms-core/webpack.config.js index 6dc835fa..3ae4aef5 100644 --- a/packages/netlify-cms-core/webpack.config.js +++ b/packages/netlify-cms-core/webpack.config.js @@ -1,21 +1,36 @@ const webpack = require('webpack'); +const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); const pkg = require('./package.json'); -const { getConfig } = require('../../scripts/webpack.js'); +const { getConfig, plugins } = require('../../scripts/webpack.js'); +const baseWebpackConfig = getConfig({ baseOnly: true }); const isProduction = process.env.NODE_ENV === 'production'; +const devServerPort = parseInt(process.env.NETLIFY_CMS_DEV_SERVER_PORT || `${8080}`); -const versionPlugin = new webpack.DefinePlugin({ - NETLIFY_CMS_CORE_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), -}); +const baseConfig = { + ...baseWebpackConfig, + plugins: [ + ...Object.entries(plugins) + .filter(([key]) => key !== 'friendlyErrors') + .map(([, plugin]) => plugin()), + new webpack.DefinePlugin({ + NETLIFY_CMS_CORE_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), + }), + new FriendlyErrorsWebpackPlugin({ + compilationSuccessInfo: { + messages: [`Netlify CMS is now running at http://localhost:${devServerPort}`], + }, + }) + ], + devServer: { + contentBase: '../../dev-test', + watchContentBase: true, + publicPath: '/dist', + quiet: true, + host: '0.0.0.0', + port: devServerPort, + }, +}; -function configs() { - return getConfig().map(config => { - return { - ...config, - plugins: [...config.plugins, versionPlugin], - }; - }); -} - -module.exports = configs(); +module.exports = baseConfig; diff --git a/packages/netlify-cms-default-exports/CHANGELOG.md b/packages/netlify-cms-default-exports/CHANGELOG.md deleted file mode 100644 index 70b3b1e5..00000000 --- a/packages/netlify-cms-default-exports/CHANGELOG.md +++ /dev/null @@ -1,168 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.4.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-default-exports@2.4.1...netlify-cms-default-exports@2.4.2) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-default-exports@2.4.0...netlify-cms-default-exports@2.4.1) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.3.5...netlify-cms-default-exports@2.4.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.3.4...netlify-cms-default-exports@2.3.5) (2020-11-26) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.3.3...netlify-cms-default-exports@2.3.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## 2.3.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.3.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.3.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.3...netlify-cms-default-exports@2.3.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.2...netlify-cms-default-exports@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.2-beta.0...netlify-cms-default-exports@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.1...netlify-cms-default-exports@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.1-beta.2...netlify-cms-default-exports@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.1-beta.1...netlify-cms-default-exports@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.1-beta.0...netlify-cms-default-exports@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.2.0...netlify-cms-default-exports@2.2.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-default-exports - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/compare/netlify-cms-default-exports@2.1.0...netlify-cms-default-exports@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/d142b32)) - - - - - -# 2.1.0 (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports/commit/82cc794)) diff --git a/packages/netlify-cms-default-exports/package.json b/packages/netlify-cms-default-exports/package.json deleted file mode 100644 index 1111e06c..00000000 --- a/packages/netlify-cms-default-exports/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "netlify-cms-default-exports", - "version": "2.4.2", - "description": "NetlifyCMS default exports", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-default-exports", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-default-exports.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "editor", - "component" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "moment": "^2.24.0", - "prop-types": "^15.7.2", - "react-immutable-proptypes": "^2.1.0", - "uuid": "^3.3.2" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-default-exports/src/index.js b/packages/netlify-cms-default-exports/src/index.js deleted file mode 100644 index f4a8e48f..00000000 --- a/packages/netlify-cms-default-exports/src/index.js +++ /dev/null @@ -1,43 +0,0 @@ -// eslint-disable-next-line @emotion/no-vanilla -import css from '@emotion/css'; -import { - withEmotionCache, - CacheProvider, - ThemeContext, - jsx, - Global, - keyframes, - ClassNames, -} from '@emotion/react'; -import EmotionStyled from '@emotion/styled'; -import Immutable from 'immutable'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import Lodash from 'lodash/lodash'; -import Moment from 'moment'; -import PropTypes from 'prop-types'; -import React from 'react'; -import ReactDOM from 'react-dom'; -import * as UUId from 'uuid'; - -const EmotionCore = { - css, - withEmotionCache, - CacheProvider, - ThemeContext, - jsx, - Global, - keyframes, - ClassNames, -}; -export const NetlifyCmsDefaultExports = { - EmotionCore, - EmotionStyled, - Immutable, - ImmutablePropTypes, - Lodash, - Moment, - PropTypes, - React, - ReactDOM, - UUId, -}; diff --git a/packages/netlify-cms-default-exports/webpack.config.js b/packages/netlify-cms-default-exports/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-default-exports/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-editor-component-image/CHANGELOG.md b/packages/netlify-cms-editor-component-image/CHANGELOG.md deleted file mode 100644 index a47ab91d..00000000 --- a/packages/netlify-cms-editor-component-image/CHANGELOG.md +++ /dev/null @@ -1,269 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.6.7...netlify-cms-editor-component-image@2.7.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.6.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.6.6...netlify-cms-editor-component-image@2.6.7) (2020-10-12) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.6.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.6.5...netlify-cms-editor-component-image@2.6.6) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## 2.6.5 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.6.4 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.6.3 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.6.1...netlify-cms-editor-component-image@2.6.2) (2020-02-14) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.6.0...netlify-cms-editor-component-image@2.6.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.5.0...netlify-cms-editor-component-image@2.6.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.5.0-beta.0...netlify-cms-editor-component-image@2.5.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.3...netlify-cms-editor-component-image@2.5.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -## [2.4.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.2...netlify-cms-editor-component-image@2.4.3) (2019-11-07) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.2-beta.0...netlify-cms-editor-component-image@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.1...netlify-cms-editor-component-image@2.4.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.1-beta.1...netlify-cms-editor-component-image@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.1-beta.0...netlify-cms-editor-component-image@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.4.0...netlify-cms-editor-component-image@2.4.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.3.0...netlify-cms-editor-component-image@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/d142b32)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.3.0-beta.0...netlify-cms-editor-component-image@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-editor-component-image - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.2.1-beta.0...netlify-cms-editor-component-image@2.3.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/82cc794)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.2.0...netlify-cms-editor-component-image@2.2.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/ccef446)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.1.0...netlify-cms-editor-component-image@2.2.0) (2018-12-11) - - -### Features - -* **editor-components:** support title in image component ([#1862](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/1862)) ([cbb7762](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/cbb7762)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.0.4...netlify-cms-editor-component-image@2.1.0) (2018-12-04) - - -### Features - -* add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/commit/1fc2f50)) - - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.0.3...netlify-cms-editor-component-image@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-editor-component-image - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.0.2...netlify-cms-editor-component-image@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-editor-component-image - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image/compare/netlify-cms-editor-component-image@2.0.1...netlify-cms-editor-component-image@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-editor-component-image - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-editor-component-image diff --git a/packages/netlify-cms-editor-component-image/README.md b/packages/netlify-cms-editor-component-image/README.md deleted file mode 100644 index ff3b13e8..00000000 --- a/packages/netlify-cms-editor-component-image/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-editor-component-image/README.md)! diff --git a/packages/netlify-cms-editor-component-image/package.json b/packages/netlify-cms-editor-component-image/package.json deleted file mode 100644 index 423ea69c..00000000 --- a/packages/netlify-cms-editor-component-image/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "netlify-cms-editor-component-image", - "description": "Image component for Netlify CMS editor widget", - "version": "2.7.0", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-editor-component-image", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-editor-component-image.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "editor", - "component" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "devDependencies": { - "cross-env": "^7.0.0", - "webpack": "^4.29.6", - "webpack-cli": "^4.0.0" - }, - "peerDependencies": { - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-editor-component-image/src/__tests__/index.spec.js b/packages/netlify-cms-editor-component-image/src/__tests__/index.spec.js deleted file mode 100644 index 325df448..00000000 --- a/packages/netlify-cms-editor-component-image/src/__tests__/index.spec.js +++ /dev/null @@ -1,75 +0,0 @@ -import component from '../index'; - -function getAsset(path) { - return path; -} - -const image = '/image'; -const alt = 'alt'; -const title = 'title'; - -describe('editor component image', () => { - it('should generate empty markdown image from empty object', () => { - expect(component.toBlock({})).toEqual(`![]()`); - }); - - it('should generate valid markdown from path', () => { - expect(component.toBlock({ image })).toEqual(`![](/image)`); - }); - - it('should generate valid markdown from path and alt text', () => { - expect(component.toBlock({ image, alt })).toEqual(`![alt](/image)`); - }); - - it('should generate valid markdown from path and title', () => { - expect(component.toBlock({ image, title })).toEqual(`![](/image "title")`); - }); - - it('should generate valid markdown from path, alt text, and title ', () => { - expect(component.toBlock({ image, alt, title })).toEqual(`![alt](/image "title")`); - }); - - it('should escape quotes in title', () => { - expect(component.toBlock({ image, alt, title: `"ti"tle"` })).toEqual( - `![alt](/image "\\"ti\\"tle\\"")`, - ); - }); - - it('should generate valid react props', () => { - expect(component.toPreview({ image, alt, title }, getAsset)).toMatchObject({ - props: { src: image, alt, title }, - }); - }); - - it('should match markdown with no properties defined', () => { - expect(`![]()`).toMatch(component.pattern); - }); - - it('should match markdown with path', () => { - expect(`![](/image)`).toMatch(component.pattern); - }); - - it('should match markdown with path and alt text', () => { - expect(`![alt](/image)`).toMatch(component.pattern); - }); - - it('should match markdown with path and title', () => { - expect(`![](/image "title")`).toMatch(component.pattern); - }); - - it('should match markdown with path, alt text, and title', () => { - expect(`![alt](/image "title")`).toMatch(component.pattern); - }); - - it('should match markdown with path, alt text, and title', () => { - expect(`![alt](/image "title")`).toMatch(component.pattern); - }); - - it('should match markdown with arbitrary amount of whitespace', () => { - expect(`![alt](/image "title")`).toMatch(component.pattern); - }); - - it('should match markdown with quoted title', () => { - expect(`![alt](/image "\\"ti\\"tle\\"")`).toMatch(component.pattern); - }); -}); diff --git a/packages/netlify-cms-editor-component-image/webpack.config.js b/packages/netlify-cms-editor-component-image/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-editor-component-image/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-lib-auth/CHANGELOG.md b/packages/netlify-cms-lib-auth/CHANGELOG.md deleted file mode 100644 index f54b81a1..00000000 --- a/packages/netlify-cms-lib-auth/CHANGELOG.md +++ /dev/null @@ -1,274 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.4.1...netlify-cms-lib-auth@2.4.2) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.4.0...netlify-cms-lib-auth@2.4.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.3.0...netlify-cms-lib-auth@2.4.0) (2021-04-14) - - -### Features - -* Adds PKCE authentication for GitLab closes [#5236](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/5236) ([#5239](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/5239)) ([829409e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/829409e0bc03b4591ee6b59d9895adc4e7190037)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.12...netlify-cms-lib-auth@2.3.0) (2020-11-26) - - -### Features - -* add azure devops backend ([#4427](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/4427)) ([4e6dc88](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/4e6dc88efb1dae4cf6137730c3b4fb6d0f75a8cc)) - - - - - -## [2.2.12](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.11...netlify-cms-lib-auth@2.2.12) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## 2.2.11 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.2.10 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.2.9 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.2.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.7...netlify-cms-lib-auth@2.2.8) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.6...netlify-cms-lib-auth@2.2.7) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.6-beta.0...netlify-cms-lib-auth@2.2.6) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.6-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.5...netlify-cms-lib-auth@2.2.6-beta.0) (2019-12-02) - - -### Bug Fixes - -* pass auth type in authURL to be used in identity widget ([#2920](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/2920)) ([87b4d0f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/87b4d0f7657df83ba25a9d4ab23b878dc3324b86)) - - - - - -## [2.2.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.4...netlify-cms-lib-auth@2.2.5) (2019-11-18) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.3...netlify-cms-lib-auth@2.2.4) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.2...netlify-cms-lib-auth@2.2.3) (2019-06-26) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.2-beta.0...netlify-cms-lib-auth@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.1...netlify-cms-lib-auth@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.1-beta.1...netlify-cms-lib-auth@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.1-beta.0...netlify-cms-lib-auth@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.2.0...netlify-cms-lib-auth@2.2.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.1.0...netlify-cms-lib-auth@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.1.0-beta.0...netlify-cms-lib-auth@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-lib-auth - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.6-beta.0...netlify-cms-lib-auth@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/82cc794)) - - - - - -## [2.0.6-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.5...netlify-cms-lib-auth@2.0.6-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/ccef446)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.4...netlify-cms-lib-auth@2.0.5) (2018-11-12) - - -### Bug Fixes - -* **auth:** scrollbars not appearing in auth window ([#1766](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/issues/1766)) ([8176243](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/commit/8176243)) - - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.3...netlify-cms-lib-auth@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-lib-auth - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.2...netlify-cms-lib-auth@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-lib-auth - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth/compare/netlify-cms-lib-auth@2.0.1...netlify-cms-lib-auth@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-lib-auth - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - -### Bug Fixes - -* **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/netlify/netlify-cms/issues/1522)) ([bdfd944](https://github.com/netlify/netlify-cms/commit/bdfd944)) diff --git a/packages/netlify-cms-lib-auth/README.md b/packages/netlify-cms-lib-auth/README.md deleted file mode 100644 index 5c2cab82..00000000 --- a/packages/netlify-cms-lib-auth/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Lib Auth - -Shared components to handle OAuth and implicit authentication flows. diff --git a/packages/netlify-cms-lib-auth/index.d.ts b/packages/netlify-cms-lib-auth/index.d.ts deleted file mode 100644 index f09b4ade..00000000 --- a/packages/netlify-cms-lib-auth/index.d.ts +++ /dev/null @@ -1,11 +0,0 @@ -declare module 'netlify-cms-lib-auth' { - class NetlifyAuthenticator { - constructor(config = {}); - - refresh: (args: { - provider: string; - refresh_token: string; - }) => Promise<{ token: string; refresh_token: string }>; - } - export { NetlifyAuthenticator }; -} diff --git a/packages/netlify-cms-lib-auth/package.json b/packages/netlify-cms-lib-auth/package.json deleted file mode 100644 index caca54bb..00000000 --- a/packages/netlify-cms-lib-auth/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "netlify-cms-lib-auth", - "description": "Shared authentication functionality for Netlify CMS.", - "version": "2.4.2", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-auth", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-lib-auth.js", - "license": "MIT", - "files": [ - "src/", - "dist/" - ], - "keywords": [ - "netlify-cms" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "uuid": "^3.3.2" - } -} diff --git a/packages/netlify-cms-lib-auth/webpack.config.js b/packages/netlify-cms-lib-auth/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-lib-auth/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-lib-util/CHANGELOG.md b/packages/netlify-cms-lib-util/CHANGELOG.md deleted file mode 100644 index 4d4e4958..00000000 --- a/packages/netlify-cms-lib-util/CHANGELOG.md +++ /dev/null @@ -1,598 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.15.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-util@2.15.2...netlify-cms-lib-util@2.15.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.15.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-util@2.15.1...netlify-cms-lib-util@2.15.2) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.15.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-util@2.15.0...netlify-cms-lib-util@2.15.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.15.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-util@2.14.0...netlify-cms-lib-util@2.15.0) (2021-12-28) - - -### Features - -* **backend-gitlab:** initial GraphQL support ([#6059](https://github.com/netlify/netlify-cms/issues/6059)) ([1523a41](https://github.com/netlify/netlify-cms/commit/1523a4140a3d2f4cc01a1548514ae17bc1ad504e)) - - - - - -# [2.14.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-util@2.13.3...netlify-cms-lib-util@2.14.0) (2021-10-18) - - -### Features - -* display author of changes in workflow tab ([#5780](https://github.com/netlify/netlify-cms/issues/5780)) ([3f607e4](https://github.com/netlify/netlify-cms/commit/3f607e41d9c4d8fe5329a9ab6841cada7742825e)) - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.13.2...netlify-cms-lib-util@2.13.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.13.1...netlify-cms-lib-util@2.13.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.13.0...netlify-cms-lib-util@2.13.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.3...netlify-cms-lib-util@2.13.0) (2021-04-04) - - -### Features - -* **open-authoring:** add alwaysFork option ([#5204](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/5204)) ([7b19e30](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/7b19e30dd2a310dbc20ccb6fcca45d5cbde1014b)) - - - - - -## [2.12.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.2...netlify-cms-lib-util@2.12.3) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.12.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.1...netlify-cms-lib-util@2.12.2) (2021-02-01) - - -### Bug Fixes - -* **backend:** allow calling 'json' again on 403 failure ([#4880](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/4880)) ([1034086](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/1034086ff603e28e3a37c8157a74cbc625f658f9)) - - - - - -## [2.12.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.12.0...netlify-cms-lib-util@2.12.1) (2020-12-13) - - -### Bug Fixes - -* **lib-util:** update js-sha256 import ([#4699](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/4699)) ([60f7e0b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/60f7e0bba67c6555acba3e04039c49f10cf51f6b)) - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.11.5...netlify-cms-lib-util@2.12.0) (2020-11-26) - - -### Features - -* add azure devops backend ([#4427](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/4427)) ([4e6dc88](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/4e6dc88efb1dae4cf6137730c3b4fb6d0f75a8cc)) - - - - - -## [2.11.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.11.4...netlify-cms-lib-util@2.11.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.11.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.11.3...netlify-cms-lib-util@2.11.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## 2.11.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.11.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.11.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.10.0...netlify-cms-lib-util@2.11.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.9.4...netlify-cms-lib-util@2.10.0) (2020-06-01) - - -### Features - -* add pre save/ post save hooks ([#3812](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3812)) ([812716e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/812716e18b09a716547f128b783c8e6f3d54cc5b)) - - - - - -## [2.9.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.9.3...netlify-cms-lib-util@2.9.4) (2020-05-19) - - -### Bug Fixes - -* clear fetch timeout on successful response ([#3768](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3768)) ([088b1a8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/088b1a8ab626498382d6305fa46d174d4f5ba755)) - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.9.2...netlify-cms-lib-util@2.9.3) (2020-04-21) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.9.1...netlify-cms-lib-util@2.9.2) (2020-04-01) - - -### Bug Fixes - -* move common api functions to a separate file ([#3511](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3511)) ([49098de](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/49098de27f053e51aa3d936d09adae3a7186c6ae)) - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.9.0...netlify-cms-lib-util@2.9.1) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.8.0...netlify-cms-lib-util@2.9.0) (2020-03-12) - - -### Features - -* add media lib virtualization ([#3381](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3381)) ([92e7601](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/92e76011e7a9e8b5370088b0a2c065df66b5f7fb)) -* **backend-github:** add pagination ([#3379](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3379)) ([39f1307](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/39f1307e3a36447da8c9b3ca79b1d7db52ea1a19)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.7.1...netlify-cms-lib-util@2.8.0) (2020-02-25) - - -### Features - -* **core:** align GitHub metadata handling with other backends ([#3316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3316)) ([7e0a8ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/7e0a8ad532012576dc5e40bd4e9d54522e307123)), closes [#3292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3292) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.7.0...netlify-cms-lib-util@2.7.1) (2020-02-14) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.6.2...netlify-cms-lib-util@2.7.0) (2020-02-10) - - -### Bug Fixes - -* filter paginated results ([#3216](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3216)) ([0a482b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/0a482b10049bcfa022b81165cabf4512d77e0b88)) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.6.1...netlify-cms-lib-util@2.6.2) (2020-01-24) - - -### Bug Fixes - -* **backend-git-gateway:** re-write GitHub pagination links ([#3135](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3135)) ([834f6b9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/834f6b9e457f3738ce0f240ddd4cc160aff9e2f5)) - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.6.0...netlify-cms-lib-util@2.6.1) (2020-01-22) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.5.2...netlify-cms-lib-util@2.6.0) (2020-01-21) - - -### Features - -* **backend-bitbucket:** Add Git-LFS support ([#3118](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3118)) ([a48c02d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/a48c02d852ca5e11055da3a14cefae8d17a68498)) - - - - - -## [2.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.5.1...netlify-cms-lib-util@2.5.2) (2020-01-16) - - -### Bug Fixes - -* use string endsWith to filter by extension ([#3097](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/3097)) ([6a13a85](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/6a13a85e269c8f299f71b3f5ee45fc5d34f75822)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.5.0...netlify-cms-lib-util@2.5.1) (2020-01-14) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.5.0-beta.0...netlify-cms-lib-util@2.5.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0...netlify-cms-lib-util@2.5.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.5...netlify-cms-lib-util@2.4.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.4.0-beta.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.4...netlify-cms-lib-util@2.4.0-beta.5) (2019-11-26) - - -### Bug Fixes - -* **backend-github:** editorial workflow commits ([#2867](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2867)) ([86adca3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/86adca3a18f25ab74d1c6702bafab250f005ceec)) -* **backend-github:** prepend collection name ([#2878](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2878)) ([465f463](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/465f4639597f258d5aa2c1b65e9d2c16023ee7ae)) - - - - - -# [2.4.0-beta.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.3...netlify-cms-lib-util@2.4.0-beta.4) (2019-09-26) - - -### Bug Fixes - -* **github-backend:** handle race condition in editorial workflow ([#2658](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2658)) ([97f1f84](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/97f1f84)) - - - - - -# [2.4.0-beta.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.2...netlify-cms-lib-util@2.4.0-beta.3) (2019-09-04) - - -### Features - -* **backend-github:** GitHub GraphQL API support ([#2456](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2456)) ([ece136c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/ece136c)) - - - - - -# [2.4.0-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.1...netlify-cms-lib-util@2.4.0-beta.2) (2019-08-24) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.4.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.4.0-beta.0...netlify-cms-lib-util@2.4.0-beta.1) (2019-08-24) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.4.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.3...netlify-cms-lib-util@2.4.0-beta.0) (2019-07-24) - - -### Features - -* **backend-github:** Open Authoring ([#2430](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2430)) ([edf0a3a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/edf0a3a)) - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.2...netlify-cms-lib-util@2.3.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.2-beta.0...netlify-cms-lib-util@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.1...netlify-cms-lib-util@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.1-beta.1...netlify-cms-lib-util@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.1-beta.0...netlify-cms-lib-util@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.3.0...netlify-cms-lib-util@2.3.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.2.0...netlify-cms-lib-util@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.2.0-beta.0...netlify-cms-lib-util@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.1.3-beta.0...netlify-cms-lib-util@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/82cc794)) - - - - - -## [2.1.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.1.2...netlify-cms-lib-util@2.1.3-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/ccef446)) - - - - - -## [2.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.1.1...netlify-cms-lib-util@2.1.2) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.1.0...netlify-cms-lib-util@2.1.1) (2018-11-29) - -**Note:** Version bump only for package netlify-cms-lib-util - - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.0.5...netlify-cms-lib-util@2.1.0) (2018-09-06) - - -### Bug Fixes - -* remove alert modal from localForage error case ([#1676](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/1676)) ([4f3116d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/4f3116d)) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/commit/0596904)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.0.4...netlify-cms-lib-util@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-lib-util - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.0.3...netlify-cms-lib-util@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-lib-util - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.0.2...netlify-cms-lib-util@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-lib-util - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util/compare/netlify-cms-lib-util@2.0.1...netlify-cms-lib-util@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-lib-util - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - -### Bug Fixes - -* **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/netlify/netlify-cms/issues/1522)) ([bdfd944](https://github.com/netlify/netlify-cms/commit/bdfd944)) diff --git a/packages/netlify-cms-lib-util/README.md b/packages/netlify-cms-lib-util/README.md deleted file mode 100644 index 66712c8b..00000000 --- a/packages/netlify-cms-lib-util/README.md +++ /dev/null @@ -1,22 +0,0 @@ -# Lib Util - -Shared utilities to handle various `netlify-cms-backend-*` backends operations. - -## Code structure - -This structure should be the same for backends. - -At first, look at `Implementation`. This is File Management System API and has factory method for `AuthComponent`. - -### File Management System API - -An abstraction layer between the CMS and Git-repository manager API. - -Used as backend in [cms-core](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-core/README.md). - -### Low-level abstractions for Git-repository manager API: - -- `API` - used for Entry files -- `git-lfs` - used for Media files -- and over halpful utilities - diff --git a/packages/netlify-cms-lib-util/package.json b/packages/netlify-cms-lib-util/package.json deleted file mode 100644 index 57c43633..00000000 --- a/packages/netlify-cms-lib-util/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "netlify-cms-lib-util", - "description": "Shared utilities for Netlify CMS.", - "version": "2.15.3", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-util", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-lib-util.js", - "license": "MIT", - "keywords": [ - "netlify-cms" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "dependencies": { - "js-sha256": "^0.9.0", - "localforage": "^1.7.3", - "semaphore": "^1.1.0" - }, - "peerDependencies": { - "immutable": "^3.7.6", - "lodash": "^4.17.11" - } -} diff --git a/packages/netlify-cms-lib-util/src/__tests__/api.spec.js b/packages/netlify-cms-lib-util/src/__tests__/api.spec.js deleted file mode 100644 index 675ff045..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/api.spec.js +++ /dev/null @@ -1,12 +0,0 @@ -import * as api from '../API'; -describe('Api', () => { - describe('getPreviewStatus', () => { - it('should return preview status on matching context', () => { - expect(api.getPreviewStatus([{ context: 'deploy' }])).toEqual({ context: 'deploy' }); - }); - - it('should return undefined on matching context', () => { - expect(api.getPreviewStatus([{ context: 'other' }])).toBeUndefined(); - }); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/apiUtils.spec.js b/packages/netlify-cms-lib-util/src/__tests__/apiUtils.spec.js deleted file mode 100644 index f5627dcb..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/apiUtils.spec.js +++ /dev/null @@ -1,74 +0,0 @@ -import * as apiUtils from '../APIUtils'; -describe('APIUtils', () => { - describe('generateContentKey', () => { - it('should generate content key', () => { - expect(apiUtils.generateContentKey('posts', 'dir1/dir2/post-title')).toBe( - 'posts/dir1/dir2/post-title', - ); - }); - }); - - describe('parseContentKey', () => { - it('should parse content key', () => { - expect(apiUtils.parseContentKey('posts/dir1/dir2/post-title')).toEqual({ - collection: 'posts', - slug: 'dir1/dir2/post-title', - }); - }); - }); - - describe('isCMSLabel', () => { - it('should return true for CMS label', () => { - expect(apiUtils.isCMSLabel('netlify-cms/draft', 'netlify-cms/')).toBe(true); - }); - - it('should return false for non CMS label', () => { - expect(apiUtils.isCMSLabel('other/label', 'netlify-cms/')).toBe(false); - }); - - it('should return true if the prefix not provided for CMS label', () => { - expect(apiUtils.isCMSLabel('netlify-cms/draft', '')).toBe(true); - }); - - it('should return false if a different prefix provided for CMS label', () => { - expect(apiUtils.isCMSLabel('netlify-cms/draft', 'other/')).toBe(false); - }); - - it('should return true for CMS label when undefined prefix is passed', () => { - expect(apiUtils.isCMSLabel('netlify-cms/draft', undefined)).toBe(true); - }); - }); - - describe('labelToStatus', () => { - it('should get status from label when default prefix is passed', () => { - expect(apiUtils.labelToStatus('netlify-cms/draft', 'netlify-cms/')).toBe('draft'); - }); - - it('should get status from label when custom prefix is passed', () => { - expect(apiUtils.labelToStatus('other/draft', 'other/')).toBe('draft'); - }); - - it('should get status from label when empty prefix is passed', () => { - expect(apiUtils.labelToStatus('netlify-cms/draft', '')).toBe('draft'); - }); - - it('should get status from label when undefined prefix is passed', () => { - expect(apiUtils.labelToStatus('netlify-cms/draft', undefined)).toBe('draft'); - }); - }); - - describe('statusToLabel', () => { - it('should generate label from status when default prefix is passed', () => { - expect(apiUtils.statusToLabel('draft', 'netlify-cms/')).toBe('netlify-cms/draft'); - }); - it('should generate label from status when custom prefix is passed', () => { - expect(apiUtils.statusToLabel('draft', 'other/')).toBe('other/draft'); - }); - it('should generate label from status when empty prefix is passed', () => { - expect(apiUtils.statusToLabel('draft', '')).toBe('netlify-cms/draft'); - }); - it('should generate label from status when undefined prefix is passed', () => { - expect(apiUtils.statusToLabel('draft', undefined)).toBe('netlify-cms/draft'); - }); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/asyncLock.spec.js b/packages/netlify-cms-lib-util/src/__tests__/asyncLock.spec.js deleted file mode 100644 index 69a780fe..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/asyncLock.spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import { asyncLock } from '../asyncLock'; - -jest.useFakeTimers(); -jest.spyOn(console, 'warn').mockImplementation(() => {}); - -describe('asyncLock', () => { - it('should be able to acquire a new lock', async () => { - const lock = asyncLock(); - - const acquired = await lock.acquire(); - - expect(acquired).toBe(true); - }); - - it('should not be able to acquire an acquired lock', async () => { - const lock = asyncLock(); - await lock.acquire(); - - const promise = lock.acquire(); - - // advance by default lock timeout - jest.advanceTimersByTime(15000); - - const acquired = await promise; - - expect(acquired).toBe(false); - }); - - it('should be able to acquire an acquired lock that was released', async () => { - const lock = asyncLock(); - await lock.acquire(); - - const promise = lock.acquire(); - - // release the lock in the "future" - setTimeout(() => lock.release(), 100); - - // advance to the time where the lock will be released - jest.advanceTimersByTime(100); - - const acquired = await promise; - - expect(acquired).toBe(true); - }); - - it('should accept a timeout for acquire', async () => { - const lock = asyncLock(); - await lock.acquire(); - - const promise = lock.acquire(50); - - /// advance by lock timeout - jest.advanceTimersByTime(50); - - const acquired = await promise; - - expect(acquired).toBe(false); - }); - - it('should be able to re-acquire a lock after a timeout', async () => { - const lock = asyncLock(); - await lock.acquire(); - - const promise = lock.acquire(); - - // advance by default lock timeout - jest.advanceTimersByTime(15000); - - let acquired = await promise; - - expect(acquired).toBe(false); - - acquired = await lock.acquire(); - expect(acquired).toBe(true); - }); - - it('should suppress "leave called too many times" error', async () => { - const lock = asyncLock(); - - await expect(() => lock.release()).not.toThrow(); - - expect(console.warn).toHaveBeenCalledTimes(1); - expect(console.warn).toHaveBeenCalledWith('leave called too many times.'); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/backendUtil.spec.js b/packages/netlify-cms-lib-util/src/__tests__/backendUtil.spec.js deleted file mode 100644 index 2da2fbea..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/backendUtil.spec.js +++ /dev/null @@ -1,97 +0,0 @@ -import { oneLine } from 'common-tags'; -import nock from 'nock'; - -import { parseLinkHeader, getAllResponses, getPathDepth, filterByExtension } from '../backendUtil'; - -describe('parseLinkHeader', () => { - it('should return the right rel urls', () => { - const url = 'https://api.github.com/resource'; - const link = oneLine` - <${url}?page=1>; rel="first", - <${url}?page=2>; rel="prev", - <${url}?page=4>; rel="next", - <${url}?page=5>; rel="last" - `; - const linkHeader = parseLinkHeader(link); - - expect(linkHeader.next).toBe(`${url}?page=4`); - expect(linkHeader.last).toBe(`${url}?page=5`); - expect(linkHeader.first).toBe(`${url}?page=1`); - expect(linkHeader.prev).toBe(`${url}?page=2`); - }); -}); - -describe('getAllResponses', () => { - function generatePulls(length) { - return Array.from({ length }, (_, id) => { - return { id: id + 1, number: `134${id}`, state: 'open' }; - }); - } - - function createLinkHeaders({ page, pageCount }) { - const pageNum = parseInt(page, 10); - const pageCountNum = parseInt(pageCount, 10); - const url = 'https://api.github.com/pulls'; - - function link(linkPage) { - return `<${url}?page=${linkPage}>`; - } - - const linkHeader = oneLine` - ${pageNum === 1 ? '' : `${link(1)}; rel="first",`} - ${pageNum === pageCountNum ? '' : `${link(pageCount)}; rel="last",`} - ${pageNum === 1 ? '' : `${link(pageNum - 1)}; rel="prev",`} - ${pageNum === pageCountNum ? '' : `${link(pageNum + 1)}; rel="next",`} - `.slice(0, -1); - - return { Link: linkHeader }; - } - - function interceptCall({ perPage = 30, repeat = 1, data = [] } = {}) { - nock('https://api.github.com') - .get('/pulls') - .query(true) - .times(repeat) - .reply(uri => { - const searchParams = new URLSearchParams(uri.split('?')[1]); - const page = searchParams.get('page') || 1; - const pageCount = data.length <= perPage ? 1 : Math.ceil(data.length / perPage); - const pageLastIndex = page * perPage; - const pageFirstIndex = pageLastIndex - perPage; - const resp = data.slice(pageFirstIndex, pageLastIndex); - return [200, resp, createLinkHeaders({ page, pageCount })]; - }); - } - - it('should return all paged response', async () => { - interceptCall({ repeat: 3, data: generatePulls(70) }); - const res = await getAllResponses('https://api.github.com/pulls', {}, 'next', url => url); - const pages = await Promise.all(res.map(res => res.json())); - - expect(pages[0]).toHaveLength(30); - expect(pages[1]).toHaveLength(30); - expect(pages[2]).toHaveLength(10); - }); -}); - -describe('getPathDepth', () => { - it('should return 1 for empty string', () => { - expect(getPathDepth('')).toBe(1); - }); - - it('should return 2 for path of one nested folder', () => { - expect(getPathDepth('{{year}}/{{slug}}')).toBe(2); - }); -}); - -describe('filterByExtension', () => { - it('should return true when extension matches', () => { - expect(filterByExtension({ path: 'file.html.md' }, '.html.md')).toBe(true); - expect(filterByExtension({ path: 'file.html.md' }, 'html.md')).toBe(true); - }); - - it("should return false when extension doesn't match", () => { - expect(filterByExtension({ path: 'file.json' }, '.html.md')).toBe(false); - expect(filterByExtension({ path: 'file.json' }, 'html.md')).toBe(false); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/implementation.spec.js b/packages/netlify-cms-lib-util/src/__tests__/implementation.spec.js deleted file mode 100644 index 633dbcf7..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/implementation.spec.js +++ /dev/null @@ -1,58 +0,0 @@ -import { getMediaAsBlob, getMediaDisplayURL } from '../implementation'; - -describe('implementation', () => { - describe('getMediaAsBlob', () => { - it('should return response blob on non svg file', async () => { - const blob = {}; - const readFile = jest.fn().mockResolvedValue(blob); - - await expect(getMediaAsBlob('static/media/image.png', 'sha', readFile)).resolves.toBe(blob); - - expect(readFile).toHaveBeenCalledTimes(1); - expect(readFile).toHaveBeenCalledWith('static/media/image.png', 'sha', { - parseText: false, - }); - }); - - it('should return text blob on svg file', async () => { - const text = 'svg'; - const readFile = jest.fn().mockResolvedValue(text); - - await expect(getMediaAsBlob('static/media/logo.svg', 'sha', readFile)).resolves.toEqual( - new Blob([text], { type: 'image/svg+xml' }), - ); - - expect(readFile).toHaveBeenCalledTimes(1); - expect(readFile).toHaveBeenCalledWith('static/media/logo.svg', 'sha', { - parseText: true, - }); - }); - }); - - describe('getMediaDisplayURL', () => { - it('should return createObjectURL result', async () => { - const blob = {}; - const readFile = jest.fn().mockResolvedValue(blob); - const semaphore = { take: jest.fn(callback => callback()), leave: jest.fn() }; - - global.URL.createObjectURL = jest - .fn() - .mockResolvedValue('blob:http://localhost:8080/blob-id'); - - await expect( - getMediaDisplayURL({ path: 'static/media/image.png', id: 'sha' }, readFile, semaphore), - ).resolves.toBe('blob:http://localhost:8080/blob-id'); - - expect(semaphore.take).toHaveBeenCalledTimes(1); - expect(semaphore.leave).toHaveBeenCalledTimes(1); - - expect(readFile).toHaveBeenCalledTimes(1); - expect(readFile).toHaveBeenCalledWith('static/media/image.png', 'sha', { - parseText: false, - }); - - expect(global.URL.createObjectURL).toHaveBeenCalledTimes(1); - expect(global.URL.createObjectURL).toHaveBeenCalledWith(blob); - }); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/path.spec.js b/packages/netlify-cms-lib-util/src/__tests__/path.spec.js deleted file mode 100644 index 0d296541..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/path.spec.js +++ /dev/null @@ -1,53 +0,0 @@ -import { fileExtensionWithSeparator, fileExtension } from '../path'; - -describe('fileExtensionWithSeparator', () => { - it('should return the extension of a file', () => { - expect(fileExtensionWithSeparator('index.html')).toEqual('.html'); - }); - - it('should return the extension of a file path', () => { - expect(fileExtensionWithSeparator('/src/main/index.html')).toEqual('.html'); - }); - - it('should return the extension of a file path with trailing slash', () => { - expect(fileExtensionWithSeparator('/src/main/index.html/')).toEqual('.html'); - }); - - it('should return the extension for an extension with two ..', () => { - expect(fileExtensionWithSeparator('/src/main/index..html')).toEqual('.html'); - }); - - it('should return an empty string for the parent path ..', () => { - expect(fileExtensionWithSeparator('..')).toEqual(''); - }); - - it('should return an empty string if the file has no extension', () => { - expect(fileExtensionWithSeparator('/src/main/index')).toEqual(''); - }); -}); - -describe('fileExtension', () => { - it('should return the extension of a file', () => { - expect(fileExtension('index.html')).toEqual('html'); - }); - - it('should return the extension of a file path', () => { - expect(fileExtension('/src/main/index.html')).toEqual('html'); - }); - - it('should return the extension of a file path with trailing slash', () => { - expect(fileExtension('/src/main/index.html/')).toEqual('html'); - }); - - it('should return the extension for an extension with two ..', () => { - expect(fileExtension('/src/main/index..html')).toEqual('html'); - }); - - it('should return an empty string for the parent path ..', () => { - expect(fileExtension('..')).toEqual(''); - }); - - it('should return an empty string if the file has no extension', () => { - expect(fileExtension('/src/main/index')).toEqual(''); - }); -}); diff --git a/packages/netlify-cms-lib-util/src/__tests__/unsentRequest.spec.js b/packages/netlify-cms-lib-util/src/__tests__/unsentRequest.spec.js deleted file mode 100644 index 91138925..00000000 --- a/packages/netlify-cms-lib-util/src/__tests__/unsentRequest.spec.js +++ /dev/null @@ -1,19 +0,0 @@ -import unsentRequest from '../unsentRequest'; - -describe('unsentRequest', () => { - describe('withHeaders', () => { - it('should create new request with headers', () => { - expect(unsentRequest.withHeaders({ Authorization: 'token' })('path').toJS()).toEqual({ - url: 'path', - headers: { Authorization: 'token' }, - }); - }); - - it('should add headers to existing request', () => { - expect(unsentRequest.withHeaders({ Authorization: 'token' }, 'path').toJS()).toEqual({ - url: 'path', - headers: { Authorization: 'token' }, - }); - }); - }); -}); diff --git a/packages/netlify-cms-lib-util/webpack.config.js b/packages/netlify-cms-lib-util/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-lib-util/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-lib-widgets/CHANGELOG.md b/packages/netlify-cms-lib-widgets/CHANGELOG.md deleted file mode 100644 index ee20c32b..00000000 --- a/packages/netlify-cms-lib-widgets/CHANGELOG.md +++ /dev/null @@ -1,150 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.8.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-widgets@1.8.0...netlify-cms-lib-widgets@1.8.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-lib-widgets - - - - - -# [1.8.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-widgets@1.7.0...netlify-cms-lib-widgets@1.8.0) (2022-01-21) - - -### Features - -* add truncate filter to summary tag ([#6105](https://github.com/netlify/netlify-cms/issues/6105)) ([d66c573](https://github.com/netlify/netlify-cms/commit/d66c573697c6a66919e048f0fde9cf2f8ea6acac)) - - - - - -# [1.7.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-lib-widgets@1.6.3...netlify-cms-lib-widgets@1.7.0) (2021-10-11) - - -### Features - -* add string template filters "default" and "ternary" ([#3677](https://github.com/netlify/netlify-cms/issues/3677)) ([#5878](https://github.com/netlify/netlify-cms/issues/5878)) ([c791158](https://github.com/netlify/netlify-cms/commit/c791158dd5ea8ea03930f9881a86c71cb1770836)) - - - - - -## [1.6.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.6.2...netlify-cms-lib-widgets@1.6.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-lib-widgets - - - - - -## [1.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.6.1...netlify-cms-lib-widgets@1.6.2) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-lib-widgets - - - - - -## [1.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.6.0...netlify-cms-lib-widgets@1.6.1) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-lib-widgets - - - - - -# [1.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.5.0...netlify-cms-lib-widgets@1.6.0) (2020-10-25) - - -### Features - -* Support filters for template strings [#3677](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/3677) ([#4396](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/4396)) ([1fa108e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/1fa108ee67b7e992a4d2a61cde13df7917e103be)) - - - - - -# [1.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.4.0...netlify-cms-lib-widgets@1.5.0) (2020-10-20) - - -### Features - -* **widget-list:** add min max configuration ([#4394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/4394)) ([5fdfe40](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/5fdfe40dd29e9e22c9ae7d6219bc057f7ea7280b)) - - - - - -# [1.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.3.5...netlify-cms-lib-widgets@1.4.0) (2020-09-28) - - -### Features - -* **core:** Add {{dirname}} to summary and preview_path ([#4279](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/4279)) ([576e4f0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/576e4f0f1a158d6b587587c52fb288d8f6eea89f)) - - - - - -## [1.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.3.4...netlify-cms-lib-widgets@1.3.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-lib-widgets - - - - - -## 1.3.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.3.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.3.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [1.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/compare/netlify-cms-lib-widgets@1.3.0...netlify-cms-lib-widgets@1.3.1) (2020-07-14) - - -### Bug Fixes - -* relation widget performance ([#3975](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/3975)) ([c7e0fe8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/c7e0fe8492d09a3d151c608f50da844f421362ed)) - - - - - -# 1.3.0 (2020-05-04) - - -### Features - -* **widget-relation:** string templates support ([#3659](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/issues/3659)) ([213ae86](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets/commit/213ae86b54d02f5fc79fe11113507587ed062ff2)) diff --git a/packages/netlify-cms-lib-widgets/README.md b/packages/netlify-cms-lib-widgets/README.md deleted file mode 100644 index 5daf1a56..00000000 --- a/packages/netlify-cms-lib-widgets/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-lib-widgets/README.md)! diff --git a/packages/netlify-cms-lib-widgets/package.json b/packages/netlify-cms-lib-widgets/package.json deleted file mode 100644 index 6ee832cf..00000000 --- a/packages/netlify-cms-lib-widgets/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "netlify-cms-lib-widgets", - "description": "Shared utilities for Netlify CMS.", - "version": "1.8.1", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-lib-widgets", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-lib-widgets.js", - "license": "MIT", - "keywords": [ - "netlify-cms" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward --extensions \".js,.jsx,.ts,.tsx\"" - }, - "peerDependencies": { - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "moment": "^2.24.0" - } -} diff --git a/packages/netlify-cms-lib-widgets/src/__tests__/stringTemplate.spec.js b/packages/netlify-cms-lib-widgets/src/__tests__/stringTemplate.spec.js deleted file mode 100644 index fd164144..00000000 --- a/packages/netlify-cms-lib-widgets/src/__tests__/stringTemplate.spec.js +++ /dev/null @@ -1,241 +0,0 @@ -import { fromJS } from 'immutable'; - -import { - compileStringTemplate, - expandPath, - extractTemplateVars, - keyToPathArray, - parseDateFromEntry, -} from '../stringTemplate'; - -describe('stringTemplate', () => { - describe('keyToPathArray', () => { - it('should return array of length 1 with simple path', () => { - expect(keyToPathArray('category')).toEqual(['category']); - }); - - it('should return path array for complex path', () => { - expect(keyToPathArray('categories[0].title.subtitles[0].welcome[2]')).toEqual([ - 'categories', - '0', - 'title', - 'subtitles', - '0', - 'welcome', - '2', - ]); - }); - }); - - describe('parseDateFromEntry', () => { - it('should return date based on dateFieldName', () => { - const date = new Date().toISOString(); - const dateFieldName = 'dateFieldName'; - const entry = fromJS({ data: { dateFieldName: date } }); - expect(parseDateFromEntry(entry, dateFieldName).toISOString()).toBe(date); - }); - - it('should return undefined on empty dateFieldName', () => { - const entry = fromJS({ data: {} }); - expect(parseDateFromEntry(entry, '')).toBeUndefined(); - expect(parseDateFromEntry(entry, null)).toBeUndefined(); - expect(parseDateFromEntry(entry, undefined)).toBeUndefined(); - }); - - it('should return undefined on invalid date', () => { - const entry = fromJS({ data: { date: '' } }); - const dateFieldName = 'date'; - expect(parseDateFromEntry(entry, dateFieldName)).toBeUndefined(); - }); - }); - - describe('extractTemplateVars', () => { - it('should extract template variables', () => { - expect(extractTemplateVars('{{slug}}-hello-{{date}}-world-{{fields.id}}')).toEqual([ - 'slug', - 'date', - 'fields.id', - ]); - }); - - it('should return empty array on no matches', () => { - expect(extractTemplateVars('hello-world')).toEqual([]); - }); - }); - - describe('compileStringTemplate', () => { - const date = new Date('2020-01-02T13:28:27.679Z'); - it('should compile year variable', () => { - expect(compileStringTemplate('{{year}}', date)).toBe('2020'); - }); - - it('should compile month variable', () => { - expect(compileStringTemplate('{{month}}', date)).toBe('01'); - }); - - it('should compile day variable', () => { - expect(compileStringTemplate('{{day}}', date)).toBe('02'); - }); - - it('should compile hour variable', () => { - expect(compileStringTemplate('{{hour}}', date)).toBe('13'); - }); - - it('should compile minute variable', () => { - expect(compileStringTemplate('{{minute}}', date)).toBe('28'); - }); - - it('should compile second variable', () => { - expect(compileStringTemplate('{{second}}', date)).toBe('27'); - }); - - it('should error on missing date', () => { - expect(() => compileStringTemplate('{{year}}')).toThrowError(); - }); - - it('return compiled template', () => { - expect( - compileStringTemplate( - '{{slug}}-{{year}}-{{fields.slug}}-{{title}}-{{date}}', - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', title: 'title', date }), - ), - ).toBe('backendSlug-2020-entrySlug-title-' + date.toString()); - }); - - it('return apply processor to values', () => { - expect( - compileStringTemplate('{{slug}}', date, 'slug', fromJS({}), value => value.toUpperCase()), - ).toBe('SLUG'); - }); - - it('return apply filter to values', () => { - expect( - compileStringTemplate( - '{{slug | upper}}-{{title | lower}}-{{year}}', - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', title: 'Title', date }), - ), - ).toBe('BACKENDSLUG-title-2020'); - }); - - it('return apply filter to date field', () => { - expect( - compileStringTemplate( - "{{slug | upper}}-{{title | lower}}-{{published | date('MM-DD')}}-{{year}}", - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', title: 'Title', published: date, date }), - ), - ).toBe('BACKENDSLUG-title-01-02-2020'); - }); - - it('return apply filter for default value', () => { - expect( - compileStringTemplate( - "{{slug | upper}}-{{title | default('none')}}-{{subtitle | default('none')}}", - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', title: 'title', subtitle: null, published: date, date }), - ), - ).toBe('BACKENDSLUG-title-none'); - }); - - it('return apply filter for ternary', () => { - expect( - compileStringTemplate( - "{{slug | upper}}-{{starred | ternary('star️','nostar')}}-{{done | ternary('done', 'open️')}}", - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', starred: true, done: false }), - ), - ).toBe('BACKENDSLUG-star️-open️'); - }); - - it('return apply filter for truncate', () => { - expect( - compileStringTemplate( - '{{slug | truncate(6)}}', - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', starred: true, done: false }), - ), - ).toBe('backen...'); - }); - - it('return apply filter for truncate', () => { - expect( - compileStringTemplate( - "{{slug | truncate(3,'***')}}", - date, - 'backendSlug', - fromJS({ slug: 'entrySlug', starred: true, done: false }), - ), - ).toBe('bac***'); - }); - }); - - describe('expandPath', () => { - it('should expand wildcard paths', () => { - const data = { - categories: [ - { - name: 'category 1', - }, - { - name: 'category 2', - }, - ], - }; - - expect(expandPath({ data, path: 'categories.*.name' })).toEqual([ - 'categories.0.name', - 'categories.1.name', - ]); - }); - - it('should handle wildcard at the end of the path', () => { - const data = { - nested: { - otherNested: { - list: [ - { - title: 'title 1', - nestedList: [{ description: 'description 1' }, { description: 'description 2' }], - }, - { - title: 'title 2', - nestedList: [{ description: 'description 2' }, { description: 'description 2' }], - }, - ], - }, - }, - }; - - expect(expandPath({ data, path: 'nested.otherNested.list.*.nestedList.*' })).toEqual([ - 'nested.otherNested.list.0.nestedList.0', - 'nested.otherNested.list.0.nestedList.1', - 'nested.otherNested.list.1.nestedList.0', - 'nested.otherNested.list.1.nestedList.1', - ]); - }); - - it('should handle non wildcard index', () => { - const data = { - categories: [ - { - name: 'category 1', - }, - { - name: 'category 2', - }, - ], - }; - const path = 'categories.0.name'; - - expect(expandPath({ data, path })).toEqual(['categories.0.name']); - }); - }); -}); diff --git a/packages/netlify-cms-lib-widgets/webpack.config.js b/packages/netlify-cms-lib-widgets/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-lib-widgets/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-locales/CHANGELOG.md b/packages/netlify-cms-locales/CHANGELOG.md deleted file mode 100644 index ea8e6871..00000000 --- a/packages/netlify-cms-locales/CHANGELOG.md +++ /dev/null @@ -1,811 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -# [1.39.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.38.2...netlify-cms-locales@1.39.0) (2022-03-28) - - -### Features - -* **image-widget:** media library gallery tools ([#6087](https://github.com/netlify/netlify-cms/issues/6087)) ([#6236](https://github.com/netlify/netlify-cms/issues/6236)) ([80c577a](https://github.com/netlify/netlify-cms/commit/80c577a462e91e29ce3517cf1419af35d9de3928)) - - - - - -## [1.38.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.38.1...netlify-cms-locales@1.38.2) (2022-02-08) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -## [1.38.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.38.0...netlify-cms-locales@1.38.1) (2021-12-03) - - -### Bug Fixes - -* **locale-hr:** fix typos ([0191f25](https://github.com/netlify/netlify-cms/commit/0191f25c51ef66292c920a93078697643c8dd68b)) -* **locale-tr:** fixe locales and added new ones. ([#6010](https://github.com/netlify/netlify-cms/issues/6010)) ([fdd9ec3](https://github.com/netlify/netlify-cms/commit/fdd9ec354d2ea3d9a2705e11119ee87b8ea96af5)) - - - - - -# [1.38.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.37.0...netlify-cms-locales@1.38.0) (2021-11-12) - - -### Features - -* **locales:** add Hebrew translation ([#5903](https://github.com/netlify/netlify-cms/issues/5903)) ([928ea9b](https://github.com/netlify/netlify-cms/commit/928ea9b5c97ef643b63aa7e6bffa8d8cac88a741)) - - - - - -# [1.37.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.36.2...netlify-cms-locales@1.37.0) (2021-11-01) - - -### Features - -* **locales:** allow copying data from other locales ([#5850](https://github.com/netlify/netlify-cms/issues/5850)) ([#5881](https://github.com/netlify/netlify-cms/issues/5881)) ([5e2d181](https://github.com/netlify/netlify-cms/commit/5e2d1814981e2c09762b18d9ff66d1fefcbe73b3)) - - - - - -## [1.36.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.36.1...netlify-cms-locales@1.36.2) (2021-10-11) - - -### Bug Fixes - -* **locale-de:** add missing German translations ([#5882](https://github.com/netlify/netlify-cms/issues/5882)) ([a6f3f3f](https://github.com/netlify/netlify-cms/commit/a6f3f3f97ec14b2fc841de43c188dfcb96f9a1ee)) - - - - - -## [1.36.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.36.0...netlify-cms-locales@1.36.1) (2021-10-07) - - -### Bug Fixes - -* remove redundant 'item' text from typed list ([#5866](https://github.com/netlify/netlify-cms/issues/5866)) ([5ccd9e2](https://github.com/netlify/netlify-cms/commit/5ccd9e26cbeb2c43de7fcea436f1a2f6c5e5590d)) - - - - - -# [1.36.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.35.1...netlify-cms-locales@1.36.0) (2021-10-07) - - -### Features - -* add missing pt locale translations ([#5868](https://github.com/netlify/netlify-cms/issues/5868)) ([96a89ee](https://github.com/netlify/netlify-cms/commit/96a89eeac8242660f627157456d0f054d9194aa2)) -* **locale-nl:** add translation ([#5869](https://github.com/netlify/netlify-cms/issues/5869)) ([6d4ecbc](https://github.com/netlify/netlify-cms/commit/6d4ecbc33e40a28e3262f3667f02f0a3b8be8cd9)) - - - - - -## [1.35.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.35.0...netlify-cms-locales@1.35.1) (2021-09-29) - - -### Bug Fixes - -* **translations:** correct catalan locale ([#5836](https://github.com/netlify/netlify-cms/issues/5836)) ([75e10ae](https://github.com/netlify/netlify-cms/commit/75e10aee5af30dda79297cbfe93b57c15f980592)) - - - - - -# [1.35.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.34.0...netlify-cms-locales@1.35.0) (2021-08-24) - - -### Features - -* **locale-pl:** update index.js pl ([#5748](https://github.com/netlify/netlify-cms/issues/5748)) ([289d766](https://github.com/netlify/netlify-cms/commit/289d76699bc8dd0549ae29d2ca59f447812afc8e)) - - - - - -# [1.34.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.33.2...netlify-cms-locales@1.34.0) (2021-08-11) - - -### Features - -* update locale ja ([#5703](https://github.com/netlify/netlify-cms/issues/5703)) ([8578f33](https://github.com/netlify/netlify-cms/commit/8578f331329a29810457ccaa1266f3dd8be15985)) - - - - - -## [1.33.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.33.1...netlify-cms-locales@1.33.2) (2021-08-09) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -## [1.33.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.33.0...netlify-cms-locales@1.33.1) (2021-08-04) - - -### Bug Fixes - -* **widget-list:** add missing translations in widget list top bar ([#5471](https://github.com/netlify/netlify-cms/issues/5471)) ([#5679](https://github.com/netlify/netlify-cms/issues/5679)) ([db560cc](https://github.com/netlify/netlify-cms/commit/db560cc082fcc0a9842919e28f715e44a6e4625a)) - - - - - -# [1.33.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.32.0...netlify-cms-locales@1.33.0) (2021-07-07) - - -### Features - -* show current status in status button ([#5574](https://github.com/netlify/netlify-cms/issues/5574)) ([fbc3728](https://github.com/netlify/netlify-cms/commit/fbc3728294b7eb23fb65cb47b3892c92d39b8148)) - - - - - -# [1.32.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-locales@1.31.0...netlify-cms-locales@1.32.0) (2021-07-06) - - -### Features - -* **open-authoring:** add hover tooltip ([#5567](https://github.com/netlify/netlify-cms/issues/5567)) ([1822815](https://github.com/netlify/netlify-cms/commit/1822815118b9d35fce8e65a8424f2cb748253ac3)) - - - - - -# [1.31.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.30.2...netlify-cms-locales@1.31.0) (2021-06-07) - - -### Features - -* updating czech translation ([#5473](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5473)) ([e249f9f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e249f9f7f7e687b49345cea75b4272e6df791c76)) - - - - - -## [1.30.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.30.1...netlify-cms-locales@1.30.2) (2021-05-30) - - -### Bug Fixes - -* **locales-nb_no:** fix spelling in deleteEntry ([#5442](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5442)) ([f296e40](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/f296e40d6fc4399c3b898799b4e008d4d04aceba)) - - - - - -## [1.30.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.30.0...netlify-cms-locales@1.30.1) (2021-05-04) - - -### Bug Fixes - -* **locale:** add missing keys to 'sv' locale ([#5341](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5341)) ([7f7fa40](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/7f7fa401ad83620b7f90205b8bd1f7b658cc53ad)) - - - - - -# [1.30.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.29.2...netlify-cms-locales@1.30.0) (2021-04-13) - - -### Features - -* add min and max fields to relation widget (resolves [#5026](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5026)) ([#5238](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5238)) ([fe117e4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/fe117e472e18079e4f65ca2dfa5c258040cf93f9)) - - - - - -## [1.29.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.29.1...netlify-cms-locales@1.29.2) (2021-04-07) - - -### Bug Fixes - -* **locale-ca:** update Catalan translation ([#5222](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5222)) ([3211f94](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/3211f94f4ae55cc008bc28325a5387722657cd2c)) - - - - - -## [1.29.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.29.0...netlify-cms-locales@1.29.1) (2021-03-31) - - -### Bug Fixes - -* **locale-nl:** Add missing locales ([#5192](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5192)) ([2f67f19](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/2f67f1963641297bc28499c52095cd53aeb74d87)) - - - - - -# [1.29.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.28.0...netlify-cms-locales@1.29.0) (2021-03-18) - - -### Features - -* **locale:** add zh_Hans locale ([#5132](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5132)) ([e2ad39c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e2ad39cb4959e2676eb87e58ecf4d065037b73c4)) -* **locale:** Added Romanian Locale ([#5128](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5128)) ([69f145b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/69f145b7470f3e17f424512b6c80786e20fde711)) - - - - - -# [1.28.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.27.0...netlify-cms-locales@1.28.0) (2021-03-10) - - -### Features - -* update locale (ja) ([#5084](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5084)) ([bebf4a8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/bebf4a80b6d18dc50981da6b4546151c78c0fd5b)) -* **locale:** add bulgarian locale ([#5054](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/5054)) ([776e2a2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/776e2a2a8dda489644c1630c7c64ccba61edcfd5)) - - - - - -# [1.27.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.26.0...netlify-cms-locales@1.27.0) (2021-02-10) - - -### Bug Fixes - -* **locale-fr:** change translation + missing ? ([#4944](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4944)) ([79f5a07](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/79f5a0719fdcfb33d47435ca62b714b1f1a6b186)) - - -### Features - -* **locale:** Make editor interface buttons translatable ([#4938](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4938)) ([c023653](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/c0236536ddec23216de9554f859339cd6eb7c553)) - - - - - -# [1.26.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.25.0...netlify-cms-locales@1.26.0) (2021-02-07) - - -### Features - -* **locale-fr:** add missing translations ([#4921](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4921)) ([7e2ce1a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/7e2ce1ab6f708423cd0ad53125384e35eb3bc04b)) -* **locale-ru:** add missing translations ([#4922](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4922)) ([e481e6e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e481e6e296b907c4926209edbdd8bc1ca2252fe9)) - - - - - -# [1.25.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.24.0...netlify-cms-locales@1.25.0) (2021-02-03) - - -### Features - -* **media-library:** add copy to clipboard, allow avif ([#4914](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4914)) ([4b73e11](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/4b73e11db0627f4046d5e23e2fa3b53b3f6788de)) - - - - - -# [1.24.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.23.1...netlify-cms-locales@1.24.0) (2021-01-14) - - -### Features - -* **widget-file:** allow adding file from url ([#4700](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4700)) ([9e277ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/9e277ad851ea598405e02a7c11624f337da18260)) - - - - - -## [1.23.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.23.0...netlify-cms-locales@1.23.1) (2021-01-12) - - -### Bug Fixes - -* **locale:** fix typos in es locales ([#4815](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4815)) ([923eaf0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/923eaf0083c430ad2565771b1c3890c4dbb11d49)) - - - - - -# [1.23.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.22.0...netlify-cms-locales@1.23.0) (2021-01-05) - - -### Bug Fixes - -* **locales-de:** fix newButton translation ([#4778](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4778)) ([#4801](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4801)) ([567438f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/567438fdd1aa775fd09a6a5de13e79c9d783e0d6)) - - -### Features - -* **locales:** add Croatian translation ([#4775](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4775)) ([a92d53f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/a92d53f88914fb73dd109686ee28c6240432f690)) - - - - - -# [1.22.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.21.0...netlify-cms-locales@1.22.0) (2020-12-23) - - -### Features - -* **locales:** add Lithuanian translation ([#4761](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4761)) ([18444cb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/18444cb839bb1599636fd300d5747796ba54648c)) - - - - - -# [1.21.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.20.0...netlify-cms-locales@1.21.0) (2020-11-30) - - -### Features - -* **locales:** add danish translation ([#4650](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4650)) ([90dd831](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/90dd8312d1b6fa39d3c7eec7dfac1a7f31326a00)) - - - - - -# [1.20.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.19.0...netlify-cms-locales@1.20.0) (2020-11-26) - - -### Features - -* add azure devops backend ([#4427](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4427)) ([4e6dc88](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/4e6dc88efb1dae4cf6137730c3b4fb6d0f75a8cc)) - - - - - -# [1.19.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.18.3...netlify-cms-locales@1.19.0) (2020-11-08) - - -### Features - -* Add `group by` to collection view (Issue 3614) ([#4486](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4486)) ([e52e290](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e52e29034ec508e1b371e4a2a733418f0c813e60)) - - - - - -## [1.18.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.18.2...netlify-cms-locales@1.18.3) (2020-10-20) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#4432](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4432)) ([a5750d7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/a5750d782e9b4f0060362459037086f4d2f18acf)) -* **locale-th:** update translations ([#4458](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4458)) ([471e879](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/471e879b782dcaf0229995c1b6581e4e16a28ed0)) - - - - - -## [1.18.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.18.1...netlify-cms-locales@1.18.2) (2020-10-12) - - -### Bug Fixes - -* **locale:** update zh_Hant translation ([#4418](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4418)) ([277a151](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/277a1519bed31145910a67e22e0f51c46e8e2006)) -* **locales:** update 'th' locale ([#4421](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4421)) ([e987922](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e987922fd332aa2f41b6025700f021039102a134)) - - - - - -## [1.18.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.18.0...netlify-cms-locales@1.18.1) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -# [1.18.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.17.4...netlify-cms-locales@1.18.0) (2020-09-20) - - -### Features - -* add korean(ko) locale ([#4332](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4332)) ([6b35ca4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/6b35ca4e3bdbb50764ff3c76ab189925ceebe54b)) - - - - - -## [1.17.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.17.3...netlify-cms-locales@1.17.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -## 1.17.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.17.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.17.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [1.17.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.16.0...netlify-cms-locales@1.17.0) (2020-07-14) - - -### Features - -* update locale (fr) ([#4002](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/4002)) ([ec58401](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/ec584015005443f3b69022663f7ec0e83847ac10)) -* **locale:** add 'vi' locale 🇻🇳 ([#3981](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3981)) ([f4b2999](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/f4b29998989c7a90a809a6e4e815cbb54dc6a81c)) - - - - - -# [1.16.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.15.0...netlify-cms-locales@1.16.0) (2020-06-18) - - -### Bug Fixes - -* handle token expiry ([#3847](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3847)) ([285c940](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/285c940562548d7bc88de244123ba87ff66fba65)) - - -### Features - -* add backend status down indicator ([#3889](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3889)) ([a50edc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/a50edc70553ad6afa1acee6a51996ad226443f8c)) -* **lang:** add 'th' locale ([#3890](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3890)) ([699526c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/699526c23b0e6ecc7f79da977a93e0d6cf5284d1)) - - - - - -# [1.15.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.14.0...netlify-cms-locales@1.15.0) (2020-06-01) - - -### Bug Fixes - -* **locale:** update translation strings for 'nl' locale ([#3802](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3802)) ([dd7bced](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/dd7bced09eb7db5bfd27c18609fb769a2ec402a4)) - - -### Features - -* add filter to collection view ([#3741](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3741)) ([c28cc0c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/c28cc0c9e7c7bc4bed07c02dfb869b2dedab9aab)) -* **lang:** add norwegian ([#3785](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3785)) ([d3aaf4d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/d3aaf4ddb326efcaffdbcc5af5c0e5c8bcaa36ea)) - - - - - -# [1.14.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.13.0...netlify-cms-locales@1.14.0) (2020-05-19) - - -### Bug Fixes - -* **locale:** Add translation for "download" in mediaLibraryModal ([#3771](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3771)) ([9d6260b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/9d6260bd4b709f95c03ff37587bc2e40485451e5)) -* **locale:** Improve Catalan translation ([#3770](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3770)) ([76b19ea](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/76b19eaca44e435f10fd1cc39ec5a0d2b008950b)) - - -### Features - -* improve search to target single collections ([#3760](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3760)) ([588622a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/588622adb23df53f9a26914446b0982eddf8f15c)) -* **locale:** add 'sv' locale ([#3724](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3724)) ([5c5f390](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/5c5f3905901a014e94b9ed2b2f8d73377432038f)) - - - - - -# [1.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.12.0...netlify-cms-locales@1.13.0) (2020-05-04) - - -### Bug Fixes - -* locale japanese ([#3668](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3668)) ([5b1353d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/5b1353d75580ffd5968f2ed5f1978864bdf13e54)) - - -### Features - -* **locale:** update PT language ([#3669](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3669)) ([b5a242e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/b5a242ec8ed627e7f5e2ce8af454dd1dda1f71cc)) - - - - - -# [1.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.11.0...netlify-cms-locales@1.12.0) (2020-04-20) - - -### Bug Fixes - -* **locale:** add missing translation strings for 'es' locale ([#3626](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3626)) ([f88c83b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/f88c83b97a18d9094240b688739d8b2909f19b0c)) - - -### Features - -* add-download-button closes [#3429](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3429) ([#3609](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3609)) ([cf25260](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/cf252605ad8fee6f3d307302dc50759813ee765c)) - - - - - -# [1.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.10.3...netlify-cms-locales@1.11.0) (2020-04-14) - - -### Features - -* **widget-datetime:** add now to datepicker ([#3484](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3484)) ([79b8469](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/79b8469337dade3bd7472b3f42b826efc7e0987d)) - - - - - -## [1.10.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.10.2...netlify-cms-locales@1.10.3) (2020-04-06) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -## [1.10.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.10.1...netlify-cms-locales@1.10.2) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -## [1.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.10.0...netlify-cms-locales@1.10.1) (2020-03-30) - - -### Bug Fixes - -* **locale:** Fix czech locale ([#3493](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3493)) ([bae6a2b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/bae6a2b68aa5b5cd2cae5dc4f466ce2e4ea49ebc)) -* update error boundary about GitHub issue data ([#3471](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3471)) ([42d60a6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/42d60a644c58e01da72eb16c1cc20d93e0d70e13)) - - - - - -# [1.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.9.4...netlify-cms-locales@1.10.0) (2020-03-13) - - -### Features - -* **catalan-translation:** add catalan translation ([#3412](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3412)) ([66baec4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/66baec4b8f6680d2d2d24e4a8297358d72266dc9)) - - - - - -## [1.9.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.9.3...netlify-cms-locales@1.9.4) (2020-03-12) - - -### Bug Fixes - -* **locale:** Translate headings into german ([#3382](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3382)) ([eb21723](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/eb2172379979764b493aa9d5c933018066868d12)) -* ja locale labels ([#3367](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3367)) ([50837b0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/50837b0068ac8972ce16cbf5f238aa5a2c5bd6e9)) - - - - - -## [1.9.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.9.2...netlify-cms-locales@1.9.3) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -## [1.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.9.1...netlify-cms-locales@1.9.2) (2020-02-22) - - -### Bug Fixes - -* **locale-tr:** fix tr locale ([#3301](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3301)) ([036ea06](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/036ea06d5e2b45731df53489d8a367fd758d04e9)) - - - - - -## [1.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.9.0...netlify-cms-locales@1.9.1) (2020-02-19) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -# [1.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.8.0...netlify-cms-locales@1.9.0) (2020-02-06) - - -### Bug Fixes - -* **locale:** add missing german translations ([#3179](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3179)) ([e6deab0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/e6deab03b9e255d968b4a5e40956712e96eb336e)) -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - -### Features - -* **dutch:** add missing dutch translations ([#3200](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3200)) ([2043c0b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/2043c0b7829dff018fa8835bead55b4b78f0f6d6)) -* **polish:** add missing polish translations ([#3197](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3197)) ([4525936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/4525936136dd0d9d9c9f3ea3e338dfbd0775348f)) - - - - - -# [1.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.7.0...netlify-cms-locales@1.8.0) (2020-02-01) - - -### Bug Fixes - -* **locale-pt:** typo fix for `backCollection` pt ([#3170](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3170)) ([67e5fd2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/67e5fd2aaf74ccbcfa088c7f33d41e7f7edf816f)) - - -### Features - -* **select-widget:** add min/max validation ([#3171](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3171)) ([fd9e2c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/fd9e2c89f23d73aa08dbfa4412c4c0bae318125b)) - - - - - -# [1.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.6.0...netlify-cms-locales@1.7.0) (2020-01-29) - - -### Features - -* **locale:** add italian localization ([#3141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3141)) ([dc403e4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/dc403e4a82cc79c10f431dc55431b25fc68024a6)) - - - - - -# [1.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.5.0...netlify-cms-locales@1.6.0) (2020-01-21) - - -### Features - -* **locale:** add czech localization ([#3108](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3108)) ([0755f90](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/0755f90142525d94158c1d112a5549e21eef77c2)) -* **locale:** add Greek translation ([#3107](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3107)) ([ee02cf6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/ee02cf61ad5d256fe2b8074b2822bc37067027c9)) - - - - - -# [1.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.4.1...netlify-cms-locales@1.5.0) (2020-01-14) - - -### Features - -* **lang:** add 'zh_Hant' locale ([#3068](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3068)) ([857a414](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/857a414e3d87e7bb707a8eab2469aa80dfcd35df)) - - - - - -## [1.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.4.0...netlify-cms-locales@1.4.1) (2020-01-09) - - -### Bug Fixes - -* **locale-tr:** fix tr locale ([#3047](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3047)) ([62e1b82](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/62e1b823fcae0af297ff565742735b6d56f0d0ed)) - - - - - -# [1.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.3.0...netlify-cms-locales@1.4.0) (2020-01-07) - - -### Bug Fixes - -* **locale-pt:** add missing pt locale import ([#3029](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3029)) ([8bf01e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/8bf01e8022aa20532f5058bc423acb2a82fa6877)) -* **locales:** fix ja locale ([#3041](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3041)) ([2edc713](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/2edc7136e7f4597328a4aa50a5a4e9b3d5623b38)) - - -### Features - -* **backend-git-gateway:** handle identity disabled error message ([#3002](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3002)) ([b5ffccd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/b5ffccdac506db416c09aaebb38611783487c52a)) -* **lang:** add 'pt' locale ([#3015](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/3015)) ([99169ed](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/99169ed8f74c24fec83c2ecc1dc5df2bd1dc95e4)) - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.3.0-beta.2...netlify-cms-locales@1.3.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-locales - - - - - -# [1.3.0-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.3.0-beta.1...netlify-cms-locales@1.3.0-beta.2) (2019-12-16) - - -### Features - -* **lang:** add 'hu' locale ([#2965](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2965)) ([30f73c6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/30f73c6ec8298f37d4b456d6b5b97930902309bf)) -* **locales:** add ja locale ([#2960](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2960)) ([10a735d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/10a735de2fefd37eced720e898b1ebbfa880499b)) - - - - - -# [1.3.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.3.0-beta.0...netlify-cms-locales@1.3.0-beta.1) (2019-12-11) - - -### Features - -* duplicate entry ([#2956](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2956)) ([d180bff](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/d180bffb44432a82f2b4e5a08df5693b30268fee)) -* **lang:** add 'ru' locale (netlify[#2951](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2951)) ([#2952](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2952)) ([237a5b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/237a5b1aa65098f9c5b3768a306633a01fa25534)) - - - - - -# [1.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.2.0...netlify-cms-locales@1.3.0-beta.0) (2019-12-02) - - -### Features - -* **lang:** add 'tr' locale ([#2936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2936)) ([09ca1a7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/09ca1a7f0391b19b6d6065fcde93fc5a855a0f60)) - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/compare/netlify-cms-locales@1.1.0...netlify-cms-locales@1.2.0) (2019-11-26) - - -### Features - -* **lang:** add 'es' locale ([#2898](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2898)) ([35da9a7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/35da9a702714f455cff1daa98bf26a0039ad0771)) -* **lang:** add 'nl' locale ([#2904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2904)) ([413791d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/413791da1238dbd60d145c9bb5e10b89996c7261)) -* **lang:** add 'uk' locale ([#2903](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2903)) ([9022e9d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/9022e9d31f300b813f44b00bd5fc31b359ab8e28)) -* workflow unpublished entry ([#2914](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2914)) ([41bb9aa](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/41bb9aac0dd6fd9f8ff157bb0b29c85aa87fe04d)) - - - - - -# 1.1.0 (2019-11-18) - - -### Features - -* add french translation ([#2884](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2884)) ([0898767](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/0898767fc93f9d25438d45318d780942bb5f7d2c)) -* add translation support ([#2870](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2870)) ([096b067](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/096b067d4542c723630ded631fc9a4ba950732f3)), closes [#2877](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2877) -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) diff --git a/packages/netlify-cms-locales/README.md b/packages/netlify-cms-locales/README.md deleted file mode 100644 index 8e2e93ec..00000000 --- a/packages/netlify-cms-locales/README.md +++ /dev/null @@ -1,20 +0,0 @@ -# Netlify CMS Locales - -## Default translations for Netlify CMS - -The English translation is loaded by default. - -To register another locale you can use the following code: - -```js -import CMS from 'netlify-cms-app'; -import { de } from 'netlify-cms-locales'; - -CMS.registerLocale('de', de); -``` - -> When importing `netlify-cms` all locales are registered by default. - -Make sure the specific locale exists in the package - unless we will happily accept a pull request for it. - -The configured locale will be merge into the English one so don’t worry about missing some phrases. diff --git a/packages/netlify-cms-locales/package.json b/packages/netlify-cms-locales/package.json deleted file mode 100644 index 9f109726..00000000 --- a/packages/netlify-cms-locales/package.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "netlify-cms-locales", - "description": "Locales for Netlify CMS.", - "version": "1.39.0", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-locales", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-locales.js", - "keywords": [ - "netlify-cms" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - } -} diff --git a/packages/netlify-cms-locales/src/bg/index.js b/packages/netlify-cms-locales/src/bg/index.js deleted file mode 100644 index 5af3b0e8..00000000 --- a/packages/netlify-cms-locales/src/bg/index.js +++ /dev/null @@ -1,302 +0,0 @@ -const bg = { - auth: { - login: 'Вход', - loggingIn: 'Влизане...', - loginWithNetlifyIdentity: 'Вход с Netlify Identity', - loginWithAzure: 'Вход с Azure', - loginWithBitbucket: 'Вход с Bitbucket', - loginWithGitHub: 'Вход с GitHub', - loginWithGitLab: 'Вход с GitLab', - errors: { - email: 'Въведете вашия имейл.', - password: 'Въведете паролата.', - identitySettings: - 'Няма достъп до настройките. Ако използвате git-gateway, не забравяйте да активирате услугата Identity и Git Gateway.', - }, - }, - app: { - header: { - content: 'Съдържание', - workflow: 'Работен процес', - media: 'Мултимедийни файлове', - quickAdd: 'Бързо добавяне', - }, - app: { - errorHeader: 'Грешка при зареждането на конфигурацията на CMS', - configErrors: 'Грешки в конфигурацията', - checkConfigYml: 'Проверете вашия файл config.yml.', - loadingConfig: 'Зареждане на конфигурация ...', - waitingBackend: 'В очакване на отговор от бекенда ...', - }, - notFoundPage: { - header: 'Не е намерен', - }, - }, - collection: { - sidebar: { - collections: 'Колекции', - allCollections: 'Всички колекции', - searchAll: 'Търсете навсякъде', - searchIn: 'Търсене в', - }, - collectionTop: { - sortBy: 'Сортирай по', - viewAs: 'Виж като', - newButton: 'Създай %{collectionLabel}', - ascending: 'Възходящ', - descending: 'Низходящ', - searchResults: 'Ресултати от търсенето за "%{searchTerm}"', - searchResultsInCollection: 'Ресултати от търсенето за "%{searchTerm}" в %{collection}', - filterBy: 'Филтрирай по', - groupBy: 'Групирай по', - }, - entries: { - loadingEntries: 'Зареждане на записи...', - cachingEntries: 'Кеширане на записи...', - longerLoading: 'Това може да отнеме няколко минути', - noEntries: 'Няма записи', - }, - groups: { - other: 'Други', - negateLabel: 'Не %{label}', - }, - defaultFields: { - author: { - label: 'Автор', - }, - updatedOn: { - label: 'Обновено', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'незадължителен', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} е задължително.', - regexPattern: '%{fieldLabel} не съответства на модела: %{pattern}.', - processing: '%{fieldLabel} се обработва.', - min: '%{fieldLabel} трябва да бъде поне %{minValue}.', - range: '%{fieldLabel} трябва да бъде между %{minValue} и %{maxValue}.', - max: '%{fieldLabel} трябва да бъде %{maxValue} или по-малко.', - rangeCount: '%{fieldLabel} трябва да има между %{minCount} и %{maxCount} елемент(и).', - rangeCountExact: '%{fieldLabel} трябва да има точно %{count} елемент(и).', - minCount: '%{fieldLabel} трябва да бъде поне %{minCount} елемент(и).', - maxCount: '%{fieldLabel} трябва да бъде %{maxCount} или по-малко елемент(и).', - invalidPath: `'%{path}' не е валиден път`, - pathExists: `Пътят '%{path}' вече съществува`, - }, - i18n: { - writingInLocale: 'Писане на %{locale}', - }, - }, - editor: { - onLeavePage: 'Наистина ли искате да напуснете тази страница?', - onUpdatingWithUnsavedChanges: - 'Имате незапазени промени, моля, запазете преди актуализиране на състоянието.', - onPublishingNotReady: 'Моля, актуализирайте състоянието на „Готово“, преди да публикувате', - onPublishingWithUnsavedChanges: 'Имате незапазени промени, моля, запазете преди публикуване.', - onPublishing: 'Наистина ли искате да публикувате този запис?', - onUnpublishing: 'Наистина ли искате да прекратите публикуването на този запис?', - onDeleteWithUnsavedChanges: - 'Наистина ли искате да изтриете този публикуван запис, както и незаписаните промени от текущата сесия?', - onDeletePublishedEntry: 'Наистина ли искате да изтриете този публикуван запис?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Това ще изтрие всички непубликувани промени в този запис, както и незаписаните ви промени от текущата сесия. Все още ли искате да изтриете?', - onDeleteUnpublishedChanges: - 'Всички непубликувани промени в този запис ще бъдат изтрити. Все още ли искате да изтриете?', - loadingEntry: 'Зареждане на запис...', - confirmLoadBackup: - 'За този запис беше възстановен локален архив, бихте ли искали да го използвате?', - }, - editorInterface: { - toggleI18n: 'Превключване i18n', - togglePreview: 'Превключване на визуализация', - toggleScrollSync: 'Синхронизирай превъртане', - }, - editorToolbar: { - publishing: 'Публикуване...', - publish: 'Публикувай', - published: 'Публикуван', - unpublish: 'Непубликувай', - duplicate: 'Дублирай', - unpublishing: 'Непубликуване...', - publishAndCreateNew: 'Публикувай и създай нов', - publishAndDuplicate: 'Публикувай и дублирай', - deleteUnpublishedChanges: 'Изтриване на непубликувани промени', - deleteUnpublishedEntry: 'Изтрий непубликувани записи', - deletePublishedEntry: 'Изтрий публикувани записи', - deleteEntry: 'Изтрий запис', - saving: 'Запазване...', - save: 'Запази', - deleting: 'Изтриване...', - updating: 'Актуализиране...', - status: 'Cъстояние: %{status}', - backCollection: 'Записване в %{collectionLabel} колекция', - unsavedChanges: 'Незапазени Промени', - changesSaved: 'Запазени промени', - draft: 'Чернова', - inReview: 'В ревю', - ready: 'Готово', - publishNow: 'Публикувай сега', - deployPreviewPendingButtonLabel: 'Проверете визуализацията', - deployPreviewButtonLabel: 'Визуализация', - deployButtonLabel: 'Изглед', - }, - editorWidgets: { - markdown: { - bold: 'Удебелен', - italic: 'Курсив', - code: 'Код', - link: 'Връзка', - linkPrompt: 'Моля, въведете URL на връзката', - headings: 'Заглавия', - quote: 'Цитат', - bulletedList: 'Маркиран Списък', - numberedList: 'Номериран Списък', - addComponent: 'Добави Компонент', - richText: 'Форматиране на текст', - markdown: 'Markdown', - }, - image: { - choose: 'Избери изображение', - chooseUrl: 'Вмъкване от URL', - replaceUrl: 'Замяна с URL', - promptUrl: 'Въведете URL адреса на изображението', - chooseDifferent: 'Избери различно изображение', - remove: 'Премахни изображение', - }, - file: { - choose: 'Избери файл file', - chooseUrl: 'Вмъкване от URL', - replaceUrl: 'Замяна с URL', - promptUrl: 'Въведете URL адреса на файла', - chooseDifferent: 'Избери различен файл', - remove: 'Премахни файл', - }, - unknownControl: { - noControl: "Няма контрол за приспособлението '%{widget}'.", - }, - unknownPreview: { - noPreview: "Няма визуализация за приспособлението '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - datetime: { - now: 'Сега', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Чернова', - copy: 'Копирай', - copyUrl: 'Копирай URL', - copyPath: 'Копитай път', - copyName: 'Копитай име', - copied: 'Копирано', - }, - mediaLibrary: { - onDelete: 'Наистина ли искате да изтриете избрания медиен файл?', - fileTooLarge: - 'Файлът е твърде голям.\nНастройките не позволяват запазване на файлове по-големи от %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Зареждане...', - noResults: 'Няма резултати.', - noAssetsFound: 'Няма намерени ресурси.', - noImagesFound: 'Няма намерени изображения.', - private: 'Частен ', - images: 'Изображения', - mediaAssets: 'Медийни ресурси', - search: 'Търсене...', - uploading: 'Качване...', - upload: 'Качи', - download: 'Изтегли', - deleting: 'Изтриване...', - deleteSelected: 'Изтрай избрани', - chooseSelected: 'Избери избрани', - }, - }, - ui: { - default: { - goBackToSite: 'Обратно към сайта', - }, - errorBoundary: { - title: 'Грешка', - details: 'Възникна грешка - моля ', - reportIt: 'докладвайте в GitHub.', - detailsHeading: 'Детайли', - privacyWarning: - 'При отваряне на билет той автоматично се попълва предварително със съобщение за грешка и информация за отстраняване на грешки.\nМоля, проверете дали данните са верни и не съдържат поверителна информация.', - recoveredEntry: { - heading: 'Възстановен документ', - warning: 'Моля, копирайте това съобщение някъде, преди да напуснете страницата!', - copyButtonLabel: 'Копиране в клипборда', - }, - }, - settingsDropdown: { - logOut: 'Изход', - }, - toast: { - onFailToLoadEntries: 'Неуспешно зареждане на записа: %{details}', - onFailToLoadDeployPreview: 'Неуспешно зареждане на визуализация: %{details}', - onFailToPersist: 'Неуспешно запазване на записа: %{details}', - onFailToDelete: 'Неуспешно изтриване на записа: %{details}', - onFailToUpdateStatus: 'Неуспешно актуализиране на състоянието: %{details}', - missingRequiredField: - 'Извинете, пропуснахте задължително поле. Моля, попълнете преди запазване.', - entrySaved: 'Записът е запазен', - entryPublished: 'Записът е публикуван', - entryUnpublished: 'Записът е непубликуван', - onFailToPublishEntry: 'Неуспешно публикуване на запис: %{details}', - onFailToUnpublishEntry: 'Неуспешно премахване на публикацията на записа: %{details}', - entryUpdated: 'Статусът на записа е актуализиран', - onDeleteUnpublishedChanges: 'Непубликуваните промени са изтрити', - onFailToAuth: '%{details}', - onLoggedOut: 'Излезли сте. Моля, запазете всички данни и влезте отново', - onBackendDown: 'Има прекъсване в работата на бекенда. Виж детайлите %{details}', - }, - }, - workflow: { - workflow: { - loading: 'Зареждане на редакционни записи', - workflowHeading: 'Редакционен работен процес', - newPost: 'Нова публикация', - description: - 'Броят на записите, които очакват проверка -% {smart_count}, готови за публикуване -% {readyCount}. |||| Броят на записите, които очакват проверка -% {smart_count}, готови за публикуване -% {readyCount}. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date}, %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '%{author}', - deleteChanges: 'Изтриване на промените', - deleteNewEntry: 'Изтриване на нов запис', - pubChanges: 'Публикуване на промени', - objavNewEntry: 'Публикуване на нов запис', - }, - workflowList: { - onDeleteEntry: 'Наистина ли искате да изтриете този запис?', - onPublishingNotReadyEntry: - 'Могат да се публикуват само елементи със статус "Готов". Плъзенете картата в колоната "Готов" за да активирате публикуването.', - onPublishEntry: 'Наистина ли искате да публикувате този запис?', - draftHeader: 'Чернови', - inReviewHeader: 'В Ревю', - readyHeader: 'Готов', - currentEntries: '%{smart_count} запис |||| %{smart_count} записи', - }, - }, -}; - -export default bg; diff --git a/packages/netlify-cms-locales/src/ca/index.js b/packages/netlify-cms-locales/src/ca/index.js deleted file mode 100644 index 7e509daf..00000000 --- a/packages/netlify-cms-locales/src/ca/index.js +++ /dev/null @@ -1,299 +0,0 @@ -const ca = { - auth: { - login: 'Iniciar sessió', - loggingIn: 'Iniciant sessió...', - loginWithNetlifyIdentity: "Iniciar sessió amb l'identitat de Netlify", - loginWithBitbucket: 'Iniciar sessió amb Bitbucket', - loginWithGitHub: 'Iniciar sessió amb GitHub', - loginWithGitLab: 'Iniciar sessió amb GitLab', - errors: { - email: 'Comprova que has escrit el teu email.', - password: 'Si us plau escriu la teva contrasenya.', - identitySettings: - "No s'ha pogut obtenir accés a les configuracions d'identitat. Quan feu servir backend de git-gateway, assegureu-vos que activeu el servei d’identitat i la passarel·la de Git.", - }, - }, - app: { - header: { - content: 'Contingut', - workflow: 'Flux Editorial', - media: 'Multimèdia', - quickAdd: 'Afegir', - }, - app: { - errorHeader: 'Error al carregar la configuració del CMS', - configErrors: 'Errors de configuració', - checkConfigYml: "Comprovi l'arxiu config.yml.", - loadingConfig: 'Carregant configuració....', - waitingBackend: 'Esperant al servidor...', - }, - notFoundPage: { - header: 'No trobat', - }, - }, - collection: { - sidebar: { - collections: 'Col·leccions', - allCollections: 'Totes les col·leccions', - searchAll: 'Buscar tots', - searchIn: 'Buscar a', - }, - collectionTop: { - sortBy: 'Ordenar per', - viewAs: 'Veure com', - newButton: 'Nou %{collectionLabel}', - ascending: 'Ascendent', - descending: 'Descendent', - searchResults: 'Buscar resultats per "%{searchTerm}"', - searchResultsInCollection: 'Buscar resultats per "%{searchTerm}" a %{collection}', - filterBy: 'Filtrar per', - groupBy: 'Agrupar per', - }, - entries: { - loadingEntries: 'Carregant entrades', - cachingEntries: 'Emmagatzemant entrades a la caché', - longerLoading: 'Això podria tardar uns minuts', - noEntries: 'Cap entrada', - }, - groups: { - other: 'Altre', - negateLabel: 'No %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Actualitzat el', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opcional', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} és obligatori.', - regexPattern: '%{fieldLabel} no coincideix amb el patró: %{pattern}.', - processing: '%{fieldLabel} està processant.', - range: "%{fieldLabel} ha d'estar entre %{minValue} i %{maxValue}.", - min: '%{fieldLabel} ha ser com a mínim %{minValue}.', - max: '%{fieldLabel} ha de ser %{maxValue} o més.', - rangeCount: '%{fieldLabel} ha de tenir entre %{minCount} i %{maxCount} element(s).', - rangeCountExact: '%{fieldLabel} ha de tenir exactament %{count} element(s).', - rangeMin: "%{fieldLabel} ha de tenir com a mínim %{minCount} d'element(s).", - rangeMax: '%{fieldLabel} ha de ser %{maxCount} o inferior.', - invalidPath: `'%{path}' no és una ruta valida`, - pathExists: `'%{path}' ja existeix`, - }, - i18n: { - writingInLocale: 'Escriure en %{locale}', - }, - }, - editor: { - onLeavePage: 'Estàs segur que vols deixar aquesta pàgina?', - onUpdatingWithUnsavedChanges: - "Tens canvis no guardats, si us plau, guarda'ls abans d'actualitzar l'estat.", - onPublishingNotReady: 'Si us plau, actualitza l\'estat a "Llest" abans de publicar.', - onPublishingWithUnsavedChanges: - "Tens canvis no guardats, si us plau, guarda'ls abans de publicar-los.", - onPublishing: 'Estàs segur que vols publicar aquesta entrada?', - onUnpublishing: 'Estàs segur que vols esborrar aquesta entrada?', - onDeleteWithUnsavedChanges: - 'Està segur que vol eliminar aquesta entrada publicada, així com els canvis no guardats de la sessió actual?', - onDeletePublishedEntry: 'Està segur que vol eliminar aquesta entrada publicada?', - onDeleteUnpublishedChangesWithUnsavedChanges: - "Això eliminarà tots els canvis no publicats d'aquesta entrada així com els canvis no guardats de la sessió actual. Encara vol procedir?", - onDeleteUnpublishedChanges: - 'Tots els canvis no publicats en aquesta entrada seràn esborrats. Encara els vol eliminar?', - loadingEntry: 'Carregant entrada...', - confirmLoadBackup: - "S'ha recuperat una copia de seguretat local per aquesta entrada. La vol utilitzar?", - }, - editorInterface: { - toggleI18n: 'Mostrar/Amagar traduccions', - togglePreview: 'Mostrar/Amagar previsualització', - }, - editorToolbar: { - publishing: 'Publicant...', - publish: 'Publicar', - published: 'Publicat', - unpublish: 'Despublicar', - duplicate: 'Duplicar', - unpublishing: 'Despublicant...', - publishAndCreateNew: 'Publicar i crear de nou', - publishAndDuplicate: 'Publica i duplica', - deleteUnpublishedChanges: 'Eliminar canvis no publicats', - deleteUnpublishedEntry: 'Eliminar entrada no publicada', - deletePublishedEntry: 'Eliminar entrada publicada', - deleteEntry: 'Eliminar entrada', - saving: 'Guardant...', - save: 'Guardar', - deleting: 'Eliminant...', - updating: 'Actualizant...', - status: 'Estat: %{status}', - backCollection: 'Escrivint a la colecció %{collectionLabel}', - unsavedChanges: 'Canvis no guardats', - changesSaved: 'Canvis guardats', - draft: 'Esborrany', - inReview: 'En revisió', - ready: 'Llest', - publishNow: 'Publicar ara', - deployPreviewPendingButtonLabel: 'Comprovar Vista Prèvia', - deployPreviewButtonLabel: 'Veure Vista Prèvia', - deployButtonLabel: 'Veure publicació', - }, - editorWidgets: { - markdown: { - bold: 'Negreta', - italic: 'Cursiva', - code: 'Codi', - link: 'Enllaç', - linkPrompt: "Introdueix l'URL de l'enllaç", - headings: 'Encapçalaments', - bulletedList: 'Llista', - numberedList: 'Llista numèrica', - addComponent: 'Afegir component', - richText: 'Text enriquit', - markdown: 'Markdown', - }, - image: { - choose: 'Escull una imatge', - chooseUrl: 'Introdueix una URL', - replaceUrl: 'Substitueix per una URL', - promptUrl: "Introdueix l'URL de la imatge", - chooseDifferent: 'Escull una imatge diferent', - remove: 'Treu la imatge', - }, - file: { - choose: 'Escull un arxiu', - chooseUrl: 'Introdueix una URL', - replaceUrl: 'Substitueix per una URL', - promptUrl: "Introdueix l'URL de l'arxiu", - chooseDifferent: 'Escull un arxiu diferent', - remove: 'Esborrar arxiu', - }, - unknownControl: { - noControl: "No existeix un control per al widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "No existeix una vista prèvia per al widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Encapçalament 1', - headingTwo: 'Encapçalament 2', - headingThree: 'Encapçalament 3', - headingFour: 'Encapçalament 4', - headingFive: 'Encapçalament 5', - headingSix: 'Encapçalament 6', - }, - datetime: { - now: 'Ara', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Esborrany', - copy: 'Copiar', - copyUrl: 'Copiar URL', - copyPath: 'Copiar path', - copyName: 'Copiar nom', - copied: 'Copiat', - }, - mediaLibrary: { - onDelete: 'Està segur de que vol eliminar el mitjà seleccionat?', - fileTooLarge: - 'El fitxer és massa gran.\nLa configuració no permet fitxers més grans de %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Carregant...', - noResults: 'Sense resultats.', - noAssetsFound: 'Arxius no trobats.', - noImagesFound: 'Imatges no trobades.', - private: 'Privat', - images: 'Imatges', - mediaAssets: 'Arxius multimèdia', - search: 'Buscar...', - uploading: 'Penjant...', - upload: 'Penjar nou', - download: 'Descarregar', - deleting: 'Eliminant...', - deleteSelected: 'Eliminar selecció', - chooseSelected: 'Confirmar selecció', - }, - }, - ui: { - default: { - goBackToSite: 'Torna enrere al lloc', - }, - errorBoundary: { - title: 'Error', - details: "S'ha produït un error - si us plau ", - reportIt: "Informa'ns d'això a GitHub.", - detailsHeading: 'Detalls', - recoveredEntry: { - heading: 'Document recuperat', - warning: - 'Si us plau, copiï/enganxi això en algun lloc abans de navegar a una altre pàgina!', - copyButtonLabel: 'Copiar al porta-retalls', - }, - }, - settingsDropdown: { - logOut: 'Tancar sessió', - }, - toast: { - onFailToLoadEntries: "No s'ha ha pogut carregar l'entrada: %{details}", - onFailToLoadDeployPreview: "No s'ha pogut carregar la vista prèvia: %{details}", - onFailToPersist: "No s'ha pogut guardar l'entrada: %{details}", - onFailToDelete: "No s'ha pogut eliminar l'entrada: %{details}", - onFailToUpdateStatus: "No s'ha pogut actualitzar l'estat: %{details}", - missingRequiredField: - "Ups, no ha omplert un camp obligatori. Si us plau, ompli'l abans de guardar.", - entrySaved: 'Entrada guardada', - entryPublished: 'Entrada publicada', - entryUnpublished: 'Entrada despublicada', - onFailToPublishEntry: "No s'ha pogut publicar: %{details}", - onFailToUnpublishEntry: "No s'ha pogut despublicar l'entrada: %{details}", - entryUpdated: "Estat de l'entrada actualitzat", - onDeleteUnpublishedChanges: 'Canvis no publicats eliminats', - onFailToAuth: '%{details}', - onLoggedOut: 'La teva sessió ha estat tancada. Si us plau, torna a iniciar-la', - onBackendDown: 'El servidor està patint problemes. Consulta %{details} per a més informació', - }, - }, - workflow: { - workflow: { - loading: 'Carregant Entradas del Flux Editorial', - workflowHeading: 'Flux Editorial', - newPost: 'Nou article', - description: - '%{smart_count} entrada esperant revisió, %{readyCount} llesta per a publicar |||| %{smart_count} entrades esperant revisió, %{readyCount} llestes per a publicar. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} per %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'per %{author}', - deleteChanges: 'Eliminar canvis', - deleteNewEntry: 'Eliminar nova entrada', - publishChanges: 'Publicar canvis', - publishNewEntry: 'Publicar nova entrada', - }, - workflowList: { - onDeleteEntry: 'Està segur que vol borrar aquesta entrada?', - onPublishingNotReadyEntry: - 'Només es poden publicar elements amb estat "Llest". Si us plau, arrossegui la targeta fins la columna "Llest" per a permetre\'n la publicació', - onPublishEntry: 'Està segur que vol publicar aquesta entrada?', - draftHeader: 'Esborranys', - inReviewHeader: 'En revisió', - readyHeader: 'Llest', - currentEntries: '%{smart_count} entrada |||| %{smart_count} entrades', - }, - }, -}; - -export default ca; diff --git a/packages/netlify-cms-locales/src/cs/index.js b/packages/netlify-cms-locales/src/cs/index.js deleted file mode 100644 index 2e635fc4..00000000 --- a/packages/netlify-cms-locales/src/cs/index.js +++ /dev/null @@ -1,299 +0,0 @@ -const cs = { - auth: { - login: 'Přihlásit', - loggingIn: 'Přihlašování…', - loginWithNetlifyIdentity: 'Přihlásit pomocí Netlify Identity', - loginWithAzure: 'Přihlásit pomocí Azure', - loginWithBitbucket: 'Přihlásit pomocí Bitbucket', - loginWithGitHub: 'Přihlásit pomocí GitHub', - loginWithGitLab: 'Přihlásit pomocí GitLab', - errors: { - email: 'Vyplňte e-mailovou adresu.', - password: 'Vyplňte heslo.', - identitySettings: - 'Nastavení identity nenalezeno. Používáte-li git-gateway server nezapomeňte aktivovat službu Identity a Git Gateway' + - '.', - }, - }, - app: { - header: { - content: 'Obsah', - workflow: 'Workflow', - media: 'Média', - quickAdd: 'Přidat', - }, - app: { - errorHeader: 'Chyba při načítání CMS konfigurace', - configErrors: 'Chyba konfigurace', - checkConfigYml: 'Zkontrolujte soubor config.yml.', - loadingConfig: 'Načítání konfigurace…', - waitingBackend: 'Čekání na server…', - }, - notFoundPage: { - header: 'Nenalezeno', - }, - }, - collection: { - sidebar: { - collections: 'Kolekce', - allCollections: 'Všechny kolekce', - searchAll: 'Hledat', - searchIn: 'Hledat v', - }, - collectionTop: { - sortBy: 'Seřadit podle', - viewAs: 'Zobrazit jako', - newButton: 'Nový %{collectionLabel}', - ascending: 'Vzestupné', - descending: 'Sestupné', - searchResults: 'Výsledky vyhledávání pro "%{searchTerm}"', - searchResultsInCollection: 'Výsledky vyhledávání pro "%{searchTerm}" v kolekci %{collection}', - filterBy: 'Filtrovat podle', - groupBy: 'Seskupit podle', - }, - entries: { - loadingEntries: 'Načítání záznamů', - cachingEntries: 'Úkládání záznamů do mezipaměti', - longerLoading: 'Načítání může trvat několik minut', - noEntries: 'Žádné záznamy', - }, - groups: { - other: 'Ostatní', - negateLabel: 'Není %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Poslední aktualizace', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'volitelný', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} je povinný.', - regexPattern: '%{fieldLabel} nesouhlasí s předepsaným vzorem: %{pattern}.', - processing: '%{fieldLabel} se zpracovává.', - range: '%{fieldLabel} musí být mezi %{minValue} a %{maxValue}.', - min: '%{fieldLabel} musí být alespoň %{minValue}.', - max: '%{fieldLabel} musí být %{maxValue} nebo méně.', - rangeCount: '%{fieldLabel} musí mít %{minCount} až %{maxCount} položek.', - rangeCountExact: '%{fieldLabel} musí mít přesně %{count} položek.', - rangeMin: '%{fieldLabel} musí mít nejméně %{minCount} položky.', - rangeMax: '%{fieldLabel} musí mít %{maxCount} nebo méně položek.', - invalidPath: `'%{path}' není platnou cestou.`, - pathExists: `Cesta '%{path}' už existuje.`, - }, - i18n: { - writingInLocale: 'Psát v %{locale}', - }, - }, - editor: { - onLeavePage: 'Chcete opravdu opustit tuto stránku?', - onUpdatingWithUnsavedChanges: 'Máte neuložené změny. Uložte je prosím před změnou statusu.', - onPublishingNotReady: 'Změňte stav na „Připraveno“ před publikováním.', - onPublishingWithUnsavedChanges: 'Máte neuložené změny, prosím uložte je před publikováním.', - onPublishing: 'Chcete opravdu publikovat tento záznam?', - onUnpublishing: 'Chcete opravdu zrušit publikování tohoto záznamu?', - onDeleteWithUnsavedChanges: - 'Chcete opravdu vymazat tento publikovaný záznam a všechny neuložené změny z této relace?', - onDeletePublishedEntry: 'Chcete opravdu smazat tento publikovaný záznam?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Tato akce vymaže všechny nepublikované změny v tomto záznamu a také všechny neuložené změny z této relace. Chcete záznam skutečně vymazat?', - onDeleteUnpublishedChanges: - 'Všechny nepublivkoané změny v tomto záznamu budou vymazány. Chcete ho skuteně vymazat?', - loadingEntry: 'Načítání záznamu…', - confirmLoadBackup: 'Lokální kopie tohoto záznamu byla nalezena, chcete ji použít?', - }, - editorInterface: { - toggleI18n: 'Přepnout lokalizaci', - togglePreview: 'Přepnout náhled', - toggleScrollSync: 'Sladit skrolování', - }, - editorToolbar: { - publishing: 'Publikování…', - publish: 'Publikovat', - published: 'Publikovaný', - unpublish: 'Zrušit publikování', - duplicate: 'Duplikovat', - unpublishing: 'Rušení publikování…', - publishAndCreateNew: 'Publikovat a vytvořit nový', - publishAndDuplicate: 'Publikovat a duplikovat', - deleteUnpublishedChanges: 'Vymazat nepublikované změny', - deleteUnpublishedEntry: 'Vymazat nepublikovaný záznam', - deletePublishedEntry: 'Vymazat publikovaný záznam', - deleteEntry: 'Vymazat záznam', - saving: 'Ukládání…', - save: 'Uložit', - deleting: 'Vymazávání…', - updating: 'Aktualizace…', - status: 'Status: %{status}', - backCollection: ' Píšete v kolekci %{collectionLabel}', - unsavedChanges: 'Neuložené změny', - changesSaved: 'Změny uloženy', - draft: 'Koncept', - inReview: 'V revizi', - ready: 'Připraveno', - publishNow: 'Publikovat teď', - deployPreviewPendingButtonLabel: 'Zkontrolovat náhled', - deployPreviewButtonLabel: 'Zobrazit náhled', - deployButtonLabel: 'Zobrazit na webu', - }, - editorWidgets: { - markdown: { - bold: 'Tučně', - italic: 'Kurzíva', - code: 'Kód', - link: 'Odkaz', - linkPrompt: 'Zadejte URL odkazu', - headings: 'Nadpisy', - quote: 'Citovat', - bulletedList: 'Odrážkový seznam', - numberedList: 'Číslovaný seznam', - addComponent: 'Přidat součástku', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'Vyberte obrázek', - chooseUrl: 'Přidat z URL', - replaceUrl: 'Nahradit z URL', - promptUrl: 'Zadejte URL obrázku', - chooseDifferent: 'Vyberte jiný obrázek', - remove: 'Odstranit obrázek', - }, - file: { - choose: 'Vyberte soubor', - chooseUrl: 'Přidat z URL', - replaceUrl: 'Nahradit z URL', - promptUrl: 'Zadejte URL souboru', - chooseDifferent: 'Vyberte jiný soubor', - remove: 'Odebrat soubor', - }, - unknownControl: { - noControl: "Žádné ovládání pro widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Žádný náhled pro widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Nadpis 1', - headingTwo: 'Nadpis 2', - headingThree: 'Nadpis 3', - headingFour: 'Nadpis 4', - headingFive: 'Nadpis 5', - headingSix: 'Nadpis 6', - }, - datetime: { - now: 'Teď', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Koncept', - copy: 'Kopírovat', - copyUrl: 'Kopírovat URL', - copyPath: 'Kopírovat cestu', - copyName: 'Kopírovat název', - copied: 'Zkopírováno', - }, - mediaLibrary: { - onDelete: 'Chcete skutečně vymazat označená média?', - fileTooLarge: 'Soubor je příliš velký.\nSoubor musí být menší než %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Načítání…', - noResults: 'Nic nenalezeno.', - noAssetsFound: 'Média nenalezena.', - noImagesFound: 'Obrázky nenalezeny.', - private: 'Soukromé ', - images: 'Obrázky', - mediaAssets: 'Média', - search: 'Hledat…', - uploading: 'Nahrávání…', - upload: 'Nahrát nový', - download: 'Stáhnout', - deleting: 'Vymazávání…', - deleteSelected: 'Smazat označené', - chooseSelected: 'Vybrat označené', - }, - }, - ui: { - default: { - goBackToSite: 'Vrátit se na stránku', - }, - errorBoundary: { - title: 'Chyba', - details: 'Nastala chyba – prosím ', - reportIt: 'nahlašte ji.', - detailsHeading: 'Detaily', - privacyWarning: - 'Při otevření problému budou předvyplněny ladící data a chybová zpráva.\nProsím zkontrolujte, jestli jsou informace správné, a případně odstraňte citlivé údaje.', - recoveredEntry: { - heading: 'Nalezený dokument', - warning: 'Prosím zkopírujte dokument do schránky před tím než odejte z této stránky!', - copyButtonLabel: 'Zkopírovat do schránky', - }, - }, - settingsDropdown: { - logOut: 'Odhlásit', - }, - toast: { - onFailToLoadEntries: 'Chyba při načítání záznamu: %{details}', - onFailToLoadDeployPreview: 'Chyba při načítání náhledu: %{details}', - onFailToPersist: 'Chyba při ukládání záznamu: %{details}', - onFailToDelete: 'Chyba při vymazávání záznamu: %{details}', - onFailToUpdateStatus: 'Chyba při změně stavu záznamu: %{details}', - missingRequiredField: 'Vynechali jste povinné pole. Prosím vyplňte ho.', - entrySaved: 'Záznam uložen', - entryPublished: 'Záznam publikován', - entryUnpublished: 'Publikování záznamu zrušeno', - onFailToPublishEntry: 'Chyba při publikování záznamu: %{details}', - onFailToUnpublishEntry: 'Chyba při rušení publikování záznamu: %{details}', - entryUpdated: 'Stav záznamu byl změněn', - onDeleteUnpublishedChanges: 'Nepublikované změny byly smazány', - onFailToAuth: '%{details}', - onLoggedOut: 'Byli jste odhlášeni, prosím zálohujte všechna data a znova se přihlašte', - onBackendDown: 'Backend zaznamenal výpadek. Podívejte se do %{details} pro více informací.', - }, - }, - workflow: { - workflow: { - loading: 'Načítání workflow záznamů', - workflowHeading: 'Schvalovací Workflow', - newPost: 'Nový post', - description: - '%{smart_count} záznam čeká na schválení, %{readyCount} připraven k publikaci. |||| %{smart_count} čeká na schválení, %{readyCount} připraveno k publikaci. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} (%{author})', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '%{author}', - deleteChanges: 'Vymazat změny', - deleteNewEntry: 'Vymazat nový záznam', - publishChanges: 'Publikovat změny', - publishNewEntry: 'Publikovat nový záznam', - }, - workflowList: { - onDeleteEntry: 'Opravdu chcete smazat tento záznam?', - onPublishingNotReadyEntry: - 'Pouze položky se statusem "Připraveno" mohou být publikováno. Pro umožnění publikace musíte přetáhnout kartu do sloupce "Připraveno"', - onPublishEntry: 'Opravdu chcete publikovat tento záznam?', - draftHeader: 'Koncepty', - inReviewHeader: 'V revizi', - readyHeader: 'Připraveno', - currentEntries: '%{smart_count} záznam |||| %{smart_count} záznamů', - }, - }, -}; - -export default cs; diff --git a/packages/netlify-cms-locales/src/da/index.js b/packages/netlify-cms-locales/src/da/index.js deleted file mode 100644 index 30e87e60..00000000 --- a/packages/netlify-cms-locales/src/da/index.js +++ /dev/null @@ -1,287 +0,0 @@ -const da = { - auth: { - login: 'Log ind', - loggingIn: 'Logger ind...', - loginWithNetlifyIdentity: 'Log ind med Netlify Identity', - loginWithAzure: 'Log ing med Azure', - loginWithBitbucket: 'Log ind med Bitbucket', - loginWithGitHub: 'Log ind med GitHub', - loginWithGitLab: 'Log ind med GitLab', - errors: { - email: 'Vær sikker på du har indtastet din e-mail.', - password: 'Indtast dit kodeord.', - identitySettings: - 'Kunne ikke tilgå identity opsætning. Ved brug af git-gateway som bagvedliggende service, sørg for at aktivere Identity service og Git Gateway.', - }, - }, - app: { - header: { - content: 'Indhold', - workflow: 'Arbejdsgang', - media: 'Medier', - quickAdd: 'Hurtig opret', - }, - app: { - errorHeader: 'Fejl ved indlæsning af CMS opsætningen', - configErrors: 'Opsætningsfejl', - checkConfigYml: 'Kontroller din config.yml fil.', - loadingConfig: 'Indlæser opsætning...', - waitingBackend: 'Venter på bagvedliggende service...', - }, - notFoundPage: { - header: 'Ikke fundet', - }, - }, - collection: { - sidebar: { - collections: 'Samlinger', - allCollections: 'Alle samlinger', - searchAll: 'Søg i alt', - searchIn: 'Søg i', - }, - collectionTop: { - sortBy: 'Sorter efter', - viewAs: 'Vis som', - newButton: 'Ny %{collectionLabel}', - ascending: 'Stigende', - descending: 'Faldende', - searchResults: 'Søgeresultater for "%{searchTerm}"', - searchResultsInCollection: 'Søgeresultater for "%{searchTerm}" i %{collection}', - filterBy: 'Filtrer efter', - groupBy: 'Grupper efter', - }, - entries: { - loadingEntries: 'Indlæser dokumenter...', - cachingEntries: 'Caching af dokumenter...', - longerLoading: 'Dette kan tage adskillige minutter', - noEntries: 'Ingen dokumenter', - }, - groups: { - other: 'Anden', - negateLabel: 'Ikke %{label}', - }, - defaultFields: { - author: { - label: 'Forfatter', - }, - updatedOn: { - label: 'Opdateret ', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'kan udelades', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} er påkrævet.', - regexPattern: '%{fieldLabel} matchede ikke: %{pattern}.', - processing: '%{fieldLabel} behandles.', - range: '%{fieldLabel} skal være mellem %{minValue} og %{maxValue}.', - min: '%{fieldLabel} skal være mindst %{minValue}.', - max: '%{fieldLabel} være være %{maxValue} eller mindre.', - rangeCount: '%{fieldLabel} skal have mellem %{minCount} og %{maxCount} element(er).', - rangeCountExact: '%{fieldLabel} skal have præcis %{count} element(er).', - rangeMin: '%{fieldLabel} skal have mindst %{minCount} element(er).', - rangeMax: '%{fieldLabel} skal have %{maxCount} eller færre element(er).', - invalidPath: `'%{path}' er ikke en gyldig sti`, - pathExists: `Stien '%{path}' findes allerede`, - }, - i18n: { - writingInLocale: 'Skriver på %{locale}', - }, - }, - editor: { - onLeavePage: 'Er du sikker på at du vil forlade siden?', - onUpdatingWithUnsavedChanges: - 'Du har ændringer der ikke er gemt, gem disse før status ændres.', - onPublishingNotReady: 'Skift status til "Klar" inden publicering.', - onPublishingWithUnsavedChanges: 'Du har ændringer der ikke er gemt, gem inden publicing.', - onPublishing: 'Er du sikker på at du vil publicere dette dokument?', - onUnpublishing: 'Er du sikker på at du vil afpublicere dette dokument?', - onDeleteWithUnsavedChanges: - 'Er du sikker på at du vil slette dette tidliere publiceret dokument, samt dine nuværende ugemte ændringer fra denne session?', - onDeletePublishedEntry: - 'Er du sikker på at du vil slette dette tidliere publiceret dokument?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Alle ikke publicerede ændringer til dette dokument vil blive slettet ligesom dine nuværende ugemte ændringer fra denne session. Er du sikker på at du vil slette?', - onDeleteUnpublishedChanges: - 'Alle ikke publicerede ændringer til dette dokument vil blive slettet. Er du sikker på at du vil slette?', - loadingEntry: 'Indlæser dokument...', - confirmLoadBackup: - 'En lokal sikkerhedskopi blev gendannet for dette dokument, vil du anvende denne?', - }, - editorToolbar: { - publishing: 'Publicerer...', - publish: 'Publicer', - published: 'Publiceret', - unpublish: 'Afpublicer', - duplicate: 'Kopier', - unpublishing: 'Afpublicerer...', - publishAndCreateNew: 'Publicer og opret ny', - publishAndDuplicate: 'Publicer og kopier', - deleteUnpublishedChanges: 'Slet upublicerede ændringer', - deleteUnpublishedEntry: 'Slet upubliceret dokument', - deletePublishedEntry: 'Slet publiceret dokument', - deleteEntry: 'Slet dokument', - saving: 'Gemmer...', - save: 'Gem', - deleting: 'Sletter...', - updating: 'Updaterer...', - status: 'Status: %{status}', - backCollection: ' Skriver til %{collectionLabel} samlingen', - unsavedChanges: 'Ugemte ændringer', - changesSaved: 'Ændringer gemt', - draft: 'Kladder', - inReview: 'Til gennemsyn', - ready: 'Klar', - publishNow: 'Publicer nu', - deployPreviewPendingButtonLabel: 'Lav preview', - deployPreviewButtonLabel: 'Vis preview', - deployButtonLabel: 'Vis live', - }, - editorWidgets: { - markdown: { - bold: 'Fed', - italic: 'Kursiv', - code: 'Kode', - link: 'Link', - linkPrompt: 'Indtast URL for link', - headings: 'Overskrifter', - quote: 'Citat', - bulletedList: 'Punktopstilling', - numberedList: 'Nummeret liste', - addComponent: 'Tilføj komponent', - richText: 'Formatteret tekst', - markdown: 'Markdown', - }, - image: { - choose: 'Vælg et billede', - chooseDifferent: 'Vælg et andet billede', - remove: 'Fjern billede', - }, - file: { - choose: 'Vælg fil', - chooseDifferent: 'Vælg en anden fil', - remove: 'Fjern fil', - }, - unknownControl: { - noControl: "Ingen kontrol finden for '%{widget}'.", - }, - unknownPreview: { - noPreview: "Ingen preview for '%{widget}'.", - }, - headingOptions: { - headingOne: 'Overskrift 1', - headingTwo: 'Overskrift 2', - headingThree: 'Overskrift 3', - headingFour: 'Overskrift 4', - headingFive: 'Overskrift 5', - headingSix: 'Overskrift 6', - }, - datetime: { - now: 'Nu', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Kladde', - }, - mediaLibrary: { - onDelete: 'Er du sikker på at du vil slette det valgte medie?', - fileTooLarge: 'Filen er for stor.\nOpsætningen tillader ikke filer større end %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Indlæser...', - noResults: 'Ingen resultater.', - noAssetsFound: 'Ingen elementer fundet.', - noImagesFound: 'Ingen billeder fundet.', - private: 'Privat ', - images: 'Billeder', - mediaAssets: 'Medie elementer', - search: 'Søg...', - uploading: 'Uploader...', - upload: 'Upload', - download: 'Download', - deleting: 'Slet...', - deleteSelected: 'Slet valgte', - chooseSelected: 'Anvend valgte', - }, - }, - ui: { - default: { - goBackToSite: 'Tilbage til hjemmesiden', - }, - errorBoundary: { - title: 'Fejl', - details: 'Der opstod en fejl - venligst ', - reportIt: 'opret et issue på GitHub.', - detailsHeading: 'Detalger', - privacyWarning: - 'Ved at oprette et issue forudfyldes det med fejlbeskeden og data til debugging.\nKontroller venligst at informationerne er korrekte og fjern eventuelle følsomme data.', - recoveredEntry: { - heading: 'Gendannet dokument', - warning: 'Kopier dette et sted hen inden du navigerer væk!', - copyButtonLabel: 'Kopier til udklipsholder', - }, - }, - settingsDropdown: { - logOut: 'Log af', - }, - toast: { - onFailToLoadEntries: 'Fejl ved indlæsning af dokumenter: %{details}', - onFailToLoadDeployPreview: 'Preview kunne ikke indlæses: %{details}', - onFailToPersist: 'Dokumentet kunne ikke gemmes: %{details}', - onFailToDelete: 'Dokumentet kunne ikke slettes: %{details}', - onFailToUpdateStatus: 'Status kunne ikke opdateres: %{details}', - missingRequiredField: - 'Ups, du mangler et påkrævet felt. Udfyld de påkrævede felter før dokumentet gemmes.', - entrySaved: 'Dokumentet er gemt', - entryPublished: 'Dokumentet er publiceret ', - entryUnpublished: 'Dokumentet er afpubliceret', - onFailToPublishEntry: 'Kunne ikke publicere på grund af en fejl: %{details}', - onFailToUnpublishEntry: 'Kunne ikke afpublicere på grund af en fejl: %{details}', - entryUpdated: 'Dokumentstatus er opdateret', - onDeleteUnpublishedChanges: 'Upublicerede ændringer blev slettet', - onFailToAuth: '%{details}', - onLoggedOut: 'Du er blevet logget ind, gem venligst evt. ændringer og log på igen', - onBackendDown: - 'Den bagvedliggende service er ikke tilgængelig i øjeblikket. Se %{details} for mere information', - }, - }, - workflow: { - workflow: { - loading: 'Indlæser dokumenter i redaktionel arbejdsgang', - workflowHeading: 'Redaktionel arbejdsgang', - newPost: 'Nyt indlæg', - description: - '%{smart_count} dokumenter afventer gennemsyn, %{readyCount} er klar til live. |||| %{smart_count} dokumenter afventer gennemsyn, %{readyCount} klar til go live. ', - dateFormat: 'D. MMMM', - }, - workflowCard: { - lastChange: '%{date} af %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'af %{author}', - deleteChanges: 'Slet ændringer', - deleteNewEntry: 'Slet nye dokumenter', - publishChanges: 'Publicer ændringer', - publishNewEntry: 'Publicer nye dokumenter', - }, - workflowList: { - onDeleteEntry: 'Er du sikker på at du vil slette dette dokument?', - onPublishingNotReadyEntry: - 'Kun dokumenter med "Klar" status kan publiceres. Træk kortet til "Klar" kolonnen for at tillade publicering.', - onPublishEntry: 'Er du sikker på at du vil publicere dokumentet?', - draftHeader: 'Kladder', - inReviewHeader: 'Til gennemsyn', - readyHeader: 'Klar', - currentEntries: '%{smart_count} dokument |||| %{smart_count} dokumenter', - }, - }, -}; - -export default da; diff --git a/packages/netlify-cms-locales/src/de/index.js b/packages/netlify-cms-locales/src/de/index.js deleted file mode 100644 index 9dbd79e5..00000000 --- a/packages/netlify-cms-locales/src/de/index.js +++ /dev/null @@ -1,316 +0,0 @@ -const de = { - auth: { - login: 'Login', - loggingIn: 'Sie werden eingeloggt...', - loginWithNetlifyIdentity: 'Mit Netlify Identity einloggen', - loginWithAzure: 'Mit Azure einloggen', - loginWithBitbucket: 'Mit Bitbucket einloggen', - loginWithGitHub: 'Mit GitHub einloggen', - loginWithGitLab: 'Mit GitLab einloggen', - errors: { - email: 'Stellen Sie sicher, Ihre E-Mail-Adresse einzugeben.', - password: 'Bitte geben Sie Ihr Passwort ein.', - identitySettings: - 'Identity Einstellungen konnten nicht abgerufen werden. Stellen Sie bei der Verwendung des Git-Gateway Backends sicher, den Identity Service und das Git Gateway zu aktivieren.', - }, - }, - app: { - header: { - content: 'Inhalt', - workflow: 'Arbeitsablauf', - media: 'Medien', - quickAdd: 'Schnell-Erstellung', - }, - app: { - errorHeader: 'Fehler beim Laden der CMS-Konfiguration.', - configErrors: 'Konfigurationsfehler', - checkConfigYml: 'Überprüfen Sie die config.yml Konfigurationsdatei.', - loadingConfig: 'Konfiguration laden...', - waitingBackend: 'Auf Server warten...', - }, - notFoundPage: { - header: 'Nicht gefunden', - }, - }, - collection: { - sidebar: { - collections: 'Inhaltstypen', - allCollections: 'Allen Inhaltstypen', - searchAll: 'Alles durchsuchen', - searchIn: 'Suchen in', - }, - collectionTop: { - sortBy: 'Sortieren nach', - viewAs: 'Anzeigen als', - newButton: 'Neue(r/s) %{collectionLabel}', - ascending: 'Aufsteigend', - descending: 'Absteigend', - searchResults: 'Suchergebnisse für "%{searchTerm}"', - searchResultsInCollection: 'Suchergebnisse für "%{searchTerm}" in %{collection}', - filterBy: 'Filtern nach', - groupBy: 'Gruppieren nach', - }, - entries: { - loadingEntries: 'Beiträge laden', - cachingEntries: 'Beiträge zwischenspeichern', - longerLoading: 'Diese Aktion kann einige Minuten in Anspruch nehmen', - noEntries: 'Keine Beiträge', - }, - groups: { - other: 'Andere', - negateLabel: 'Nicht %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Änderungsdatum', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'optional', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} ist erforderlich.', - regexPattern: '%{fieldLabel} entspricht nicht dem Muster: %{pattern}.', - processing: '%{fieldLabel} wird verarbeitet.', - range: '%{fieldLabel} muss zwischen %{minValue} und %{maxValue} liegen.', - min: '%{fieldLabel} muss größer als %{minValue} sein.', - max: '%{fieldLabel} darf nicht größer als %{maxValue} sein.', - rangeCount: '%{fieldLabel} muss %{minCount} bis %{maxCount} Element(e) enthalten.', - rangeCountExact: '%{fieldLabel} muss exakt %{count} Element(e) enthalten.', - rangeMin: '%{fieldLabel} muss mindestens %{minCount} Element(e) enthalten.', - rangeMax: '%{fieldLabel} darf maximal %{maxCount} Element(e) enthalten.', - invalidPath: `'%{path}' ist kein gültiger Pfad`, - pathExists: `Pfad '%{path}' existiert bereits`, - }, - i18n: { - writingInLocale: 'Aktuelle Sprache: %{locale}', - copyFromLocale: 'Aus anderer Sprache übernehmen', - copyFromLocaleConfirm: - 'Wollen Sie wirklich die Daten aus der Sprache %{locale} übernehmen?\nAlle bishergen Inhalte werden überschrieben.', - }, - }, - editor: { - onLeavePage: 'Möchten Sie diese Seite wirklich verlassen?', - onUpdatingWithUnsavedChanges: - 'Es sind noch ungespeicherte Änderungen vorhanden. Bitte speichern Sie diese, bevor Sie den Status aktualisieren.', - onPublishingNotReady: - 'Bitte setzten die den Status vor dem Veröffentlichen auf "Abgeschlossen".', - onPublishingWithUnsavedChanges: - 'Es sind noch ungespeicherte Änderungen vorhanden. Bitte speicheren Sie vor dem Veröffentlichen.', - onPublishing: 'Soll dieser Beitrag wirklich veröffentlicht werden?', - onUnpublishing: 'Soll die Veröffentlichung dieses Beitrags wirklich zurückgezogen werden?', - onDeleteWithUnsavedChanges: - 'Möchten Sie diesen veröffentlichten Beitrag, sowie Ihre nicht gespeicherten Änderungen löschen?', - onDeletePublishedEntry: 'Soll dieser veröffentlichte Beitrag wirklich gelöscht werden?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Möchten Sie diesen unveröffentlichten Beitrag, sowie Ihre nicht gespeicherten Änderungen löschen?', - onDeleteUnpublishedChanges: - 'Alle unveröffentlichten Änderungen werden gelöscht. Möchten Sie wirklich löschen?', - loadingEntry: 'Beitrag laden...', - confirmLoadBackup: - 'Für diesen Beitrag ist ein lokales Backup vorhanden. Möchten Sie dieses benutzen?', - }, - editorInterface: { - toggleI18n: 'Übersetzungen', - togglePreview: 'Vorschau', - toggleScrollSync: 'Synchron scrollen', - }, - editorToolbar: { - publishing: 'Veröffentlichen...', - publish: 'Veröffentlichen', - published: 'Veröffentlicht', - unpublish: 'Veröffentlichung zurückziehen', - duplicate: 'Duplizieren', - unpublishing: 'Veröffentlichung wird zurückgezogen...', - publishAndCreateNew: 'Veröffentlichen und neuen Beitrag erstellen', - publishAndDuplicate: 'Veröffentlichen und Beitrag duplizieren', - deleteUnpublishedChanges: 'Unveröffentlichte Änderungen verwerfen', - deleteUnpublishedEntry: 'Lösche unveröffentlichten Beitrag', - deletePublishedEntry: 'Lösche veröffentlichten Beitrag', - deleteEntry: 'Lösche Beitrag', - saving: 'Speichern...', - save: 'Speichern', - statusInfoTooltipDraft: - 'Beitrag ist im Entwurfsstatus. Um ihn fertigzustellen und zur Überprüfung freizugeben, setzen Sie den Status auf ‘Zur Überprüfung‘.', - statusInfoTooltipInReview: - 'Beitrag wird überprüft, keine weitere Aktion erforderlich. Sie können weitere Änderungen vornehmen, während die Überprüfung läuft.', - deleting: 'Löschen...', - updating: 'Aktualisieren...', - status: 'Status: %{status}', - backCollection: 'Zurück zu allen %{collectionLabel}', - unsavedChanges: 'Ungespeicherte Änderungen', - changesSaved: 'Änderungen gespeichert', - draft: 'Entwurf', - inReview: 'Zur Überprüfung', - ready: 'Abgeschlossen', - publishNow: 'Jetzt veröffentlichen', - deployPreviewPendingButtonLabel: 'Überprüfen ob eine Vorschau vorhanden ist', - deployPreviewButtonLabel: 'Vorschau anzeigen', - deployButtonLabel: 'Live ansehen', - }, - editorWidgets: { - markdown: { - bold: 'Fett', - italic: 'Kursiv', - code: 'Code', - link: 'Link', - linkPrompt: 'Link-URL eingeben', - headings: 'Überschriften', - quote: 'Zitat', - bulletedList: 'Aufzählungsliste', - numberedList: 'Nummerierte Liste', - addComponent: 'Komponente hinzufügen', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'Wähle ein Bild', - chooseUrl: 'Von URL hinzufügen', - replaceUrl: 'Von URL ersetzen', - promptUrl: 'Bild-URL eingeben', - chooseDifferent: 'Wähle ein anderes Bild', - remove: 'Entferne Bild', - }, - file: { - choose: 'Wählen Sie eine Datei', - chooseUrl: 'Von URL hinzufügen', - replaceUrl: 'Von URL ersetzen', - promptUrl: 'Datei-URL eingeben', - chooseDifferent: 'Wählen Sie eine andere Datei', - remove: 'Datei löschen', - }, - unknownControl: { - noControl: "Kein Bedienelement für Widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Keine Vorschau für Widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Überschrift 1', - headingTwo: 'Überschrift 2', - headingThree: 'Überschrift 3', - headingFour: 'Überschrift 4', - headingFive: 'Überschrift 5', - headingSix: 'Überschrift 6', - }, - datetime: { - now: 'Jetzt', - }, - list: { - add: '%{item} hinzufügen', - addType: '%{item} hinzufügen', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Entwurf', - copy: 'Kopieren', - copyUrl: 'URL kopieren', - copyPath: 'Pfad kopieren', - copyName: 'Name kopieren', - copied: 'Kopiert', - }, - mediaLibrary: { - onDelete: 'Soll das ausgewählte Medium wirklich gelöscht werden?', - fileTooLarge: 'Datei zu groß.\nErlaubt sind nur Dateien bis %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Laden...', - noResults: 'Keine Egebnisse.', - noAssetsFound: 'Keine Medien gefunden.', - noImagesFound: 'Keine Bilder gefunden.', - private: 'Privat ', - images: 'Bilder', - mediaAssets: 'Medien', - search: 'Suchen...', - uploading: 'Hochladen...', - upload: 'Hochladen', - download: 'Download', - deleting: 'Löschen...', - deleteSelected: 'Ausgewähltes Element löschen', - chooseSelected: 'Ausgewähltes Element verwenden', - }, - }, - ui: { - default: { - goBackToSite: 'Zurück zur Seite', - }, - errorBoundary: { - title: 'Fehler', - details: 'Ein Fehler ist aufgetreten - bitte ', - reportIt: 'berichte ihn.', - detailsHeading: 'Details', - privacyWarning: - 'Beim Eröffnen eines Fehlerberichts werden automatisch die Fehlermeldung und Debugdaten eingefügt.\nBitte überprüfen Sie, ob die Informationen korrrekt sind und entfernen Sie ggfs. sensible Daten.', - recoveredEntry: { - heading: 'Wiederhergestellter Beitrag', - warning: 'Bitte sichern Sie sich diese Informationen, bevor Sie die Seite verlassen!', - copyButtonLabel: 'In Zwischenablage speichern', - }, - }, - settingsDropdown: { - logOut: 'Abmelden', - }, - toast: { - onFailToLoadEntries: 'Beitrag konnte nicht geladen werden: %{details}', - onFailToLoadDeployPreview: 'Vorschau konnte nicht geladen werden: %{details}', - onFailToPersist: 'Beitrag speichern fehlgeschlagen: %{details}', - onFailToDelete: 'Beitrag löschen fehlgeschlagen: %{details}', - onFailToUpdateStatus: 'Status aktualisieren fehlgeschlagen: %{details}', - missingRequiredField: 'Oops, einige zwingend erforderliche Felder sind nicht ausgefüllt.', - entrySaved: 'Beitrag gespeichert', - entryPublished: 'Beitrag veröffentlicht', - entryUnpublished: 'Beitrag nicht mehr öffentlich', - onFailToPublishEntry: 'Veröffentlichen fehlgeschlagen: %{details}', - onFailToUnpublishEntry: - 'Veröffentlichung des Beitrags konnte nicht rückgängig gemacht werden: %{details}', - entryUpdated: 'Beitragsstatus aktualisiert', - onDeleteUnpublishedChanges: 'Unveröffentlichte Änderungen verworfen', - onFailToAuth: '%{details}', - onLoggedOut: - 'Sie wurden ausgeloggt. Bitte sichern Sie Ihre Daten und melden Sie sich erneut an.', - onBackendDown: - 'Der Server ist aktuell nicht erreichbar. Für weitere Informationen, siehe: %{details}', - }, - }, - workflow: { - workflow: { - loading: 'Arbeitsablauf Beiträge laden', - workflowHeading: 'Redaktioneller Arbeitsablauf', - newPost: 'Neuer Beitrag', - description: - '%{smart_count} Beitrag zur Überprüfung bereit, %{readyCount} bereit zur Veröffentlichung. |||| %{smart_count} Beiträge zur Überprüfung bereit, %{readyCount} bereit zur Veröffentlichung. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} von %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'von %{author}', - deleteChanges: 'Änderungen verwerfen', - deleteNewEntry: 'Lösche neuen Beitrag', - publishChanges: 'Veröffentliche Änderungen', - publishNewEntry: 'Veröffentliche neuen Beitrag', - }, - workflowList: { - onDeleteEntry: 'Soll dieser Beitrag wirklich gelöscht werden?', - onPublishingNotReadyEntry: - 'Nur Beiträge im Status "Abgeschlossen" können veröffentlicht werden. Bitte ziehen Sie den Beitrag in die "Abgeschlossen" Spalte um die Veröffentlichung zu aktivieren.', - onPublishEntry: 'Soll dieser Beitrag wirklich veröffentlicht werden soll?', - draftHeader: 'Entwurf', - inReviewHeader: 'In Prüfung', - readyHeader: 'Abgeschlossen', - currentEntries: '%{smart_count} Beitrag |||| %{smart_count} Beiträge', - }, - }, -}; - -export default de; diff --git a/packages/netlify-cms-locales/src/es/index.js b/packages/netlify-cms-locales/src/es/index.js deleted file mode 100644 index d8d1558e..00000000 --- a/packages/netlify-cms-locales/src/es/index.js +++ /dev/null @@ -1,259 +0,0 @@ -const es = { - auth: { - login: 'Iniciar sesión', - loggingIn: 'Iniciando sesión...', - loginWithNetlifyIdentity: 'Iniciar sesión con Netlify Identity', - loginWithBitbucket: 'Iniciar sesión con Bitbucket', - loginWithGitHub: 'Iniciar sesión con GitHub', - loginWithGitLab: 'Iniciar sesión con GitLab', - errors: { - email: 'Asegúrate de introducir tu correo electrónico.', - password: 'Por favor introduce tu contraseña.', - identitySettings: - 'No se pudo acceder a la configuración de Identity. Cuando uses el backend git-gateway asegurate de habilitar el servicio Identity y Git Gateway.', - }, - }, - app: { - header: { - content: 'Contenido', - workflow: 'Flujo Editorial', - media: 'Medios', - quickAdd: 'Añadir rápido', - }, - app: { - errorHeader: 'Error al cargar la configuración del CMS', - configErrors: 'Errores de configuración', - checkConfigYml: 'Compruebe el archivo config.yml.', - loadingConfig: 'Cargando configuración....', - waitingBackend: 'Esperando al servidor...', - }, - notFoundPage: { - header: 'No encontrado', - }, - }, - collection: { - sidebar: { - collections: 'Colecciones', - searchAll: 'Buscar todas', - }, - collectionTop: { - sortBy: 'Ordenar por', - viewAs: 'Ver como', - newButton: 'Nuevo %{collectionLabel}', - ascending: 'Ascendente', - descending: 'Descendente', - }, - entries: { - loadingEntries: 'Cargando entradas', - cachingEntries: 'Almacenando entradas en caché', - longerLoading: 'Esto puede tardar varios minutos', - noEntries: 'Ninguna entrada', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Actualizado en', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opcional', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} es obligatorio.', - regexPattern: '%{fieldLabel} no coincide con el patrón: %{pattern}.', - processing: '%{fieldLabel} está procesando.', - range: '%{fieldLabel} debe estar entre %{minValue} y %{maxValue}.', - min: '%{fieldLabel} debe ser por lo menos %{minValue}.', - max: '%{fieldLabel} debe ser %{maxValue} o menos.', - rangeCount: '%{fieldLabel} debe tener entre %{minCount} y %{maxCount} elemento(s).', - rangeCountExact: '%{fieldLabel} debe tener exactamente %{count} elemento(s).', - rangeMin: '%{fieldLabel} debe ser por lo menos %{minCount} elemento(s).', - rangeMax: '%{fieldLabel} debe ser %{maxCount} o menos elemento(s).', - }, - }, - editor: { - onLeavePage: '¿Estás seguro de que quieres dejar esta página?', - onUpdatingWithUnsavedChanges: - 'Tiene cambios no guardados, por favor, guárdelos antes de actualizar el estado.', - onPublishingNotReady: 'Por favor, actualice el estado a "Ready" antes de publicar.', - onPublishingWithUnsavedChanges: - 'Tiene cambios no guardados, por favor guárdelos antes de publicarlos.', - onPublishing: '¿Estás seguro de que quieres publicar esta entrada?', - onUnpublishing: '¿Estás seguro de que quieres retirar esta entrada?', - onDeleteWithUnsavedChanges: - '¿Está seguro de que desea eliminar esta entrada publicada, así como los cambios no guardados de la sesión actual?', - onDeletePublishedEntry: '¿Estás seguro de que quieres borrar esta entrada publicada?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Esto eliminará todos los cambios no publicados de esta entrada, así como los cambios no guardados de la sesión actual. ¿Todavía quieres borrar?', - onDeleteUnpublishedChanges: - 'Todos los cambios no publicados en esta entrada serán eliminados. ¿Todavía quieres borrar?', - loadingEntry: 'Cargando entrada...', - confirmLoadBackup: - 'Se recuperó una copia de seguridad local para esta entrada, ¿le gustaría utilizarla?', - }, - editorToolbar: { - publishing: 'Publicando...', - publish: 'Publicar', - published: 'Publicado', - unpublish: 'Retirar', - duplicate: 'Duplicar', - unpublishing: 'Retirando...', - publishAndCreateNew: 'Publicar y crear nuevo', - publishAndDuplicate: 'Publicar y duplicar', - deleteUnpublishedChanges: 'Eliminar cambios no publicados', - deleteUnpublishedEntry: 'Eliminar entrada no publicada', - deletePublishedEntry: 'Eliminar entrada publicada', - deleteEntry: 'Eliminar entrada', - saving: 'Guardando...', - save: 'Guardar', - deleting: 'Eliminando...', - updating: 'Actualizando...', - status: 'Estado: %{status}', - backCollection: ' Escribiendo en la colección %{collectionLabel}', - unsavedChanges: 'Cambios no guardados', - changesSaved: 'Cambios guardados', - draft: 'Borrador', - inReview: 'En revisión', - ready: 'Listo', - publishNow: 'Publicar ahora', - deployPreviewPendingButtonLabel: 'Comprobar Vista Previa', - deployPreviewButtonLabel: 'Ver Vista Previa', - deployButtonLabel: 'Ver publicación', - }, - editorWidgets: { - markdown: { - richText: 'Texto enriquecido', - markdown: 'Markdown', - }, - image: { - choose: 'Elige una imagen', - chooseDifferent: 'Elige una imagen diferente', - remove: 'Quita la imagen', - }, - file: { - choose: 'Escoge un archivo', - chooseDifferent: 'Elige un archivo diferente', - remove: 'Remover archivo', - }, - unknownControl: { - noControl: "No existe un control para el widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "No existe una vista previa para el widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Encabezado 1', - headingTwo: 'Encabezado 2', - headingThree: 'Encabezado 3', - headingFour: 'Encabezado 4', - headingFive: 'Encabezado 5', - headingSix: 'Encabezado 6', - }, - datetime: { - now: 'Ahora', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Borrador', - }, - mediaLibrary: { - onDelete: '¿Está seguro de que desea eliminar el archivo seleccionado?', - fileTooLarge: - 'Archivo muy pesado.\nConfigurado para no permitir archivos más pesados que %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Cargando...', - noResults: 'Sin resultados.', - noAssetsFound: 'Archivos no encontrados.', - noImagesFound: 'Imágenes no encontradas.', - private: 'Privado ', - images: 'Imágenes', - mediaAssets: 'Archivos multimedia', - search: 'Buscar...', - uploading: 'Subiendo...', - upload: 'Subir nuevo', - download: 'Descargar', - deleting: 'Eliminando...', - deleteSelected: 'Eliminar selección', - chooseSelected: 'Confirmar selección', - }, - }, - ui: { - default: { - goBackToSite: 'Regresar al sitio', - }, - errorBoundary: { - title: 'Error', - details: 'Se ha producido un error - por favor ', - reportIt: 'infórmenos de ello.', - detailsHeading: 'Detalles', - privacyWarning: - 'Abrir un reporte lo rellena previamente con el mensaje de error y los datos de depuración.\nPor favor verifica que la información es correcta y elimina cualquier dato sensible.', - recoveredEntry: { - heading: 'Documento recuperado', - warning: '¡Por favor, copie/pegue esto en algún lugar antes de ir a otra página!', - copyButtonLabel: 'Copiar al portapapeles', - }, - }, - settingsDropdown: { - logOut: 'Cerrar sesión', - }, - toast: { - onFailToLoadEntries: 'No se ha podido cargar la entrada: %{details}', - onFailToLoadDeployPreview: 'No se ha podido cargar la vista previa: %{details}', - onFailToPersist: 'No se ha podido guardar la entrada: %{details}', - onFailToDelete: 'No se ha podido borrar la entrada: %{details}', - onFailToUpdateStatus: 'No se ha podido actualizar el estado: %{details}', - missingRequiredField: - 'Oops, no ha rellenado un campo obligatorio. Por favor, rellénelo antes de guardar.', - entrySaved: 'Entrada guardada', - entryPublished: 'Entrada publicada', - entryUnpublished: 'Entrada retirada', - onFailToPublishEntry: 'No se ha podido publicar: %{details}', - onFailToUnpublishEntry: 'No se ha podido retirar la entrada: %{details}', - entryUpdated: 'Estado de entrada actualizado', - onDeleteUnpublishedChanges: 'Cambios no publicados eliminados', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Cargando Entradas del Flujo Editorial', - workflowHeading: 'Flujo Editorial', - newPost: 'Nuevo artículo', - description: - '%{smart_count} entrada esperando revisión, %{readyCount} lista para publicar |||| %{smart_count} entradas esperando revisión, %{readyCount} listas para publicar. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} por %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'por %{author}', - deleteChanges: 'Eliminar cambios', - deleteNewEntry: 'Eliminar nueva entrada', - publishChanges: 'Publicar cambios', - publishNewEntry: 'Publicar nueva entrada', - }, - workflowList: { - onDeleteEntry: '¿Está seguro de que quiere borrar esta entrada?', - onPublishingNotReadyEntry: - 'Sólo se pueden publicar los elementos con el estado "Listo". Por favor, arrastre la tarjeta hasta la columna "Listo" para permitir la publicación.', - onPublishEntry: '¿Estás seguro de que quieres publicar esta entrada?', - draftHeader: 'Borradores', - inReviewHeader: 'En revisión', - readyHeader: 'Listo', - currentEntries: '%{smart_count} entrada |||| %{smart_count} entradas', - }, - }, -}; - -export default es; diff --git a/packages/netlify-cms-locales/src/fr/index.js b/packages/netlify-cms-locales/src/fr/index.js deleted file mode 100644 index 206710fa..00000000 --- a/packages/netlify-cms-locales/src/fr/index.js +++ /dev/null @@ -1,308 +0,0 @@ -const fr = { - auth: { - login: 'Se connecter', - loggingIn: 'Connexion en cours...', - loginWithNetlifyIdentity: 'Se connecter avec Netlify Identity', - loginWithAzure: 'Se connecter avec Azure', - loginWithBitbucket: 'Se connecter avec Bitbucket', - loginWithGitHub: 'Se connecter avec GitHub', - loginWithGitLab: 'Se connecter avec GitLab', - errors: { - email: "Assurez-vous d'avoir entré votre email.", - password: 'Merci de saisir votre mot de passe.', - identitySettings: - "Impsosible d'accéder aux paramètres d'identité. Si vous utilisez le backend git-gateway, merci de vous assurer que vous avez bien activé le service Identity et la passerelle Git.", - }, - }, - app: { - header: { - content: 'Contenus', - workflow: 'Flux', - media: 'Media', - quickAdd: 'Ajout rapide', - }, - app: { - errorHeader: 'Erreur au chargement de la configuration du CMS', - configErrors: 'Erreurs de configuration', - checkConfigYml: 'Vérifiez votre fichier config.yml.', - loadingConfig: 'Chargement de la configuration...', - waitingBackend: 'En attente du serveur...', - }, - notFoundPage: { - header: 'Introuvable', - }, - }, - collection: { - sidebar: { - collections: 'Collections', - allCollections: 'Toutes les collections', - searchAll: 'Tout rechercher', - searchIn: 'Rechercher dans', - }, - collectionTop: { - sortBy: 'Trier par', - viewAs: 'Voir comme', - newButton: 'Créer une entrée de type %{collectionLabel}', - ascending: 'Croissant', - descending: 'Décroissant', - searchResults: 'Résultats de la recherche pour "%{searchTerm}"', - searchResultsInCollection: - 'Résultats de la recherche pour "%{searchTerm}" dans %{collection}', - filterBy: 'Filtrer par', - groupBy: 'Grouper par', - }, - entries: { - loadingEntries: 'Chargement des entrées', - cachingEntries: 'Mise en cache des entrées', - longerLoading: 'Cela peut prendre quelques minutes', - noEntries: 'Aucune entrée', - }, - groups: { - other: 'Autre', - negateLabel: 'Non %{label}', - }, - defaultFields: { - author: { - label: 'Auteur', - }, - updatedOn: { - label: 'Mis à jour le', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'optionnel', - }, - }, - editorControlPane: { - widget: { - required: 'Le champ %{fieldLabel} est requis.', - regexPattern: 'Le champ %{fieldLabel} ne correspond pas au schéma: %{pattern}.', - processing: 'Le champ %{fieldLabel} est en cours de traitement.', - range: 'Le champ %{fieldLabel} doit être compris entre %{minValue} et %{maxValue}.', - min: 'Le champ %{fieldLabel} doit avoir une valeur de %{minValue} ou plus.', - max: 'Le champ %{fieldLabel} doit avoir une valeur de %{maxValue} ou moins.', - rangeCount: '%{fieldLabel} doit avoir entre %{minCount} et %{maxCount} élément(s).', - rangeCountExact: '%{fieldLabel} doit avoir exactement %{count} éléments(s).', - rangeMin: '%{fieldLabel} doit avoir au moins %{minCount} éléments(s).', - rangeMax: '%{fieldLabel} doit avoir %{maxCount} éléments(s) ou moins.', - invalidPath: `'%{path}' n'est pas un chemin valide`, - pathExists: `Le chemin '%{path}' existe déjà`, - }, - i18n: { - writingInLocale: 'Écrire en %{locale}', - }, - }, - editor: { - onLeavePage: 'Voulez-vous vraiment quitter cette page ?', - onUpdatingWithUnsavedChanges: - 'Veuillez enregistrer vos modifications avant de mettre à jour le statut.', - onPublishingNotReady: 'Veuillez mettre à jour le statut à "Prêt" avant de publier.', - onPublishingWithUnsavedChanges: 'Veuillez enregistrer vos modifications avant de publier.', - onPublishing: 'Voulez-vous vraiment publier cette entrée ?', - onUnpublishing: 'Voulez-vous vraiment dépublier cette entrée ?', - onDeleteWithUnsavedChanges: - 'Voulez-vous vraiment supprimer cette entrée publiée ainsi que vos modifications non enregistrées de cette session ?', - onDeletePublishedEntry: 'Voulez-vous vraiment supprimer cette entrée publiée ?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Ceci supprimera toutes les modifications non publiées de cette entrée ainsi que vos modifications non enregistrées de cette session. Voulez-vous toujours supprimer ?', - onDeleteUnpublishedChanges: - 'Toutes les modifications non publiées de cette entrée seront supprimées. Voulez-vous toujours supprimer ?', - loadingEntry: "Chargement de l'entrée...", - confirmLoadBackup: - "Une sauvegarde locale a été trouvée pour cette entrée. Voulez-vous l'utiliser ?", - }, - editorInterface: { - toggleI18n: 'Édition multilingue', - togglePreview: 'Aperçu', - toggleScrollSync: 'Défilement synchronisé', - }, - editorToolbar: { - publishing: 'Publication...', - publish: 'Publier', - published: 'Publiée', - unpublish: 'Dépublier', - duplicate: 'Dupliquer', - unpublishing: 'Dépublication...', - publishAndCreateNew: 'Publier et créer une nouvelle entrée', - publishAndDuplicate: 'Publier et dupliquer', - deleteUnpublishedChanges: 'Supprimer les modications non publiées', - deleteUnpublishedEntry: "Supprimer l'entrée non publiée", - deletePublishedEntry: "Supprimer l'entrée publiée", - deleteEntry: "Supprimer l'entrée", - saving: 'Enregistrement...', - save: 'Enregistrer', - deleting: 'Suppression...', - updating: 'Mise à jour...', - status: 'Statut: %{status}', - backCollection: ' Écriture dans la collection %{collectionLabel}', - unsavedChanges: 'Modifications non enregistrées', - changesSaved: 'Modifications enregistrées', - draft: 'Brouillon', - inReview: 'En cours de révision', - ready: 'Prêt', - publishNow: 'Publier maintenant', - deployPreviewPendingButtonLabel: "Vérifier l'aperçu", - deployPreviewButtonLabel: "Voir l'aperçu", - deployButtonLabel: 'Voir en direct', - }, - editorWidgets: { - markdown: { - bold: 'Gras', - italic: 'Italique', - code: 'Code', - link: 'Lien', - linkPrompt: "Entrer l'adresse web du lien", - headings: 'Titres', - quote: 'Citation', - bulletedList: 'Liste à puces', - numberedList: 'Liste numérotée', - addComponent: 'Ajouter un composant', - richText: 'Texte enrichi', - markdown: 'Markdown', - }, - image: { - choose: 'Choisir une image', - chooseUrl: 'Insérer depuis une adresse web', - replaceUrl: 'Remplacer depuis une adresse web', - promptUrl: "Entrer l'adresse web de l'image", - chooseDifferent: 'Choisir une image différente', - remove: "Supprimer l'image", - }, - file: { - choose: 'Choisir un fichier', - chooseUrl: 'Insérer depuis une adresse web', - replaceUrl: 'Remplacer depuis une adresse web', - promptUrl: "Entrer l'adresse web du fichier", - chooseDifferent: 'Choisir un fichier différent', - remove: 'Effacer le fichier', - }, - unknownControl: { - noControl: "Pas de contrôle pour le gadget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Pas d'aperçu pour le gadget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Titre 1', - headingTwo: 'Titre 2', - headingThree: 'Titre 3', - headingFour: 'Titre 4', - headingFive: 'Titre 5', - headingSix: 'Titre 6', - }, - datetime: { - now: 'Maintenant', - }, - list: { - add: 'Ajouter %{item}', - addType: 'Ajouter une entrée de type %{item}', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Brouillon', - copy: 'Copier', - copyUrl: "Copier l'adresse web", - copyPath: "Copier le chemin d'accès", - copyName: 'Copier le nom', - copied: 'Copié', - }, - mediaLibrary: { - onDelete: 'Voulez-vous vraiment supprimer la ressource sélectionné ?', - fileTooLarge: - "Le fichier est trop volumineux.\nL'instance est configurée pour bloquer les envois de plus de %{size} kB.", - }, - mediaLibraryModal: { - loading: 'Chargement...', - noResults: 'Aucun résultat.', - noAssetsFound: 'Aucune ressource trouvée.', - noImagesFound: 'Aucune image trouvée.', - private: 'Privé ', - images: 'Images', - mediaAssets: 'Ressources', - search: 'Recherche...', - uploading: 'Téléversement...', - upload: 'Téléverser une nouvelle ressource', - download: 'Télécharger', - deleting: 'Suppression...', - deleteSelected: 'Supprimer les éléments sélectionnés', - chooseSelected: 'Choisir les éléments sélectionnés', - }, - }, - ui: { - default: { - goBackToSite: 'Retourner sur le site', - }, - errorBoundary: { - title: 'Erreur', - details: 'Une erreur est survenue, veuillez ', - reportIt: 'la signaler sur GitHub.', - detailsHeading: 'Détails', - privacyWarning: - "Ouvrir une issue la préremplie avec le message d'erreur et des données de déboggage.\nMerci de vérifier l'exactitude des informations et de supprimer toute donnée sensible si nécessaire.", - recoveredEntry: { - heading: 'Document récupéré', - warning: 'Veuillez copier/coller ceci quelque part avant de naviguer ailleurs!', - copyButtonLabel: 'Copier dans le presse-papier', - }, - }, - settingsDropdown: { - logOut: 'Déconnexion', - }, - toast: { - onFailToLoadEntries: "Échec du chargement de l'entrée : %{details}", - onFailToLoadDeployPreview: "Échec du chargement de l'aperçu : %{details}", - onFailToPersist: "Échec de l'enregistrement de l'entrée : %{details}", - onFailToDelete: "Échec de la suppression de l'entrée : %{details}", - onFailToUpdateStatus: 'Échec de la mise à jour du statut : %{details}', - missingRequiredField: - 'Oops, il manque un champ requis. Veuillez le renseigner avant de soumettre.', - entrySaved: 'Entrée enregistrée', - entryPublished: 'Entrée publiée', - entryUnpublished: 'Entrée dépubliée', - onFailToPublishEntry: 'Échec de la publication : %{details}', - onFailToUnpublishEntry: "Impossible de dépublier l'entrée : %{details}", - entryUpdated: "Statut de l'entrée mis à jour", - onDeleteUnpublishedChanges: 'Modifications non publiées supprimées', - onFailToAuth: '%{details}', - onLoggedOut: 'Vous avez été déconnecté, merci de sauvegarder les données et vous reconnecter', - onBackendDown: - "Le serveur est actuellement hors-service. Pour plus d'informations : %{details}", - }, - }, - workflow: { - workflow: { - loading: 'Chargement des entrées du flux éditorial', - workflowHeading: 'Flux éditorial', - newPost: 'Nouvel article', - description: - '%{smart_count} entrée(s) en attente de revue, %{readyCount} prête(s) à être publiée(s). |||| %{smart_count} entrée(s) en attente de revue, %{readyCount} prête(s) à être publiée(s). ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} par %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'par %{author}', - deleteChanges: 'Supprimer les mofications', - deleteNewEntry: 'Supprimer la nouvelle entrée', - publishChanges: 'Publier les modifications', - publishNewEntry: 'Publier la nouvelle entrée', - }, - workflowList: { - onDeleteEntry: 'Voulez-vous vraiment supprimer cette entrée ?', - onPublishingNotReadyEntry: - 'Seuls les éléments ayant le statut "Prêt" peuvent être publiés. Veuillez glisser/déposer la carte dans la colonne "Prêt" pour activer la publication', - onPublishEntry: 'Voulez-vous vraiment publier cette entrée ?', - draftHeader: 'Brouillons', - inReviewHeader: 'En cours de révision', - readyHeader: 'Prêt', - currentEntries: '%{smart_count} entrée |||| %{smart_count} entrées', - }, - }, -}; - -export default fr; diff --git a/packages/netlify-cms-locales/src/gr/index.js b/packages/netlify-cms-locales/src/gr/index.js deleted file mode 100644 index 9b52888c..00000000 --- a/packages/netlify-cms-locales/src/gr/index.js +++ /dev/null @@ -1,232 +0,0 @@ -const gr = { - auth: { - login: 'Σύνδεση', - loggingIn: 'Σύνδεση στο...', - loginWithNetlifyIdentity: 'Σύνδεση μέσω Netlify', - loginWithBitbucket: 'Σύνδεση μέσω Bitbucket', - loginWithGitHub: 'Σύνδεση μέσω GitHub', - loginWithGitLab: 'Σύνδεση μέσω GitLab', - errors: { - email: 'Βεβαιωθείτε ότι έχετε εισαγάγει το email σας.', - password: 'Παρακαλώ εισάγετε τον κωδικό πρόσβασής σας.', - identitySettings: - 'Δεν είναι δυνατή η πρόσβαση στις ρυθμίσεις ταυτότητας. Όταν χρησιμοποιείτε το παρασκήνιο του git Gateway, φροντίστε να ενεργοποιήσετε την υπηρεσία Identity και το git Gateway.', - }, - }, - app: { - header: { - content: 'Περιεχόμενα', - workflow: 'Ροής εργασίας', - media: 'Πολυμέσα', - quickAdd: 'Γρήγορη προσθήκη', - }, - app: { - errorHeader: 'Σφάλμα κατά τη φόρτωση της ρύθμισης παραμέτρων CMS', - configErrors: 'Σφάλματα ρύθμισης παραμέτρων', - checkConfigYml: 'Ελέγξτε το αρχείο config.yml.', - loadingConfig: 'Φόρτωση ρύθμισης παραμέτρων...', - waitingBackend: 'Αναμονή για παρασκηνιακό...', - }, - notFoundPage: { - header: 'Δεν βρέθηκε', - }, - }, - collection: { - sidebar: { - collections: 'Συλλογές', - searchAll: 'Αναζήτηση όλων', - }, - collectionTop: { - viewAs: 'Προβολή ως', - newButton: 'Νέο %{collectionLabel}', - }, - entries: { - loadingEntries: 'Εγγραφές φόρτωσης', - cachingEntries: 'Εγγραφές προσωρινής αποθήκευσης', - longerLoading: 'Αυτό μπορεί να διαρκέσει αρκετά λεπτά', - }, - }, - editor: { - editorControl: { - field: { - optional: 'προαιρετικός', - }, - }, - editorControlPane: { - widget: { - required: 'Το %{fieldLabel} είναι απαραίτητο.', - regexPattern: 'Το %{fieldLabel} δεν ταιριάζει με το μοτίβο: %{pattern}.', - processing: 'Το %{fieldLabel} επεξεργάζεται.', - range: 'Το %{fieldLabel} πρέπει να είναι μεταξύ %{minValue} και %{maxValue}.', - min: 'Το %{fieldLabel} πρέπει να είναι τουλάχιστον %{minValue}.', - max: 'Το %{fieldLabel} πρέπει να είναι %{maxValue} ή μικρότερο.', - }, - }, - editor: { - onLeavePage: 'Είστε βέβαιοι ότι θέλετε να αφήσετε αυτήν τη σελίδα;', - onUpdatingWithUnsavedChanges: - 'Έχετε μη αποθηκευμένες αλλαγές, αποθηκεύστε πριν να ενημερώσετε την κατάσταση.', - onPublishingNotReady: 'Ενημερώστε την κατάσταση σε "έτοιμο" πριν από τη δημοσίευση.', - onPublishingWithUnsavedChanges: - 'Έχετε μη αποθηκευμένες αλλαγές, αποθηκεύστε πριν από τη δημοσίευση.', - onPublishing: 'Είστε βέβαιοι ότι θέλετε να δημοσιεύσετε αυτήν την καταχώρηση;', - onUnpublishing: - 'Είστε βέβαιοι ότι θέλετε να καταργήσετε τη δημοσίευση αυτής της καταχώρησης;', - onDeleteWithUnsavedChanges: - 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη δημοσιευμένη καταχώρηση, καθώς και τις αλλαγές που δεν αποθηκεύσατε από την τρέχουσα περίοδο λειτουργίας;', - onDeletePublishedEntry: - 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν τη δημοσιευμένη καταχώρηση;', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Αυτό θα διαγράψει όλες τις μη δημοσιευμένες αλλαγές σε αυτήν την καταχώρηση, καθώς και τις αλλαγές που δεν έχετε αποθηκεύσει από την τρέχουσα περίοδο λειτουργίας. Θέλετε ακόμα να διαγράψετε;', - onDeleteUnpublishedChanges: - 'Όλες οι μη δημοσιευμένες αλλαγές σε αυτήν την καταχώρηση θα διαγραφούν. Θέλετε ακόμα να διαγράψετε;', - loadingEntry: 'Φόρτωση εισόδου...', - confirmLoadBackup: - 'Ανακτήθηκε ένα τοπικό αντίγραφο ασφαλείας για αυτήν την καταχώρηση, θέλετε να το χρησιμοποιήσετε;', - }, - editorToolbar: { - publishing: 'Δημοσίευση...', - publish: 'Δημοσίευση', - published: 'Δημοσιεύθηκε', - unpublish: 'Κατάργηση δημοσίευσης', - duplicate: 'Διπλότυπο', - unpublishing: 'Κατάργηση δημοσίευσης...', - publishAndCreateNew: 'Δημοσίευση και δημιουργία νέων', - publishAndDuplicate: 'Δημοσίευση και αντίγραφο', - deleteUnpublishedChanges: 'Διαγραφή μη δημοσιευμένων αλλαγών', - deleteUnpublishedEntry: 'Διαγραφή μη δημοσιευμένης καταχώρησης', - deletePublishedEntry: 'Διαγραφή δημοσιευμένης καταχώρησης', - deleteEntry: 'Διαγραφή καταχώρησης', - saving: 'Εξοικονόμηση...', - save: 'Αποθήκευση', - deleting: 'Διαγραφή...', - updating: 'Ενημέρωση...', - status: 'Κατάστασης: %{status}', - backCollection: ' Εγγραφή στη συλλογή %{collectionLabel}', - unsavedChanges: 'Μη αποθηκευμένες αλλαγές', - changesSaved: 'Αλλαγές που αποθηκεύτηκαν', - draft: 'Σχέδιο', - inReview: 'Σε επανεξέταση', - ready: 'Έτοιμα', - publishNow: 'Δημοσίευση τώρα', - deployPreviewPendingButtonLabel: 'Έλεγχος για προεπισκόπηση', - deployPreviewButtonLabel: 'Προβολή προεπισκόπησης', - deployButtonLabel: 'Προβολή Live', - }, - editorWidgets: { - image: { - choose: 'Επιλέξτε μια εικόνα', - chooseDifferent: 'Επιλέξτε διαφορετική εικόνα', - remove: 'Αφαιρέστε την εικόνα', - }, - file: { - choose: 'Επιλέξτε ένα αρχείο', - chooseDifferent: 'Επιλέξτε διαφορετικό αρχείο', - remove: 'Αφαιρέστε το αρχείο', - }, - unknownControl: { - noControl: "Δεν υπάρχει έλεγχος για το widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Δεν υπάρχει προεπισκόπηση για το widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Προσχέδιο', - }, - mediaLibrary: { - onDelete: 'Είστε βέβαιοι ότι θέλετε να διαγράψετε τα επιλεγμένα πολυμέσα;', - fileTooLarge: - 'Το αρχείο είναι πολύ μεγάλο.\nΔεν επιτρέπονται αρχεία μεγαλύτερα από %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Φόρτωση...', - noResults: 'Χωρίς αποτελέσματα.', - noAssetsFound: 'Δεν βρέθηκαν αρχεία.', - noImagesFound: 'Δεν βρέθηκαν εικόνες.', - private: 'Ιδιωτικό', - images: 'Εικόνες', - mediaAssets: 'Αρχεία πολυμέσων', - search: 'Αναζήτηση...', - uploading: 'Φόρτωμα...', - upload: 'Ανεβάστε νέα', - deleting: 'Διαγραφή...', - deleteSelected: 'Διαγραφή επιλεγμένου', - chooseSelected: 'Επιλέξτε επιλεγμένο', - }, - }, - ui: { - errorBoundary: { - title: 'Σφάλμα', - details: 'Υπάρχει ένα λάθος ', - reportIt: 'παρακαλώ να το αναφέρετε.', - detailsHeading: 'Λεπτομέρειες', - recoveredEntry: { - heading: 'Ανακτημένο έγγραφο', - warning: 'Παρακαλώ αντιγράψτε/επικολλήστε αυτό κάπου πριν πλοηγηθείτε μακριά!', - copyButtonLabel: 'Αντιγραφή στο Πρόχειρο', - }, - }, - settingsDropdown: { - logOut: 'Αποσύνδεση', - }, - toast: { - onFailToLoadEntries: 'Απέτυχε η φόρτωση της καταχώρησης: %{details}', - onFailToLoadDeployPreview: 'Απέτυχε η φόρτωση της προεπισκόπησης: %{details}', - onFailToPersist: 'Απέτυχε η διατήρηση της καταχώρησης:% {Details}', - onFailToDelete: 'Απέτυχε η διαγραφή της καταχώρησης: %{details}', - onFailToUpdateStatus: 'Απέτυχε η ενημέρωση της κατάστασης: %{details}', - missingRequiredField: - 'Ουπς, ξεχάσατε ένα απαιτούμενο πεδίο. Συμπληρώστε το πριν από την αποθήκευση.', - entrySaved: 'Η καταχώρηση Αποθηκεύτηκε', - entryPublished: 'Η καταχώρηση δημοσιεύτηκε', - entryUnpublished: 'Μη δημοσιευμένη καταχώρηση', - onFailToPublishEntry: 'Η δημοσίευση απέτυχε: %{details}', - onFailToUnpublishEntry: 'Απέτυχε η κατάργηση δημοσίευσης καταχώρησης: %{details}', - entryUpdated: 'Η κατάσταση εισόδου ενημερώθηκε', - onDeleteUnpublishedChanges: 'Οι μη δημοσιευμένες αλλαγές διαγράφηκαν', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Φόρτωση καταχωρήσεων ροής εργασίας σύνταξης', - workflowHeading: 'Ροή εργασιών', - newPost: 'Νέα δημοσίευση', - description: - '%{smart_count} καταχώρησεις σε αναμονή για αναθεώρηση, %{readyCount} έτοιμες για Live μετάβαση. |||| %{smart_count} καταχωρήσεις σε αναμονή για αναθεώρηση, %{readyCount} έτοιμες για Live μετάβαση. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} από %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'από %{author}', - deleteChanges: 'Διαγραφή αλλαγών', - deleteNewEntry: 'Διαγραφή νέας καταχώρησης', - publishChanges: 'Δημοσίευση αλλαγών', - publishNewEntry: 'Δημοσίευση νέας καταχώρησης', - }, - workflowList: { - onDeleteEntry: 'Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτήν την καταχώρηση;', - onPublishingNotReadyEntry: - 'Μόνο τα στοιχεία με κατάσταση "Ready" μπορούν να δημοσιευτούν. Σύρετε την κάρτα στη στήλη "έτοιμο" για να ενεργοποιήσετε τη δημοσίευση.', - onPublishEntry: 'Είστε βέβαιοι ότι θέλετε να δημοσιεύσετε αυτήν την καταχώρηση;', - draftHeader: 'Προσχέδια', - inReviewHeader: 'Σε ανασκόπηση', - readyHeader: 'Έτοιμα', - currentEntries: '%{smart_count} καταχωρηση |||| %{smart_count} καταχωρησεις', - }, - }, -}; - -export default gr; diff --git a/packages/netlify-cms-locales/src/he/index.js b/packages/netlify-cms-locales/src/he/index.js deleted file mode 100644 index 03c20edb..00000000 --- a/packages/netlify-cms-locales/src/he/index.js +++ /dev/null @@ -1,306 +0,0 @@ -const he = { - auth: { - login: 'התחברות', - loggingIn: 'התחברות...', - loginWithNetlifyIdentity: 'התחברות עם Netlify Identity', - loginWithAzure: 'התחברות עם Azure', - loginWithBitbucket: 'התחברות עם Bitbucket', - loginWithGitHub: 'התחברות עם GitHub', - loginWithGitLab: 'התחברות עם GitLab', - errors: { - email: 'נא לא לשכוח להקליד את כתובת המייל', - password: 'נא להקליד את הסיסמה.', - identitySettings: - 'הגדרות אימות הזהות אינן נגישות. כאשר משתמשים ב-git-gateway כשירות ה-backend יש לוודא ששירות אימות הזהות ו-Git Gateway הופעלו.', - }, - }, - app: { - header: { - content: 'תוכן', - workflow: 'ניהול אייטמים לפני הפרסום', - media: 'מדיה', - quickAdd: 'הוספה מהירה', - }, - app: { - errorHeader: 'אירעה שגיאה בטעינת הגדרות מערכת ניהול התוכן', - configErrors: 'שגיאות בהגדרות', - checkConfigYml: 'יש לבדוק את הקובץ config.yml.', - loadingConfig: 'טעינת הגדרות...', - waitingBackend: 'ממתין לטעינת ה-backend...', - }, - notFoundPage: { - header: 'לא נמצא', - }, - }, - collection: { - sidebar: { - collections: 'קטגוריות', - allCollections: 'כל הקטגוריות', - searchAll: 'חיפוש כללי', - searchIn: 'חיפוש בקטגוריית', - }, - collectionTop: { - sortBy: 'מיון לפי', - viewAs: 'תצוגה לפי', - newButton: 'חדש %{collectionLabel}', - ascending: 'בסדר עולה', - descending: 'בסדר יורד', - searchResults: 'תוצאות חיפוש עבור "%{searchTerm}"', - searchResultsInCollection: 'תוצאות חיפוש עבור "%{searchTerm}" ב%{collection}', - filterBy: 'סינון לפי', - groupBy: 'ארגון לפי', - }, - entries: { - loadingEntries: 'טעינת אייטמים...', - cachingEntries: 'שמירת אייטמים בזכרון המטמון', - longerLoading: 'התהליך עשוי להימשך כמה דקות', - noEntries: 'לא נמצאו אייטמים', - }, - groups: { - other: 'אחר', - negateLabel: 'לא %{label}', - }, - defaultFields: { - author: { - label: 'מאת', - }, - updatedOn: { - label: 'עודכן בתאריך', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'רשות', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} הוא שדה חובה.', - regexPattern: '%{fieldLabel} לא תואם לדפוס %{pattern}.', - processing: '%{fieldLabel} מעובד.', - range: '%{fieldLabel} חייב להיות בין %{minValue} לבין %{maxValue}.', - min: '%{fieldLabel} חייב להיות לפחות %{minValue}.', - max: '%{fieldLabel} חייב להיות %{maxValue} או פחות.', - rangeCount: '%{fieldLabel} חייב לכלול בין %{minCount} לבין %{maxCount} אייטמים.', - rangeCountExact: '%{fieldLabel} חייב לכלול בדיוק %{count} אייטמים.', - rangeMin: '%{fieldLabel} חייב לכלול לפחות %{minCount} אייטמים', - rangeMax: '%{fieldLabel} חייב לכלול %{maxCount} אייטמים לכל היותר.', - invalidPath: `'%{path}' אינו URL תקין`, - pathExists: `'%{path}' כבר קיים`, - }, - i18n: { - writingInLocale: 'כתיבה בשפה ה%{locale}', - }, - }, - editor: { - onLeavePage: 'האם ברצונך לעבור לעמוד אחר ללא שמירה?', - onUpdatingWithUnsavedChanges: 'בוצעו שינויים שלא נשמרו. יש לבצע שמירה לפני עדכון מצב האייטם.', - onPublishingNotReady: 'נא לשנות את מצב האייטם ל״מוכן לפרסום״ לפני הפרסום.', - onPublishingWithUnsavedChanges: 'בוצעו שינויים שלא נשמרו. יש לבצע שמירה לפני הפרסום.', - onPublishing: 'האם ברצונך לפרסם את האייטם?', - onUnpublishing: 'האם ברצונך לבטל את פרסום האייטם?', - onDeleteWithUnsavedChanges: - 'האם ברצונך למחוק את האייטם הזה לפני פרסומו, וכן את השינויים שבוצעו כעת וטרם נשמרו?', - onDeletePublishedEntry: 'האם ברצונך למחוק את האייטם הזה לאחר פרסומו?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'פעולה זו תמחק את כל השינויים שבוצעו באייטם זה ולא פורסמו, וכן את השינויים שבוצעו כעת וטרם נשמרו. האם ברצונך למחוק?', - onDeleteUnpublishedChanges: - 'כל השינויים שבוצעו באייטם זה ולא פורסמו יימחקו. האם ברצונך למחוק אותו?', - loadingEntry: 'טעינת אייטם...', - confirmLoadBackup: 'קיים עותק מקומי שמור של האייטם. האם ברצונך לטעון אותו?', - }, - editorInterface: { - toggleI18n: 'החלפת שפות', - togglePreview: 'הפעלת תצוגה מקדימה', - toggleScrollSync: 'סנכרון הגלילה', - }, - editorToolbar: { - publishing: 'פרסום...', - publish: 'פרסום', - published: 'פורסם', - unpublish: 'ביטול הפרסום', - duplicate: 'שכפול', - unpublishing: 'ביטול הפרסום...', - publishAndCreateNew: 'פרסום ויצירת אייטם חדש', - publishAndDuplicate: 'פרסום ושכפול', - deleteUnpublishedChanges: 'מחיקת השינויים שלא פורסמו', - deleteUnpublishedEntry: 'מחיקת אייטם שטרם פורסם', - deletePublishedEntry: 'מחיקת אייטם שפורסם', - deleteEntry: 'מחיקת האייטם', - saving: 'שמירה...', - save: 'שמירה', - statusInfoTooltipDraft: - 'האייטם מוגדר כטיוטה. כדי להשלים את הפעולה ולהעביר אותו למצב ״ממתין לאישור״ יש להעביר אותו למצב ״ממתין לאישור״', - statusInfoTooltipInReview: - 'האייטם ממתין לאישור - לא נדרשת פעולה נוספת. ניתן עדיין לבצע שינויים בעת שהאייטם ממתין לאישור.', - deleting: 'מחיקה...', - updating: 'עדכון...', - status: 'מצב: %{status}', - backCollection: 'כתיבה בקטגוריית %{collectionLabel}', - unsavedChanges: 'שינויים לא שמורים', - changesSaved: 'השינויים נשמרו', - draft: 'טיוטה', - inReview: 'ממתין לאישור', - ready: 'מוכן לפרסום', - publishNow: 'פרסום מיידי', - deployPreviewPendingButtonLabel: 'בדיקת תצוגה מקדימה', - deployPreviewButtonLabel: 'צפייה בתצוגה מקדימה', - deployButtonLabel: 'צפייה באתר', - }, - editorWidgets: { - markdown: { - bold: 'מודגש', - italic: 'נטוי', - code: 'קוד', - link: 'קישור', - linkPrompt: 'נא להקליד את הכתובת לקישור', - headings: 'כותרת', - quote: 'ציטוט', - bulletedList: 'רשימה לא-ממוספרת', - numberedList: 'רשימה ממוספרת', - addComponent: 'הוספת רכיב', - richText: 'טקסט עשיר', - markdown: 'Markdown', - }, - image: { - choose: 'בחירת תמונה', - chooseUrl: 'הוספה מכתובת אינטרנט', - replaceUrl: 'החלפת תמונה מכתובת אינטרנט', - promptUrl: 'נא להכניס את ה-URL של התמונה', - chooseDifferent: 'בחירת תמונה אחרת', - remove: 'הסרת תמונה', - }, - file: { - choose: 'בחירת קובץ', - chooseUrl: 'הוספה מכתובת אינטרנט', - replaceUrl: 'החלפת קובץ מכתובת אינטרנט', - promptUrl: 'נא להכניס את ה-URL של הקובץ', - chooseDifferent: 'בחירת קובץ אחר', - remove: 'הסרת קובץ', - }, - unknownControl: { - noControl: "לא הוגדרו פעולות ל'%{widget}'.", - }, - unknownPreview: { - noPreview: "אין תצוגה מקדימה ל'%{widget}'.", - }, - headingOptions: { - headingOne: 'כותרת 1', - headingTwo: 'כותרת 2', - headingThree: 'כותרת 3', - headingFour: 'כותרת 4', - headingFive: 'כותרת 5', - headingSix: 'כותרת 6', - }, - datetime: { - now: 'עכשיו', - }, - list: { - add: 'הוספת %{item}', - addType: 'הוספת אייטם מסוג %{item}', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'טיוטה', - copy: 'העתקה', - copyUrl: 'העתקת ה-URL', - copyPath: 'העתקת הנתיב', - copyName: 'העתקת השם', - copied: 'העתקה הושלמה', - }, - mediaLibrary: { - onDelete: 'האם ברצונך למחוק את פריט המדיה הזה?', - fileTooLarge: 'הקובץ גדול מדי.\nמוגדר לא לאפשר העלאת קבצים גדולים מ-%{size} קילובייט.', - }, - mediaLibraryModal: { - loading: 'טעינה...', - noResults: 'לא נמצאו תוצאות.', - noAssetsFound: 'לא נמצאו קבצים.', - noImagesFound: 'לא נמצאו תמונות.', - private: 'פרטי ', - images: 'תמונות', - mediaAssets: 'קבצי מדיה', - search: 'חיפוש...', - uploading: 'העלאה...', - upload: 'העלאה', - download: 'הורדה', - deleting: 'מחיקה...', - deleteSelected: 'למחוק את הקובץ המסומן', - chooseSelected: 'לבחור את הקובץ המסומן', - }, - }, - ui: { - default: { - goBackToSite: 'בחזרה לאתר', - }, - errorBoundary: { - title: 'שגיאה', - details: 'אירעה שגיאה. נא ', - reportIt: 'דווחו על הבעיה ב-GitHub.', - detailsHeading: 'פרטים', - privacyWarning: - 'פתיחת Issue מעתיקה את הודעת השגיאה ונתונים רלוונטיים לאיתור הבעיה (debugging).\nיש לוודא שהמידע מדויק ולמחוק נתונים אישיים כלשהם.', - recoveredEntry: { - heading: 'מסמך משוחזר', - warning: 'נא להעתיק ולהדביק את זה לפני ניווט לחלון אחר!', - copyButtonLabel: 'העתקה', - }, - }, - settingsDropdown: { - logOut: 'התנתקות', - }, - toast: { - onFailToLoadEntries: 'טעינת האייטם %{details} נכשלה', - onFailToLoadDeployPreview: 'טעינת התצוגה המקדימה של האייטם %{details} נכשלה', - onFailToPersist: 'אחסון האייטם %{details} נכשל', - onFailToDelete: 'מחיקת האייטם %{details} נכשלה', - onFailToUpdateStatus: 'עדכון מצב האייטם %{details} נכשל', - missingRequiredField: 'אופס, שכחת למלא שדה חובה. נא להשלים את המידע החסר לפני השמירה', - entrySaved: 'האייטם נשמר', - entryPublished: 'האייטם פורסם', - entryUnpublished: 'האייטם הועבר לטיוטות', - onFailToPublishEntry: 'פרסום האייטם %{details} נכשל', - onFailToUnpublishEntry: 'ביטול פרסום האייטם %{details} נכשל', - entryUpdated: 'מצב האייטם עודכן', - onDeleteUnpublishedChanges: 'השינויים שלא פורסמו נמחקו', - onFailToAuth: '%{details}', - onLoggedOut: 'נותקת מהמערכת. יש לגבות מידע לא שמור ולהתחבר שוב', - onBackendDown: 'ה-backend המוגדר אינו זמין. ראו %{details} למידע נוסף', - }, - }, - workflow: { - workflow: { - loading: 'טעינת אייטמים', - workflowHeading: 'ניהול אייטמים לפני הפרסום', - newPost: 'אייטם חדש', - description: - '%אייטם {smart_count} ממתין לאישור, אייטם %{readyCount} מוכן לפרסום |||| %{smart_count} אייטמים ממתינים לאישור, %{readyCount} מוכנים לפרסום', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} מאת %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'מאת %{author}', - deleteChanges: 'למחוק את השינויים', - deleteNewEntry: 'למחוק אייטם חדש', - publishChanges: 'פרסום השינויים', - publishNewEntry: 'פרסום אייטם חדש', - }, - workflowList: { - onDeleteEntry: 'האם ברצונך למחוק אייטם זה?', - onPublishingNotReadyEntry: - 'ניתן לפרסם רק אייטמים שנמצאים במצב ״מוכן לפרסום״. נא לגרור את האייטם לטור ״מוכן לפרסום״ כדי לפרסם.', - onPublishEntry: 'האם ברצונך לפרסם אייטם זה?', - draftHeader: 'טיוטות', - inReviewHeader: 'ממתין לאישור', - readyHeader: 'מוכן לפרסום', - currentEntries: 'אייטם %{smart_count} |||| %{smart_count} אייטמים', - }, - }, -}; - -export default he; diff --git a/packages/netlify-cms-locales/src/hr/index.js b/packages/netlify-cms-locales/src/hr/index.js deleted file mode 100644 index 1cb9ab9b..00000000 --- a/packages/netlify-cms-locales/src/hr/index.js +++ /dev/null @@ -1,285 +0,0 @@ -const hr = { - auth: { - login: 'Prijava', - loggingIn: 'Prijava u tijeku...', - loginWithNetlifyIdentity: 'Prijava sa Netlify računom', - loginWithAzure: 'Prijava za Azure računom', - loginWithBitbucket: 'Prijava sa Bitbucket računom', - loginWithGitHub: 'Prijava sa GitHub računom', - loginWithGitLab: 'Prijava sa GitLab računom', - errors: { - email: 'Unesite email.', - password: 'Molimo unisite lozinku.', - identitySettings: - 'Nemoguće pristupiti postavkama identita. Kod korištenja git-gateway backenda morate uključiti "Identity service" te "Git Gateway"', - }, - }, - app: { - header: { - content: 'Sadržaj', - workflow: 'Tijek rada', - media: 'Mediji', - quickAdd: 'Dodaj', - }, - app: { - errorHeader: 'Greška pri učitavanju CMS konfiguracije', - configErrors: 'Greška u konfiguraciji', - checkConfigYml: 'Provjeri config.yml datoteku.', - loadingConfig: 'Učitavanje konfiguracije...', - waitingBackend: 'Čekanje na backend...', - }, - notFoundPage: { - header: 'Stranica nije pronađena', - }, - }, - collection: { - sidebar: { - collections: 'Zbirke', - allCollections: 'Sve zbirke', - searchAll: 'Pretraži sve', - searchIn: 'Pretraži u', - }, - collectionTop: { - sortBy: 'Sortiraj', - viewAs: 'Pogledaj kao', - newButton: 'Nova %{collectionLabel}', - ascending: 'Uzlazno', - descending: 'Silzano', - searchResults: 'Rezulatati pretraživanja za "%{searchTerm}"', - searchResultsInCollection: 'Rezulatati pretraživanja za "%{searchTerm}" u %{collection}', - filterBy: 'Filtriraj po', - groupBy: 'Grupiraj po', - }, - entries: { - loadingEntries: 'Učitavanje unosa...', - cachingEntries: 'Predmemoriranje unosa...', - longerLoading: 'Ovo bi moglo potrajati par minuta', - noEntries: 'Nema unosa', - }, - groups: { - other: 'Ostalo', - negateLabel: 'Nije %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Ažurirano na', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opcionalno', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} je obvezan.', - regexPattern: '%{fieldLabel} se ne podudara sa uzorkom: %{pattern}.', - processing: '%{fieldLabel} se procesira.', - range: '%{fieldLabel} mora biti između %{minValue} i %{maxValue}.', - min: '%{fieldLabel} mora biti najmanje %{minValue}.', - max: '%{fieldLabel} mora biti %{maxValue} ili manje.', - rangeCount: '%{fieldLabel} mora imati između %{minCount} i %{maxCount} predmeta.', - rangeCountExact: '%{fieldLabel} mora imati točno %{count} predmeta.', - rangeMin: '%{fieldLabel} mora imati najmanje %{minCount} predmet(a).', - rangeMax: '%{fieldLabel} mora imate %{maxCount} ili manje predmeta.', - invalidPath: `'%{path}' nije valjana putanja`, - pathExists: `Putanja '%{path}' već postoji`, - }, - i18n: { - writingInLocale: 'Pisanje na %{locale}', - }, - }, - editor: { - onLeavePage: 'Jeste li sigurni da želite napustiti stranicu?', - onUpdatingWithUnsavedChanges: - 'Imate nespremljene promjene, molimo spremite prije ažuriranja statusa.', - onPublishingNotReady: 'Molimo ažurirajte status na "Spremno" prije objavljivanja.', - onPublishingWithUnsavedChanges: - 'Imate nespremljene promjene, molimo spremite prije objavljivanja.', - onPublishing: 'Jeste li sigurni da želite objaviti ovaj unos?', - onUnpublishing: 'Jeste li sigurni da želite maknuti objavu za ovaj unos?', - onDeleteWithUnsavedChanges: - 'Jeste li sigurni da želite obrisati objavljeni unos, te nespremljene promjene u trenutnoj sesiji?', - onDeletePublishedEntry: 'Jeste li sigurni da želite obrisati ovaj objavljeni unos?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Obrisat ćete sve neobjavljene promjene na ovom unosu, te sve nespremljene promjene u trenutnoj sesiji. Želite li i dalje obrisati?', - onDeleteUnpublishedChanges: - 'Sve nespremljene promjene na ovom unosu će biti obrisane. Želite li i dalje obrisati?', - loadingEntry: 'Učitavanje unosa...', - confirmLoadBackup: 'Lokalna kopija je dohvaćena za ovaj unos, želite li ju koristiti?', - }, - editorToolbar: { - publishing: 'Objavljivanje...', - publish: 'Objavi', - published: 'Objavljeno', - unpublish: 'Obriši iz objava', - duplicate: 'Dupliciraj', - unpublishing: 'Brisanje iz objava...', - publishAndCreateNew: 'Objavi i kreiraj novo', - publishAndDuplicate: 'Objavi i dupliciraj', - deleteUnpublishedChanges: 'Obriši neobjavljene promjene', - deleteUnpublishedEntry: 'Obriši neobjavljene unose', - deletePublishedEntry: 'Obriši objavljeni unos', - deleteEntry: 'Obriši unos', - saving: 'Spremanje...', - save: 'Spremi', - deleting: 'Brisanje...', - updating: 'Ažuriranje...', - status: 'Status: %{status}', - backCollection: 'Pisanje u %{collectionLabel} zbirci', - unsavedChanges: 'Nespremljene promjene', - changesSaved: 'Promjene spremljene', - draft: 'Skica', - inReview: 'Osvrt', - ready: 'Spremno', - publishNow: 'Objavi sad', - deployPreviewPendingButtonLabel: 'Provjeri za osvrt', - deployPreviewButtonLabel: 'Pogledaj osvrt', - deployButtonLabel: 'Pogledaj na produkciji', - }, - editorWidgets: { - markdown: { - bold: 'Podebljano', - italic: 'Kurziv', - code: 'Kod', - link: 'Link', - linkPrompt: 'Unesi URL linka', - headings: 'Naslovi', - quote: 'Citat', - bulletedList: 'Nabrajan popis', - numberedList: 'Numeriran popis', - addComponent: 'Dodaj komponentu', - richText: 'Bogati tekst', - markdown: 'Markdown', - }, - image: { - choose: 'Odaberi sliku', - chooseDifferent: 'Odaberi drugu sliku', - remove: 'Izbriši sliku', - }, - file: { - choose: 'Odaberi datoteku', - chooseDifferent: 'Odaberi drugu datoteku', - remove: 'Obriši datoteku', - }, - unknownControl: { - noControl: "Kontrola nije pronađena za widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Prikaz nije pronađen za widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Naslov 1', - headingTwo: 'Naslov 2', - headingThree: 'Naslov 3', - headingFour: 'Naslov 4', - headingFive: 'Naslov 5', - headingSix: 'Naslov 6', - }, - datetime: { - now: 'Sad', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Skica', - }, - mediaLibrary: { - onDelete: 'Jeste li sigurni da želite obrisati odabrane medijske datoteke?', - fileTooLarge: - 'Datoteka prevelika.\nKonfigurirano da ne podržava datoteke veće od %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Učitavanje...', - noResults: 'Nema rezultata.', - noAssetsFound: 'Sredstva nisu pronađena.', - noImagesFound: 'Slike nisu pronađene.', - private: 'Privatno ', - images: 'Slike', - mediaAssets: 'Medijska sredstva', - search: 'Pretraži...', - uploading: 'Učitavanje...', - upload: 'Učitaj', - download: 'Preuzmi', - deleting: 'Brisanje...', - deleteSelected: 'Obriši označeno', - chooseSelected: 'Odaberi označeno', - }, - }, - ui: { - default: { - goBackToSite: 'Povratak na stranicu', - }, - errorBoundary: { - title: 'Greška', - details: 'Dogodila se greška - molimo ', - reportIt: 'otvori issue (problem) na GitHubu.', - detailsHeading: 'Detalji', - privacyWarning: - 'Otvaranje issue-a (problema) populira ga sa porukom od greške i debug podacima.\nProvjerite jesu li infomacije točne i obrišite osjetljive podatke ako postoje.', - recoveredEntry: { - heading: 'Obnovljen dokument', - warning: 'Molimo kopiraj/zalijepi ovo negdje prije odlaska dalje!', - copyButtonLabel: 'Kopiraj u međuspremnik', - }, - }, - settingsDropdown: { - logOut: 'Odjava', - }, - toast: { - onFailToLoadEntries: 'Neuspjelo dohvaćanje unosa: %{details}', - onFailToLoadDeployPreview: 'Neuspjelo dohvaćanje pregleda: %{details}', - onFailToPersist: 'Neuspjelo spremanje unosa: %{details}', - onFailToDelete: 'Neuspjelo brisanje unosa: %{details}', - onFailToUpdateStatus: 'Neuspjelo ažuriranje statusa: %{details}', - missingRequiredField: 'Uups, preskočili ste obvezno polje. Molimo popunite prije spremanja.', - entrySaved: 'Unos spremljen', - entryPublished: 'Unos objavljen', - entryUnpublished: 'Unos obrisan', - onFailToPublishEntry: 'Neuspjelo objavljivanje unosa: %{details}', - onFailToUnpublishEntry: 'Neuspjelo brisanje unosa: %{details}', - entryUpdated: 'Status unosa ažuriran', - onDeleteUnpublishedChanges: 'Otkrivene neobjavljene objave', - onFailToAuth: '%{details}', - onLoggedOut: 'Odjavljeni ste, molimo spremite sve podatke i prijavite se ponovno', - onBackendDown: 'Backend servis ima prekid rada. Pogledaj %{details} za više informacija', - }, - }, - workflow: { - workflow: { - loading: 'Učitavanje unosa uredničkog tijeka rada', - workflowHeading: 'Urednički tijek rada', - newPost: 'Nova objava', - description: - '%{smart_count} unos čeka pregled, %{readyCount} unos spreman za produkciju. |||| %{smart_count} unosa čeka pregled, %{readyCount} unosa spremno za produkciju. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} od strane %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'od strane %{author}', - deleteChanges: 'Obriši promjene', - deleteNewEntry: 'Obriši novi unos', - publishChanges: 'Objavi promjene', - publishNewEntry: 'Objavi novi unos', - }, - workflowList: { - onDeleteEntry: 'Jeste li sigurni da želite obrisati unos?', - onPublishingNotReadyEntry: - 'Samo promjene sa statusom "Spremno" mogu biti objavljene. Molimo povucite karticu u kolumnu "Spremno" prije objavljivanja.', - onPublishEntry: 'Jeste li sigurni da želite objaviti unos?', - draftHeader: 'Skice', - inReviewHeader: 'U osvrtu', - readyHeader: 'Spremno', - currentEntries: '%{smart_count} unos |||| %{smart_count} unosa', - }, - }, -}; - -export default hr; diff --git a/packages/netlify-cms-locales/src/hu/index.js b/packages/netlify-cms-locales/src/hu/index.js deleted file mode 100644 index e49edd96..00000000 --- a/packages/netlify-cms-locales/src/hu/index.js +++ /dev/null @@ -1,217 +0,0 @@ -const hu = { - app: { - header: { - content: 'Tartalom', - workflow: 'Munkafolyamat', - media: 'Média', - quickAdd: 'Gyors hozzáadás', - }, - app: { - errorHeader: 'Hiba történt a CMS konfiguráció betöltése közben', - configErrors: 'Configurációs hibák', - checkConfigYml: 'Ellenőrizd a config.yml filet.', - loadingConfig: 'Konfiguráció betöltése...', - waitingBackend: 'Várakozás hattérrendszerekre...', - }, - notFoundPage: { - header: 'Nincs találat', - }, - }, - collection: { - sidebar: { - collections: 'Gyűjtemények', - searchAll: 'Keresés mindenre', - }, - collectionTop: { - viewAs: 'Nézet mint', - newButton: 'Új %{collectionLabel}', - }, - entries: { - loadingEntries: 'Bejegyzések betöltése', - cachingEntries: 'Bejegyzések cacheelése', - longerLoading: 'Ez még eltarthat néhany percig', - }, - }, - editor: { - editorControl: { - field: { - optional: 'választható', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} kötelező mező.', - regexPattern: '%{fieldLabel} nem egyezik a %{pattern} mintával.', - processing: '%{fieldLabel} feldolgozás alatt.', - range: '%{fieldLabel}, %{minValue} és %{maxValue} értékek között kell legyen.', - min: '%{fieldLabel} legalább %{minValue} kell legyen vagy több.', - max: '%{fieldLabel} legalabb %{maxValue} vagy kevesebb kell legyen.', - }, - }, - editor: { - onLeavePage: 'Biztos hogy el akarod hagyni az oldalt?', - onUpdatingWithUnsavedChanges: - 'Mentettlen változtatások vannak, kérjük, mentse az állapot frissítése előtt.', - onPublishingNotReady: 'Változtasd az állapotot "Kész"-re publikálás előtt.', - onPublishingWithUnsavedChanges: - 'Mentetlen változtatások vannak, kérjük, mentsen a publikálás előtt.', - onPublishing: 'Publikálod ezt a bejegyzést?', - onUnpublishing: 'Publikálás visszavonása erre a bejegyzésre?', - onDeleteWithUnsavedChanges: - 'Töröljük ezt a publikált bejegyzést, a többi mentetlen modositással együtt?', - onDeletePublishedEntry: 'Töröljük ezt a publikált bejegyzést?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Ezzel törli a bejegyzés összes nem közzétett módosítását, valamint az aktuális munkamenetből nem mentett módosításokat. Még mindig törli?', - onDeleteUnpublishedChanges: - 'A bejegyzés összes, nem közzétett módosítása törlődik. Még mindig törli?', - loadingEntry: 'Bejegyzés betöltése...', - confirmLoadBackup: - 'Helyi biztonsági másolat került helyre ehhez a bejegyzéshez, szeretné használni?', - }, - editorToolbar: { - publishing: 'Publikálás...', - publish: 'Publikáció', - published: 'Publikálás', - unpublish: 'Publikálás visszavonása', - duplicate: 'Duplikált', - unpublishing: 'Publikálás visszavonása...', - publishAndCreateNew: 'Publikálás és új létrehozása', - publishAndDuplicate: 'Publikálás és duplikál', - deleteUnpublishedChanges: 'Nempublikált változtatások törlése', - deleteUnpublishedEntry: 'Nempublikált bejegyzés törlése', - deletePublishedEntry: 'Publikált bejegyzés törlése', - deleteEntry: 'Bejegyzés törlése', - saving: 'Mentés...', - save: 'Mentés', - deleting: 'Törlés...', - updating: 'Frissítés...', - status: 'Beállitása: %{status}', - backCollection: ' Írás a %{collectionLabel} gyűjteménybe', - unsavedChanges: 'Nemmentett változtatások', - changesSaved: 'Változások elmentve', - draft: 'Piszkozat', - inReview: 'Felülvizsgálat alatt', - ready: 'Kész', - publishNow: 'Publikálás most', - deployPreviewPendingButtonLabel: 'Előnézet ellenörzése', - deployPreviewButtonLabel: 'Előnézet megtekintése', - deployButtonLabel: 'Élő megtekintése', - }, - editorWidgets: { - image: { - choose: 'Válasszon képet', - chooseDifferent: 'Válasszon másik képet', - remove: 'Távolítsa el a képet', - }, - file: { - choose: 'Válasszon fájlt', - chooseDifferent: 'Válasszon másik fájlt', - remove: 'Távolítsa el a fájlt', - }, - unknownControl: { - noControl: "Nincs vezérlés a '%{widget}' widget számára.", - }, - unknownPreview: { - noPreview: "Nincs előnézet a '%{widget}' widget számára.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - list: { - add: 'Új %{item}', - addType: 'Új típus %{item}', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Piszkozat', - }, - mediaLibrary: { - onDelete: 'Biztos törli a kiválasztott média tartalmat?', - }, - mediaLibraryModal: { - loading: 'Betöltés...', - noResults: 'Nincs találat.', - noAssetsFound: 'Nem található tartalom.', - noImagesFound: 'Nem található kép.', - private: 'Privát ', - images: 'Képek', - mediaAssets: 'Média tartalmak', - search: 'Keresés...', - uploading: 'Feltöltés...', - upload: 'Új feltöltés', - deleting: 'Törlés...', - deleteSelected: 'Kijelöltek törlése', - chooseSelected: 'Kijelöl', - }, - }, - ui: { - errorBoundary: { - title: 'Hiba', - details: 'Hiba történt - kérjük ', - reportIt: 'jelentse.', - detailsHeading: 'Részletek', - recoveredEntry: { - heading: 'Helyreállitott dokumentum', - warning: 'Kérjük mentse ezt el (vágólapra) mielőtt elhagyná az oldalt!', - copyButtonLabel: 'Másolás a vágólapra', - }, - }, - settingsDropdown: { - logOut: 'Kijelentkezés', - }, - toast: { - onFailToLoadEntries: 'A bejegyzés betöltése nem sikerült: %{details}', - onFailToLoadDeployPreview: 'Az előnézet betöltése nem sikerült: %{details}', - onFailToPersist: 'Bejegyzés megtartása sikertelen: %{details}', - onFailToDelete: 'A bejegyzés törlése sikertelen: %{details}', - onFailToUpdateStatus: 'Az állapot frissítése nem sikerült: %{details}', - missingRequiredField: 'Hoppá, kihagytál egy kötelező mezőt. Mentés előtt töltsd ki.', - entrySaved: 'Bejegyzés elmentve', - entryPublished: 'Bejegyzés publikálva', - entryUnpublished: 'Bejegyzés publikálása visszavonva', - onFailToPublishEntry: 'Bejegyzés publikálása sikertelen: %{details}', - onFailToUnpublishEntry: 'Bejegyzés publikálásának visszavonása sikertelen: %{details}', - entryUpdated: 'Bejegyzés állapota frissült', - onDeleteUnpublishedChanges: 'Unpublished changes deleted', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'A szerkesztési munkafolyamat-bejegyzések betöltése', - workflowHeading: 'Szerkesztői Folyamat', - newPost: 'New Post', - description: - '%{smart_count} bejegyzés felülvizsgálatra vár, %{readyCount} élesítésre vár. |||| %{smart_count} bejegyzés felülvizsgálatra vár, %{readyCount} élesítésre vár. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date}, írta %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '%{author}', - deleteChanges: 'Változtatások törlése', - deleteNewEntry: 'Új bejegyzés törlése', - publishChanges: 'Változtatások publikálása', - publishNewEntry: 'Új bejegyzés publikálása', - }, - workflowList: { - onDeleteEntry: 'Biztosan törli ezt a bejegyzést?', - onPublishingNotReadyEntry: - 'Csak a "Kész" állapotú tételek tehetők közzé. A közzététel engedélyezéséhez húzza a kártyát a „Kész” oszlopba.', - onPublishEntry: 'Biztosan közzéteszi ezt a bejegyzést?', - draftHeader: 'Piszkozat', - inReviewHeader: 'Vizsgálat alatt', - readyHeader: 'Kész', - currentEntries: '%{smart_count} bejegyzés |||| %{smart_count} bejegyzések', - }, - }, -}; - -export default hu; diff --git a/packages/netlify-cms-locales/src/index.js b/packages/netlify-cms-locales/src/index.js deleted file mode 100644 index e187867c..00000000 --- a/packages/netlify-cms-locales/src/index.js +++ /dev/null @@ -1,30 +0,0 @@ -export { default as cs } from './cs'; -export { default as da } from './da'; -export { default as de } from './de'; -export { default as en } from './en'; -export { default as es } from './es'; -export { default as ca } from './ca'; -export { default as fr } from './fr'; -export { default as gr } from './gr'; -export { default as hu } from './hu'; -export { default as it } from './it'; -export { default as lt } from './lt'; -export { default as ja } from './ja'; -export { default as nl } from './nl'; -export { default as nb_no } from './nb_no'; -export { default as nn_no } from './nn_no'; -export { default as pl } from './pl'; -export { default as pt } from './pt'; -export { default as ro } from './ro'; -export { default as ru } from './ru'; -export { default as sv } from './sv'; -export { default as th } from './th'; -export { default as tr } from './tr'; -export { default as uk } from './uk'; -export { default as vi } from './vi'; -export { default as zh_Hant } from './zh_Hant'; -export { default as ko } from './ko'; -export { default as hr } from './hr'; -export { default as bg } from './bg'; -export { default as zh_Hans } from './zh_Hans'; -export { default as he } from './he'; diff --git a/packages/netlify-cms-locales/src/it/index.js b/packages/netlify-cms-locales/src/it/index.js deleted file mode 100644 index ef72c4bf..00000000 --- a/packages/netlify-cms-locales/src/it/index.js +++ /dev/null @@ -1,229 +0,0 @@ -const it = { - auth: { - login: 'Accedi', - loggingIn: "Effettuando l'accesso...", - loginWithNetlifyIdentity: 'Accedi con Netlify Identity', - loginWithBitbucket: 'Accedi con Bitbucket', - loginWithGitHub: 'Accedi con GitHub', - loginWithGitLab: 'Accedi con GitLab', - errors: { - email: 'Assicurati di inserire la tua mail.', - password: 'Inserisci la tua password.', - identitySettings: - 'Impossibile accedere alle impostazioni di Identity. Quando usi git-gateway come backend assicurati di abilitare il servizio Itentity e Git Gateway.', - }, - }, - app: { - header: { - content: 'Contenuti', - workflow: 'Workflow', - media: 'Media', - quickAdd: 'Aggiunta veloce', - }, - app: { - errorHeader: 'Errore nel caricamento della configurazione CMS', - configErrors: 'Errori di Configurazione', - checkConfigYml: 'Controlla il tuo file config.yml.', - loadingConfig: 'Caricando la configurazione...', - waitingBackend: 'Attendi il backend...', - }, - notFoundPage: { - header: 'Non trovato', - }, - }, - collection: { - sidebar: { - collections: 'Collezioni', - searchAll: 'Cerca su tutto', - }, - collectionTop: { - viewAs: 'Vedi come', - newButton: 'Nuovo/a %{collectionLabel}', - }, - entries: { - loadingEntries: 'Caricando le voci', - cachingEntries: 'Cachando le voci', - longerLoading: 'Questa operazione potrebbe durare diversi minuti', - }, - }, - editor: { - editorControl: { - field: { - optional: 'opzionale', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} è richiesto.', - regexPattern: '%{fieldLabel} non corrisponde allo schema: %{pattern}.', - processing: '%{fieldLabel} sta elaborando.', - range: '%{fieldLabel} deve essere tra %{minValue} e %{maxValue}.', - min: '%{fieldLabel} deve essere almeno %{minValue}.', - max: '%{fieldLabel} deve essere %{maxValue} o meno.', - }, - }, - editor: { - onLeavePage: 'Sei sicuro di voler lasciare questa pagina?', - onUpdatingWithUnsavedChanges: - 'Hai delle modifiche non salvate, salvale prima di aggiornare lo status.', - onPublishingNotReady: 'Aggiorna lo status a "Pronto" prima di pubblicare.', - onPublishingWithUnsavedChanges: - 'Hai delle modifiche non salvate, salvale prima di pubblicare.', - onPublishing: 'Sei sicuro di voler pubblicare questa voce?', - onUnpublishing: 'Sei sicuro di voler nascondere questa voce?', - onDeleteWithUnsavedChanges: - 'Sei sicuro di voler cancellare questa voce pubblicata e tutte le modifiche non salvate della tua sessione corrente?', - onDeletePublishedEntry: 'Sei sicuro di voler cancellare questa voce pubblicata?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Questo cancellerà tutte le modifiche non pubblicate di questa voce, come anche tutte le modifiche non salvate della sessione corrente. Vuoi ancora cancellarle?', - onDeleteUnpublishedChanges: - 'Tutte le modifiche non pubblicate a questa voce saranno cancellate. Vuoi ancora cancellarle?', - loadingEntry: 'Caricando la voce...', - confirmLoadBackup: 'Un backup locale è stato recuperato per questa voce, vuoi utilizzarlo?', - }, - editorToolbar: { - publishing: 'Pubblicando...', - publish: 'Pubblica', - published: 'Pubblicato', - unpublish: 'Rimuovi dalla pubblicazione', - duplicate: 'Duplica', - unpublishing: 'Rimuovendo dalla pubblicazione...', - publishAndCreateNew: 'Pubblica e creane uno nuovo', - publishAndDuplicate: 'Pubblica e duplica', - deleteUnpublishedChanges: 'Cancella le modifiche non pubblicate', - deleteUnpublishedEntry: 'Cancella le voci non pubblicate', - deletePublishedEntry: 'Cancella la voce pubblicata', - deleteEntry: 'Cancella voce', - saving: 'Salvando...', - save: 'Salva', - deleting: 'Cancellando...', - updating: 'Aggiornando...', - status: 'Status: %{status}', - backCollection: ' Scrivendo nella sezione %{collectionLabel}', - unsavedChanges: 'Modifiche non salvate', - changesSaved: 'Modifiche salvate', - draft: 'Bozza', - inReview: 'In revisione', - ready: 'Pronto', - publishNow: 'Pubblica ora', - deployPreviewPendingButtonLabel: "Controlla l'anteprima", - deployPreviewButtonLabel: "Guarda l'anteprima", - deployButtonLabel: 'Guarda Live', - }, - editorWidgets: { - image: { - choose: "Scegli un'immagine", - chooseDifferent: "Scegli un'immagine diversa", - remove: 'Rimuovi immagine', - }, - file: { - choose: 'Scegli un file', - chooseDifferent: 'Scegli un altro file', - remove: 'Rimuovi il file', - }, - unknownControl: { - noControl: "Nessun controllo per il widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Nessuna preview per il widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Bozza', - }, - mediaLibrary: { - onDelete: 'Sei sicuro di voler cancellare il media selezionato?', - fileTooLarge: - 'File troppo grande.\nConfigurato per non accettare file piú grandi di %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Caricamento...', - noResults: 'Nessun risultato.', - noAssetsFound: 'Nessun assets trovato.', - noImagesFound: 'Nessuna immagine trovata.', - private: 'Privato ', - images: 'Immagini', - mediaAssets: 'Media assets', - search: 'Cerca...', - uploading: 'Uploading...', - upload: 'Upload', - deleting: 'Deleting...', - deleteSelected: 'Cancella selezionato', - chooseSelected: 'Prendi selezionato', - }, - }, - ui: { - errorBoundary: { - title: 'Errore', - details: "C'è stato un errore - per favore ", - reportIt: 'riportalo.', - detailsHeading: 'Dettagli', - recoveredEntry: { - heading: 'Documento recuperato', - warning: 'Per favore copia/incollalo da qualche parte prima di navigare altrove!', - copyButtonLabel: 'Copialo negli appunti', - }, - }, - settingsDropdown: { - logOut: 'Esci', - }, - toast: { - onFailToLoadEntries: 'Caricamento voce non riuscito: %{details}', - onFailToLoadDeployPreview: 'Caricamento della preview non riuscito: %{details}', - onFailToPersist: 'Salvataggio della voce non riuscito: %{details}', - onFailToDelete: 'Cancellazione della voce non riuscita: %{details}', - onFailToUpdateStatus: 'Aggiornamento dello status non riuscito: %{details}', - missingRequiredField: - 'Oops, ti sei perso un campo obbligatorio. Per favore completalo prima di salvare.', - entrySaved: 'Voce salvata', - entryPublished: 'Voce pubblicata', - entryUnpublished: 'Voce rimossa dalla pubblicazione', - onFailToPublishEntry: 'Pubblicazione fallita: %{details}', - onFailToUnpublishEntry: 'Rimozione della pubblicazione fallita: %{details}', - entryUpdated: 'Status della voce aggiornato', - onDeleteUnpublishedChanges: 'Modifiche non pubblicate cancellate', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Caricando le voci del Flusso Editoriale', - workflowHeading: 'Flusso Editoriale', - newPost: 'Nuovo Post', - description: - '%{smart_count} voce attende la revisione, %{readyCount} pronte per la pubblicazione. |||| %{smart_count} voci attendono la revisione, %{readyCount} pronte per la pubblicazione. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} da %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'da %{author}', - deleteChanges: 'Cancella le modifiche', - deleteNewEntry: 'Cancella nuova voce', - publishChanges: 'Pubblica modifiche', - publishNewEntry: 'Pubblica una nuova voce', - }, - workflowList: { - onDeleteEntry: 'Sei sicuro di voler cancellare questa voce?', - onPublishingNotReadyEntry: - 'Solo gli oggetti con lo status "Pronto" possono essere pubblicati. Sposta la Card nella colonna "Pronto" per abilitare la pubblicazione.', - onPublishEntry: 'Sei sicuro di voler pubblicare questa voce?', - draftHeader: 'Bozze', - inReviewHeader: 'In Revisione', - readyHeader: 'Pronto', - currentEntries: '%{smart_count} voce |||| %{smart_count} voci', - }, - }, -}; - -export default it; diff --git a/packages/netlify-cms-locales/src/ja/index.js b/packages/netlify-cms-locales/src/ja/index.js deleted file mode 100644 index bc020081..00000000 --- a/packages/netlify-cms-locales/src/ja/index.js +++ /dev/null @@ -1,302 +0,0 @@ -const ja = { - auth: { - login: 'ログイン', - loggingIn: 'ログインしています...', - loginWithNetlifyIdentity: 'Netlify Identity でログインする', - loginWithAzure: 'Azure でログインする', - loginWithBitbucket: 'Bitbucket でログインする', - loginWithGitHub: 'GitHub でログインする', - loginWithGitLab: 'GitLab でログインする', - errors: { - email: 'メールアドレスを確認してください。', - password: 'パスワードを入力してください。', - identitySettings: - '認証情報にアクセスできませんでした。git-gateway backend を利用している場合は、認証サービスと Git Gateway が有効になっているかを確認してください。', - }, - }, - app: { - header: { - content: 'コンテンツ', - workflow: 'ワークフロー', - media: 'メディア', - quickAdd: '新規作成', - }, - app: { - errorHeader: 'CMS設定の読み込みエラー', - configErrors: '設定エラー', - checkConfigYml: 'config.ymlを確認してください。', - loadingConfig: '設定を読み込んでいます...', - waitingBackend: 'バックエンドの応答を待機しています...', - }, - notFoundPage: { - header: 'ページが見つかりません', - }, - }, - collection: { - sidebar: { - collections: 'コレクション', - allCollections: 'すべてのコレクション', - searchAll: '検索', - searchIn: '検索対象', - }, - collectionTop: { - sortBy: 'ソート', - viewAs: '表示モード', - newButton: '%{collectionLabel}を作成', - ascending: '昇順', - descending: '降順', - searchResults: '「%{searchTerm}」の検索結果', - searchResultsInCollection: '%{collection}内の「%{searchTerm}」の検索結果', - filterBy: '絞り込み', - groupBy: 'グルーピング', - }, - entries: { - loadingEntries: 'エントリを読み込み中', - cachingEntries: 'エントリをキャッシュ中', - longerLoading: '少々お待ちください', - noEntries: 'エントリがありません', - }, - groups: { - other: 'その他', - negateLabel: '%{label}以外', - }, - defaultFields: { - author: { - label: '作成者', - }, - updatedOn: { - label: '最終更新', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: '任意', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel}は必須です。', - regexPattern: '%{fieldLabel}が入力規則(%{pattern})と一致しません。', - processing: '%{fieldLabel}を処理しています。', - range: '%{fieldLabel}は%{minValue}から%{maxValue}まで入力可能です。', - min: '%{fieldLabel}の最小値は%{minValue}です。', - max: '%{fieldLabel}の最大値は%{maxValue}です。', - rangeCount: '%{fieldLabel}は%{minCount}個から%{maxCount}個まで選択してください。', - rangeCountExact: '%{fieldLabel}はちょうど%{count}個選択してください。', - rangeMin: '%{fieldLabel}は%{minCount}個以上選択してください。', - rangeMax: '%{fieldLabel}は%{maxCount}個以下選択してください。', - invalidPath: `'%{path}'は有効なパスではありません。`, - pathExists: `'%{path}'というパスはすでに存在しています。`, - }, - i18n: { - writingInLocale: '言語: %{locale}', - }, - }, - editor: { - onLeavePage: 'このページから遷移しますか?', - onUpdatingWithUnsavedChanges: - '変更した項目があります。ステータスを更新する前に保存してください。', - onPublishingNotReady: '公開する前に、ステータスを「準備完了」に更新してください。', - onPublishingWithUnsavedChanges: '変更した項目があります。公開する前に保存してください。', - onPublishing: 'このエントリを公開しますか?', - onUnpublishing: 'このエントリを未公開にしますか?', - onDeleteWithUnsavedChanges: - '保存されていない変更も削除されますが、この公開エントリを削除しますか?', - onDeletePublishedEntry: 'この公開エントリを削除しますか?', - onDeleteUnpublishedChangesWithUnsavedChanges: - '保存されていない変更も削除されますが、このエントリの未公開の変更を削除しますか?', - onDeleteUnpublishedChanges: - '公開されていない変更も削除されますが、このエントリを削除しますか?', - loadingEntry: 'エントリの読込中...', - confirmLoadBackup: 'ローカルのバックアップが復旧できました。利用しますか?', - }, - editorInterface: { - toggleI18n: '言語を切り替える', - togglePreview: 'プレビュー表示を切り替える', - toggleScrollSync: 'スクロール同期を切り替える', - }, - editorToolbar: { - publishing: '公開しています...', - publish: '公開', - published: '公開済', - unpublish: '未公開', - duplicate: '複製', - unpublishing: '未公開にしています...', - publishAndCreateNew: '公開して新規作成', - publishAndDuplicate: '公開して複製する', - deleteUnpublishedChanges: '未公開の変更を削除', - deleteUnpublishedEntry: '未公開エントリを削除', - deletePublishedEntry: '公開エントリを削除', - deleteEntry: 'エントリを削除', - saving: '保存中...', - save: '保存', - statusInfoTooltipDraft: - 'エントリのステータスは下書きに設定されています。最終決定してレビューに提出するには、ステータスを「レビュー中」に設定します。', - statusInfoTooltipInReview: - 'エントリはレビュー中なので、それ以上のアクションは必要ありません。ただし、レビュー中でも追加の変更を行うことができます。', - deleting: '削除しています...', - updating: '更新しています...', - status: 'ステータス: %{status}', - backCollection: '%{collectionLabel}のエントリを作成中', - unsavedChanges: '未保存', - changesSaved: '保存済', - draft: '下書き', - inReview: 'レビュー中', - ready: '準備完了', - publishNow: '公開する', - deployPreviewPendingButtonLabel: 'プレビューのチェック', - deployPreviewButtonLabel: 'プレビューを見る', - deployButtonLabel: 'ライブで見る', - }, - editorWidgets: { - markdown: { - bold: '太字', - italic: '斜体', - code: 'コード', - link: 'リンク', - linkPrompt: 'リンクのURLを入力してください', - headings: '見出し', - quote: '引用', - bulletedList: '箇条書き', - numberedList: '番号付きリスト', - addComponent: 'コンポーネント追加', - richText: 'リッチテキスト', - markdown: 'マークダウン', - }, - image: { - choose: '画像を選択', - chooseUrl: 'URLを入力する', - replaceUrl: 'URLを変更する', - promptUrl: '画像のURLを入力してください', - chooseDifferent: '他の画像を選択', - remove: '画像を削除', - }, - file: { - choose: 'ファイルを選択', - chooseUrl: 'URLを入力する', - replaceUrl: 'URLを変更する', - promptUrl: 'ファイルのURLを入力してください', - chooseDifferent: '他のファイルを選択', - remove: 'ファイルを削除', - }, - unknownControl: { - noControl: "'%{widget}'はウィジェットとして利用できません。", - }, - unknownPreview: { - noPreview: "'%{widget}'のウィジェットにはプレビューがありません。", - }, - headingOptions: { - headingOne: '見出し 1', - headingTwo: '見出し 2', - headingThree: '見出し 3', - headingFour: '見出し 4', - headingFive: '見出し 5', - headingSix: '見出し 6', - }, - datetime: { - now: '現時刻', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: '下書き', - copy: 'コピー', - copyUrl: 'URLをコピー', - copyPath: 'パスをコピー', - copyName: '名前をコピー', - copied: 'コピーしました', - }, - mediaLibrary: { - onDelete: '選択しているデータを削除しますか?', - fileTooLarge: 'ファイルサイズが大きすぎます。\n%{size} kB 以下にしてください。', - }, - mediaLibraryModal: { - loading: '読込中...', - noResults: 'データがありません。', - noAssetsFound: 'データがありません。', - noImagesFound: 'データがありません。', - private: 'プライベート', - images: '画像', - mediaAssets: 'メディア', - search: '検索', - uploading: 'アップロード中...', - upload: 'アップロードする', - download: 'ダウンロードする', - deleting: '削除中...', - deleteSelected: '削除する', - chooseSelected: '選択する', - }, - }, - ui: { - default: { - goBackToSite: 'サイトに戻る', - }, - errorBoundary: { - title: 'エラー', - details: 'エラーが発生しました。', - reportIt: 'レポートする', - detailsHeading: '詳細', - privacyWarning: - 'エラーメッセージとデバッグのデータがレポートする前に表示されます。\n情報が正しいことを確認し、機密データが存在する場合は削除してください。', - recoveredEntry: { - heading: '復旧したエントリ', - warning: '必要あれば、このページから遷移する前にコピーしてください。', - copyButtonLabel: 'コピーする', - }, - }, - settingsDropdown: { - logOut: 'ログアウト', - }, - toast: { - onFailToLoadEntries: 'エントリの読み込みに失敗しました。%{details}', - onFailToLoadDeployPreview: 'プレビューの読み込みに失敗しました。%{details}', - onFailToPersist: 'エントリの保存に失敗しました。%{details}', - onFailToDelete: 'エントリの削除に失敗しました。%{details}', - onFailToUpdateStatus: 'エントリのステータス更新に失敗しました。%{details}', - missingRequiredField: 'すべての必須項目を入力してください。', - entrySaved: '保存しました。', - entryPublished: '公開しました。', - entryUnpublished: '未公開にしました。', - onFailToPublishEntry: 'エントリの公開に失敗しました。%{details}', - onFailToUnpublishEntry: 'エントリを未公開にするのに失敗しました。%{details}', - entryUpdated: 'エントリのステータスを更新しました。', - onDeleteUnpublishedChanges: '未公開の変更を削除しました。', - onFailToAuth: '%{details}', - onLoggedOut: 'ログアウトされています。データをバックアップし、再度ログインしてください。', - onBackendDown: 'バックエンドのシステムが停止しています。%{details}', - }, - }, - workflow: { - workflow: { - loading: 'ワークフロー内のエントリを読込中', - workflowHeading: 'ワークフロー', - newPost: '新規作成', - description: '%{smart_count}件がレビュー中、%{readyCount}件が準備完了です。', - dateFormat: 'M月D日', - }, - workflowCard: { - lastChange: '%{author}が%{date}に更新', - lastChangeNoAuthor: '最終更新日:%{date}', - lastChangeNoDate: '最終更新者:%{author}', - deleteChanges: '変更を削除', - deleteNewEntry: 'エントリを削除', - publishChanges: '変更を公開', - publishNewEntry: 'エントリを公開', - }, - workflowList: { - onDeleteEntry: 'このエントリを削除しますか?', - onPublishingNotReadyEntry: - '「準備完了」のエントリのみを公開できます。「準備完了」列にカードを移動し、ステータスを更新してください。', - onPublishEntry: 'このエントリを公開しますか?', - draftHeader: '下書き', - inReviewHeader: 'レビュー中', - readyHeader: '準備完了', - currentEntries: '%{smart_count}件のエントリ', - }, - }, -}; - -export default ja; diff --git a/packages/netlify-cms-locales/src/ko/index.js b/packages/netlify-cms-locales/src/ko/index.js deleted file mode 100644 index 96a139b2..00000000 --- a/packages/netlify-cms-locales/src/ko/index.js +++ /dev/null @@ -1,268 +0,0 @@ -const ko = { - auth: { - login: '로그인', - loggingIn: '로그인 중...', - loginWithNetlifyIdentity: 'Netlify Identity 로 로그인', - loginWithBitbucket: 'Bitbucket 으로 로그인', - loginWithGitHub: 'GitHub 로 로그인', - loginWithGitLab: 'GitLab 으로 로그인', - errors: { - email: '반드시 이메일을 입력해 주세요.', - password: '암호를 입력해 주세요.', - identitySettings: - '설정에 접근할 수 없습니다. git-gateway 백엔드 사용시 Identity service와 Git Gateway를 활성화 해야 합니다.', - }, - }, - app: { - header: { - content: '콘텐츠', - workflow: '워크플로우', - media: '미디어', - quickAdd: '빠른 추가', - }, - app: { - errorHeader: 'CMS 구성을 불러오는 중 오류가 발생했습니다.', - configErrors: '구성 오류', - checkConfigYml: 'config.yml 파일을 확인하세요.', - loadingConfig: '구성 불러오는 중...', - waitingBackend: '백엔드 기다리는 중...', - }, - notFoundPage: { - header: '찾을 수 없음', - }, - }, - collection: { - sidebar: { - collections: '컬렉션', - allCollections: '모든 컬렉션', - searchAll: '모든 컬렉션에서 검색', - searchIn: '다음 컬렉션에서 검색', - }, - collectionTop: { - sortBy: '정렬 기준', - viewAs: '다음으로 보기', - newButton: '새 %{collectionLabel} 항목', - ascending: '오름차순', - descending: '내림차순', - searchResults: '"%{searchTerm}"에 대한 검색결과', - searchResultsInCollection: '%{collection} 컬랙션에서 "%{searchTerm}"에 대한 검색결과', - filterBy: '필터 기준', - }, - entries: { - loadingEntries: '항목 불러오는 중...', - cachingEntries: '항목 캐시 중...', - longerLoading: '몇 분 정도 걸릴 수 있습니다.', - noEntries: '항목 없음', - }, - defaultFields: { - author: { - label: '저자', - }, - updatedOn: { - label: '업데이트 시각', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: '선택사항', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} 은(는) 필수입니다.', - regexPattern: '%{fieldLabel} 이(가) %{pattern} 패턴과 일치하지 않습니다.', - processing: '%{fieldLabel} 은(는) 처리중 입니다.', - range: '%{fieldLabel} 은(는) 반드시 %{minValue} 에서 %{maxValue} 사이여야 합니다.', - min: '%{fieldLabel} 은(는) 적어도 %{minValue} 이상 이여야 합니다.', - max: '%{fieldLabel} 은(는) 최대 %{maxValue} 여야 합니다.', - rangeCount: '%{fieldLabel} 개수는 %{minCount} 개 에서 %{maxCount} 개 사이여야 합니다.', - rangeCountExact: '%{fieldLabel} 개수는 정확히 %{count} 개 여야 합니다.', - rangeMin: '%{fieldLabel} 개수는 적어도 %{minCount} 개 이상 이여야 합니다.', - rangeMax: '%{fieldLabel} 개수는 최대 %{maxCount} 개 여야 합니다.', - invalidPath: `'%{path}' 은(는) 올바른 경로가 아닙니다.`, - pathExists: `'%{path}' 경로가 이미 존재합니다.`, - }, - }, - editor: { - onLeavePage: '이 페이지를 떠나시겠습니까?', - onUpdatingWithUnsavedChanges: - '저장하지 않은 변경사항이 있습니다. 상태 업데이트 전 먼저 저장하세요.', - onPublishingNotReady: '게시 하기 앞서 상태를 "준비됨" 으로 업데이트 하세요.', - onPublishingWithUnsavedChanges: - '저장하지 않은 변경사항이 있습니다, 게시하기 전 먼저 저장하세요.', - onPublishing: '이 항목을 게시하시곘습니까?', - onUnpublishing: '이 항목을 게시 철회 하시겠습니까?', - onDeleteWithUnsavedChanges: - '현재 세션에서의 저장되지 않은 변경사항과 이 게시된 항목을 삭제하시겠습니까?', - onDeletePublishedEntry: '이 게시된 항목을 삭제하시겠습니까?', - onDeleteUnpublishedChangesWithUnsavedChanges: - '이 항목의 게시되지 않은 모든 변경사항과 현재 세션의 저장되지 않은 변경사항이 삭제됩니다. 정말로 삭제하시겠습니까?', - onDeleteUnpublishedChanges: - '이 항목에 대해 게시되지 않은 변경사항이 삭제됩니다. 정말로 삭제하시겠습니까?', - loadingEntry: '항목 불러오는 중...', - confirmLoadBackup: - '이 항목에 대한 로컬 백업이 복구되었습니다, 복구된 것으로 사용하시겠습니까?', - }, - editorToolbar: { - publishing: '게시 중...', - publish: '게시', - published: '게시됨', - unpublish: '게시 철회', - duplicate: '복제', - unpublishing: '게시 철회 중...', - publishAndCreateNew: '게시하고 새로 만들기', - publishAndDuplicate: '게시하고 복제', - deleteUnpublishedChanges: '게시 안된 변경사항 삭제', - deleteUnpublishedEntry: '게시 안된 항목 삭제', - deletePublishedEntry: '게시된 항목 삭제', - deleteEntry: '항목 삭제', - saving: '저장 중...', - save: '저장', - deleting: '삭제 중...', - updating: '업데이트 중...', - status: '상태: %{status}', - backCollection: '%{collectionLabel} 컬랙션에 작성하는 중', - unsavedChanges: '변경사항 저장되지 않음', - changesSaved: '변경사항 저장됨', - draft: '초안', - inReview: '검토중', - ready: '준비됨', - publishNow: '지금 게시', - deployPreviewPendingButtonLabel: '미리보기 확인', - deployPreviewButtonLabel: '미리보기 보기', - deployButtonLabel: '라이브 보기', - }, - editorWidgets: { - markdown: { - richText: '리치 텍스트', - markdown: '마크다운', - }, - image: { - choose: '이미지 선택', - chooseDifferent: '다른 이미지 선택', - remove: '이미지 삭제', - }, - file: { - choose: '파일 선택', - chooseDifferent: '다른 파일 선택', - remove: '파일 삭제', - }, - unknownControl: { - noControl: "'%{widget}' 위젝에 대한 컨트롤이 없습니다.", - }, - unknownPreview: { - noPreview: "'%{widget}' 위젯에 대한 미리보기가 없습니다.", - }, - headingOptions: { - headingOne: '제목 1', - headingTwo: '제목 2', - headingThree: '제목 3', - headingFour: '제목 4', - headingFive: '제목 5', - headingSix: '제목 6', - }, - datetime: { - now: '현재시각', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: '초안', - }, - mediaLibrary: { - onDelete: '선택하신 미디어를 삭제하시겠습니까?', - fileTooLarge: - '파일이 너무 큽니다.\n%{size} kB 보다 큰 파일을 허용하지 않도록 구성되어 있습니다.', - }, - mediaLibraryModal: { - loading: '불러오는 중...', - noResults: '일치 항목 없음.', - noAssetsFound: '발견된 에셋 없음.', - noImagesFound: '발견된 이미지 없음.', - private: '개인 ', - images: '이미지', - mediaAssets: '미디어 에셋', - search: '검색...', - uploading: '업로드 중...', - upload: '업로드', - download: '다운로드', - deleting: '삭제 중...', - deleteSelected: '선택항목 삭제', - chooseSelected: '선택한 것으로 결정', - }, - }, - ui: { - default: { - goBackToSite: '사이트로 돌아가기', - }, - errorBoundary: { - title: '오류', - details: '오류가 발생했습니다.', - reportIt: 'GitHub에서 이슈를 열어 보고해 주세요.', - detailsHeading: '자세한 내용', - privacyWarning: - '이슈를 열면 사전에 오류 메시지와 디버깅 데이터로 채워집니다.\n정보가 올바른지 확인하시고 민감한 정보가 있다면 지워주세요.', - recoveredEntry: { - heading: '복구된 문서', - warning: '다른 곳으로 가시기 전에 이 내용을 꼭 복사해두세요!', - copyButtonLabel: '클립보드로 복사', - }, - }, - settingsDropdown: { - logOut: '로그아웃', - }, - toast: { - onFailToLoadEntries: '항목 불러오기 실패: %{details}', - onFailToLoadDeployPreview: '미리보기 불러오기 실패: %{details}', - onFailToPersist: '항목 저장 실패: %{details}', - onFailToDelete: '항목 삭제 실패: %{details}', - onFailToUpdateStatus: '상태 업데이트 실패: %{details}', - missingRequiredField: '이런! 필수 필드를 놓치셨습니다. 저장하기 전에 먼저 채우세요.', - entrySaved: '항목 저장됨', - entryPublished: '항목 게시됨', - entryUnpublished: '항목 게시 철회됨', - onFailToPublishEntry: '게시 실패: %{details}', - onFailToUnpublishEntry: '항목 게시 철회 실해: %{details}', - entryUpdated: '항목 상태 업데이트됨', - onDeleteUnpublishedChanges: '게시되지 않은 변경사항 삭제됨', - onFailToAuth: '%{details}', - onLoggedOut: '로그아웃 하셨습니다, 데티어를 백업하시고 다시 로그인 하세요.', - onBackendDown: - '백엔드 서비스가 장애를 겪고 있습니다. 자세한 사항은 %{details} 을(를) 참고하세요.', - }, - }, - workflow: { - workflow: { - loading: '편집 워크플로우의 항목을 불러오는 중', - workflowHeading: '편집 워크플로우', - newPost: '새 게시물', - description: - '%{smart_count}개 항목 검토 대기중, %{readyCount}개 항목 게시 준비 완료됨. |||| %{smart_count}개 항목 검토 대기중, %{readyCount}개 항목 게시 준비 완료됨. ', - dateFormat: 'M월 D일', - }, - workflowCard: { - lastChange: '%{date} by %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'by %{author}', - deleteChanges: '변경사항 삭제', - deleteNewEntry: '새 항목 삭제', - publishChanges: '변경사항 게시', - publishNewEntry: '새 항목 게시', - }, - workflowList: { - onDeleteEntry: 'Are you sure you want to delete this entry?', - onPublishingNotReadyEntry: - '"준비됨" 상태의 항목만 게시할 수 있습니다. 게시를 활성화 하려면 카드를 "준비됨" 열에 끌어 놓으세요.', - onPublishEntry: '이 항목을 게시하시곘습니까?', - draftHeader: '초안', - inReviewHeader: '검토 진행중', - readyHeader: '준비됨', - currentEntries: '%{smart_count}개 항목 |||| %{smart_count}개 항목', - }, - }, -}; - -export default ko; diff --git a/packages/netlify-cms-locales/src/lt/index.js b/packages/netlify-cms-locales/src/lt/index.js deleted file mode 100644 index d22811ec..00000000 --- a/packages/netlify-cms-locales/src/lt/index.js +++ /dev/null @@ -1,290 +0,0 @@ -const lt = { - auth: { - login: 'Prisijungti', - loggingIn: 'Prisijungiama...', - loginWithNetlifyIdentity: 'Prisijungti su Netlify Identity', - loginWithAzure: 'Prisijungti su Azure', - loginWithBitbucket: 'Prisijungti su Bitbucket', - loginWithGitHub: 'Prisijungti su GitHub', - loginWithGitLab: 'Prisijungti su GitLab', - errors: { - email: 'Įveskite savo elektroninį paštą.', - password: 'Įveskite savo slaptažodį.', - identitySettings: - 'Deja, nepavyksta pasiekti Identity paslaugos nustatymus. Kai naudojate git-gateway backend metodą, įjunkite „Identity service“ ir „Git Gateway“.', - }, - }, - app: { - header: { - content: 'Turinys', - workflow: 'Darbo eiga', - media: 'Medija', - quickAdd: 'Sukurti naują', - }, - app: { - errorHeader: 'Klaida, neišėjo užkrauti/pasiekti CMS konfigūracijos failą', - configErrors: 'Konfigūracijos (nustatymų) klaidos', - checkConfigYml: 'Patikrinkite config.yml balsą.', - loadingConfig: 'Kraunamas nustatymų (konfigūracijos) failas...', - waitingBackend: 'Laukiama serverio...', - }, - notFoundPage: { - header: 'Nerasta', - }, - }, - collection: { - sidebar: { - collections: 'Kolekcijos', - allCollections: 'Visos kolekcijos', - searchAll: 'Ieškoti viską', - searchIn: 'Ieškoti tik čia', - }, - collectionTop: { - sortBy: 'Rikiavimo tvarka', - viewAs: 'Peržiūrėti kaip', - newButton: 'Nauja(s) %{collectionLabel}', - ascending: 'Didėjimo tvarka (A-Z)', - descending: 'Mažėjimo tvarka (Z-A)', - searchResults: 'Paieškos rezultatai: „%{searchTerm}“', - searchResultsInCollection: 'Paieškos rezultatai: „%{searchTerm}“ iš %{collection}', - filterBy: 'Filtruoti', - groupBy: 'Grupuoti', - }, - entries: { - loadingEntries: 'Kraunamas turinys...', - cachingEntries: 'Talpinami įrašai...', - longerLoading: 'Šis procesas gali trukti keletą minučių', - noEntries: 'Nėra turinio', - }, - groups: { - other: 'Kita', - negateLabel: 'Ne %{label}', - }, - defaultFields: { - author: { - label: 'Autorius', - }, - updatedOn: { - label: 'Atnaujinta', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'neprivaloma', - }, - }, - editorControlPane: { - widget: { - required: 'Privaloma užpildyti laukelį %{fieldLabel}.', - regexPattern: - '%{fieldLabel} laukelis neatitiko konfigūracijoje nustatytų taisyklių: %{pattern}.', - processing: 'Apdorojame %{fieldLabel}.', - range: '%{fieldLabel} turi būti tarp %{minValue} ir %{maxValue}.', - min: '%{fieldLabel} turi būti bent %{minValue}.', - max: '%{fieldLabel} turi būti %{maxValue} arba mažiau.', - rangeCount: '%{fieldLabel} turi būti tarp %{minCount} ir %{maxCount} elementų/-o.', - rangeCountExact: '%{fieldLabel} turi turėti būtent tik %{count} elementų/-us.', - rangeMin: '%{fieldLabel} turi būti bent %{minCount} elementų.', - rangeMax: '%{fieldLabel} turi būti %{maxCount} arba mažiau elementų.', - invalidPath: `'%{path}' nėra taisyklinga nuoroda/adresas į resursą/-us`, - pathExists: `Adresas '%{path}' jau egzistuoja`, - }, - i18n: { - writingInLocale: 'Rašome %{locale} kalboje', - }, - }, - editor: { - onLeavePage: 'Ar tikrai norite uždaryti šį puslapį?', - onUpdatingWithUnsavedChanges: - 'Turite neišsaugotų pakeitimų! Prašome išsaugoti prieš pakeičiant statusą.', - onPublishingNotReady: 'Prieš publikuojant, privalote pakeisti statusą į „Paruošta“.', - onPublishingWithUnsavedChanges: - 'Yra neišsaugotų pakeitimų, prašome išsaugoti juos prieš publikuojant.', - onPublishing: 'Ae tikrai norite publikuoti šį įrašą?', - onUnpublishing: 'Tikrai norite panaikinti publikavimo statusą?', - onDeleteWithUnsavedChanges: - 'Tikrai norite panaikinti publikuotą įrašą ir Jūsų pakeiitmus iš dabartinės sesijos?', - onDeletePublishedEntry: 'Tikrai norite ištrinti šį publikuotą įrašą?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Tai ištrins visus nepublikuotus pakeitimus įraše, taip pat neišsaugotus pakeitimus per dabartinę sesiją. Vis tiek norite trinti?', - onDeleteUnpublishedChanges: - 'Visi Jūsų pakeitimai įraše bus panaikinti. Ar tikrai norite trinti jį?', - loadingEntry: 'Kraunamas įrašas...', - confirmLoadBackup: - 'Radome Jūsų įrenginyje išsaugota juodraštį šiam įrašui, ar norite jį atgaivinti ir naudoti?', - }, - editorToolbar: { - publishing: 'Publikuojama...', - publish: 'Publikuoti', - published: 'Jau publikuota', - unpublish: 'Atšaukti paskelbimą', - duplicate: 'Daryti dublį', - unpublishing: 'Nebeskelbiama...', - publishAndCreateNew: 'Publikuoti šitą, po to kurti kažką naujo', - publishAndDuplicate: 'Publikuoti šitą, po to kurti šito dublį', - deleteUnpublishedChanges: 'Ištrinti publikuotus pakeitimus', - deleteUnpublishedEntry: 'Ištrinti nepaskelbtą įrašą', - deletePublishedEntry: 'Ištrinti paskelbtą įrašą', - deleteEntry: 'Panaikinti įrašą', - saving: 'Išsaugojama...', - save: 'Išsaugoti', - deleting: 'Trinama...', - updating: 'Atnaujinama...', - status: 'Statusą: %{status}', - backCollection: ' Rašoma %{collectionLabel} kolekcijoje', - unsavedChanges: 'Neišsaugoti pakeitimai', - changesSaved: 'Pakeitimai išsauogti', - draft: 'Juodraštis', - inReview: 'Peržiūrima redakcijoje', - ready: 'Paruošta', - publishNow: 'Skelbti naują', - deployPreviewPendingButtonLabel: 'Tikrinti, ar yra demonstracija', - deployPreviewButtonLabel: 'Žiūrėti demonstraciją (netiesiogiai)', - deployButtonLabel: 'Žiūrėti tiesiogiai tinklalapyje', - }, - editorWidgets: { - markdown: { - bold: 'Paryškinta', - italic: 'Pasvariu tekstu (italic)', - code: 'Kodo šriftas', - link: 'Nuoroda (adresas)', - linkPrompt: 'Įveskite adresą čia', - headings: 'Antraštės', - quote: 'Citata', - bulletedList: 'Sąrašas su ženkleliais', - numberedList: 'Sąrašas su numeriais', - addComponent: 'Pridėti komponentą', - richText: 'Normali peržiūra', - markdown: 'Rodyti be formatavimo (Markdown)', - }, - image: { - choose: 'Pasirinkti vaizdą', - chooseDifferent: 'Pasirinkti skirtingą vaizdą', - remove: 'Panaikinti vaizdą', - }, - file: { - choose: 'Pasirinkti failą', - chooseDifferent: 'Pasirinkti kitą failą', - remove: 'Panaikinti failą', - }, - unknownControl: { - noControl: "Klaida: valdiklis taisyklingai neveikia. No control for widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Klaida: valdiklis taisyklingai neveikia. No preview for widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Antraštė 1', - headingTwo: 'Antraštė 2', - headingThree: 'Antraštė 3', - headingFour: 'Antraštė 4', - headingFive: 'Antraštė 5', - headingSix: 'Antraštė 6', - }, - datetime: { - now: 'Dabar', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Juodraštis', - }, - mediaLibrary: { - onDelete: 'Ar jūs tikrai norite ištrinti pasirinktą mediją?', - fileTooLarge: - 'Failas per didelis.\nNustatymuose (konfigūracijoje) nurodyta, kad failai negali viršyti %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Kraunama...', - noResults: 'Nėra rezultatų.', - noAssetsFound: 'Turinio nerasta.', - noImagesFound: 'Vaizdų nerasta.', - private: 'Privatu ', - images: 'Vaizdai', - mediaAssets: 'Medijos turinys', - search: 'Paieška...', - uploading: 'Keliama...', - upload: 'Įkelti', - download: 'Parsiųsti', - deleting: 'Trinama...', - deleteSelected: 'Ištrinti parinktus', - chooseSelected: 'Pasirinkti parinktus', - }, - }, - ui: { - default: { - goBackToSite: 'Grįžti atgal į tinklalapį', - }, - errorBoundary: { - title: 'Klaida', - details: 'Buvo klaida - jeigu galite, prašome ', - reportIt: 'pranešti apie techninę problemą „GitHub“ puslapyje.', - detailsHeading: 'Detalės', - privacyWarning: - 'Opening an issue pre-populates it with the error message and debugging data.\nPlease verify the information is correct and remove sensitive data if exists.', - recoveredEntry: { - heading: 'Sugrąžintas dokumentas', - warning: 'Prašome kopijuoti/įkluoti šitą kažkur prieš uždarant puslapį!', - copyButtonLabel: 'Nukopijuoti į iškarpinę', - }, - }, - settingsDropdown: { - logOut: 'Atsijungti', - }, - toast: { - onFailToLoadEntries: 'Nepavyko užkrauti įrašo: %{details}', - onFailToLoadDeployPreview: 'Nepavyko užkrauti demonstracijos lango: %{details}', - onFailToPersist: 'Nepavyko išlaikyti įrašo: %{details}', - onFailToDelete: 'Nepayvko ištrinti: %{details}', - onFailToUpdateStatus: 'Nepavyko pakeisti statusą: %{details}', - missingRequiredField: - 'Pasitikrinkite — kažkurio (ar kelių) laukelių neužpildėte. Tai padarius galėsite išsaugoti įrašą.', - entrySaved: 'Įrašas išsaugotos', - entryPublished: 'Įrašas publikuotas', - entryUnpublished: 'Įrašas nepublikuotas', - onFailToPublishEntry: 'Nepavyko publikuoti: %{details}', - onFailToUnpublishEntry: 'Nepavyko panaikinti publikavimą: %{details}', - entryUpdated: 'Įrašo statusas pakeistas', - onDeleteUnpublishedChanges: 'Nepublikuoti pakeitimai ištrinti', - onFailToAuth: 'Nepavyko prisijungti: %{details}', - onLoggedOut: - 'Mes jus atjungėme. Jeigu yra poreikis, sukurkite duomenų atsarginę kopiją. Galite tiesiog iš naujo prisijungti.', - onBackendDown: - 'Deja, serveris šiuo metu neveikia. Bandykite iš naujo dar sykį arba šiek tiek vėliau. Detalės: %{details}', - }, - }, - workflow: { - workflow: { - loading: 'Kraunamas turinys', - workflowHeading: 'Redakcijos darbo eiga', - newPost: 'Naujas įrašas', - description: - '%{smart_count} įrašas laukia Jūsų peržiūrėjimo, %{readyCount} jau gali būti publikuojamas. |||| %{smart_count} elementai laukia Jūsų peržiūrėjimo, %{readyCount} jau gali būti publikuojami. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} pagal %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'oagal %{author}', - deleteChanges: 'Trinti keitimus', - deleteNewEntry: 'Trinti naują įrašą', - publishChanges: 'Publikuoti keitimus', - publishNewEntry: 'Kurti naują įrašą', - }, - workflowList: { - onDeleteEntry: 'Ar tikrai norite ištrinti šį įrašą?', - onPublishingNotReadyEntry: - 'Tik įrašai su statusu „Paruošta“ gali būti patvirtinti. Prašome pajudinti įrašo kortelę link „Paruošta“ stulpelio, kad galėtumėte publikuoti įrašą.', - onPublishEntry: 'Ar jūs tikrai norite publikuoti šį įrašą?', - draftHeader: 'Juodraščiai', - inReviewHeader: 'Peržiūrima redakcijoje', - readyHeader: 'Paruošta', - currentEntries: '%{smart_count} įrašas |||| %{smart_count} įrašai', - }, - }, -}; - -export default lt; diff --git a/packages/netlify-cms-locales/src/nb_no/index.js b/packages/netlify-cms-locales/src/nb_no/index.js deleted file mode 100644 index 72ce9faa..00000000 --- a/packages/netlify-cms-locales/src/nb_no/index.js +++ /dev/null @@ -1,255 +0,0 @@ -const nb_no = { - auth: { - login: 'Logg inn', - loggingIn: 'Logger inn..', - loginWithNetlifyIdentity: 'Logg på med Netlify Identity', - loginWithBitbucket: 'Logg på med Bitbucket', - loginWithGitHub: 'Logg på med GitHub', - loginWithGitLab: 'Logg på med GitLab', - errors: { - email: 'Du må skrive inn e-posten din.', - password: 'Du må skrive inn passordet ditt.', - identitySettings: - 'Fant ingen innstillinger for Identity. Hvis du skal bruke git-gateway må du skru på Identity service og Git Gateway.', - }, - }, - app: { - header: { - content: 'Innhold', - workflow: 'Arbeidsflyt', - media: 'Media', - quickAdd: 'Hurtiginnlegg', - }, - app: { - errorHeader: 'Det oppstod en feil under lastingen av CMS konfigurasjonen', - configErrors: 'Konfigurasjonsfeil', - checkConfigYml: 'Sjekk config.yml filen.', - loadingConfig: 'Laster konfigurasjon...', - waitingBackend: 'Venter på backend...', - }, - notFoundPage: { - header: 'Ikke funnet', - }, - }, - collection: { - sidebar: { - collections: 'Samlinger', - searchAll: 'Søk i alle', - }, - collectionTop: { - sortBy: 'Sorter etter', - viewAs: 'Vis som', - newButton: 'Ny %{collectionLabel}', - ascending: 'Stigende', - descending: 'Synkende', - }, - entries: { - loadingEntries: 'Laster innlegg...', - cachingEntries: 'Mellomlagrer innlegg...', - longerLoading: 'Dette kan ta opptil flere minutter', - noEntries: 'Ingen innlegg', - }, - defaultFields: { - author: { - label: 'Forfatter', - }, - updatedOn: { - label: 'Oppdatert', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'valgfritt', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} er påkrevd.', - regexPattern: '%{fieldLabel} samsvarer ikke med mønsteret: %{pattern}.', - processing: '%{fieldLabel} blir prosessert.', - range: '%{fieldLabel} må være mellom %{minValue} og %{maxValue}.', - min: '%{fieldLabel} må minst være %{minValue}.', - max: '%{fieldLabel} må være %{maxValue} eller mindre.', - rangeCount: '%{fieldLabel} må ha mellom %{minCount} og %{maxCount} element(er).', - rangeCountExact: '%{fieldLabel} må ha nøyaktig %{count} element(er).', - rangeMin: '%{fieldLabel} må minst ha %{minCount} element(er).', - rangeMax: '%{fieldLabel} må ha %{maxCount} eller færre element(er).', - }, - }, - editor: { - onLeavePage: 'Er du sikker på du vil navigere bort fra denne siden?', - onUpdatingWithUnsavedChanges: 'Du må lagre endringene dine før du oppdaterer status.', - onPublishingNotReady: 'Du må endre status til "Klar" før du publiserer.', - onPublishingWithUnsavedChanges: 'Du må lagre endringene dine før du kan publisere.', - onPublishing: 'Er du sikker på at du vil publisere?', - onUnpublishing: 'Er du sikker på at du vil avpublisere innlegget?', - onDeleteWithUnsavedChanges: - 'Er du sikker på at du vil slette et publisert innlegg med tilhørende ulagrede endringer?', - onDeletePublishedEntry: 'Er du sikker på at du vil slette dette publiserte innlegget?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Handlingen sletter endringer som ikke er publisert eller lagret enda. Er du sikker på du vil fortsette?', - onDeleteUnpublishedChanges: - 'Alle endringer som ikke er publisert i dette innlegget vil gå tapt. Vil du fortsette?', - loadingEntry: 'Laster innlegg...', - confirmLoadBackup: 'Vil du gjenopprette tidligere endringer som ikke har blitt lagret?', - }, - editorToolbar: { - publishing: 'Publiserer...', - publish: 'Publiser', - published: 'Publisert', - unpublish: 'Avpubliser', - duplicate: 'Dupliser', - unpublishing: 'Avpubliserer...', - publishAndCreateNew: 'Publiser og lag nytt', - publishAndDuplicate: 'Publiser og dupliser', - deleteUnpublishedChanges: 'Slett upubliserte endringer', - deleteUnpublishedEntry: 'Slett upublisert innlegg', - deletePublishedEntry: 'Slett publisert innlegg', - deleteEntry: 'Slett innlegg', - saving: 'Lagrer...', - save: 'Lagre', - deleting: 'Sletter...', - updating: 'Oppdaterer...', - status: 'Status: %{status}', - backCollection: ' Skriver i samlingen %{collectionLabel}', - unsavedChanges: 'Ulagrede endringer', - changesSaved: 'Endringer lagret', - draft: 'Kladd', - inReview: 'Til godkjenning', - ready: 'Klar', - publishNow: 'Publiser nå', - deployPreviewPendingButtonLabel: 'Kontroller forhåndsvisning', - deployPreviewButtonLabel: 'Vis forhåndsvisning', - deployButtonLabel: 'Vis i produksjon', - }, - editorWidgets: { - markdown: { - richText: 'Rik-tekst', - markdown: 'Markdown', - }, - image: { - choose: 'Velg et bilde', - chooseDifferent: 'Velg et annet bilde', - remove: 'Fjern bilde', - }, - file: { - choose: 'Velg en fil', - chooseDifferent: 'Velg en annen fil', - remove: 'Fjern fil', - }, - unknownControl: { - noControl: "Ingen konfigurasjon for widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Ingen forhåndsvisning tilgjengelig for '%{widget}'.", - }, - headingOptions: { - headingOne: 'Overskrift 1', - headingTwo: 'Overskrift 2', - headingThree: 'Overskrift 3', - headingFour: 'Overskrift 4', - headingFive: 'Overskrift 5', - headingSix: 'Overskrift 6', - }, - datetime: { - now: 'Nå', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Kladd', - }, - mediaLibrary: { - onDelete: 'Er du sikker på at du vil slette markert element?', - fileTooLarge: 'Filen er for stor.\nMaksimal konfiguert filstørrelse er %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Laster...', - noResults: 'Ingen resultater.', - noAssetsFound: 'Ingen elementer funnet.', - noImagesFound: 'Ingen bilder funnet.', - private: 'Privat ', - images: 'Bilder', - mediaAssets: 'Mediebibliotek', - search: 'Søk...', - uploading: 'Laster opp...', - upload: 'Last opp', - download: 'Last ned', - deleting: 'Sletter...', - deleteSelected: 'Slett markert', - chooseSelected: 'Velg markert', - }, - }, - ui: { - default: { - goBackToSite: 'Gå tilbake til siden', - }, - errorBoundary: { - title: 'Feil', - details: 'Det har oppstått en feil. Det er fint om du ', - reportIt: 'oppretter et issue på GitHub.', - detailsHeading: 'Detaljer', - privacyWarning: - 'Når du åpner et issue forhåndsutfylles feil og feilsøkingsdata. Dobbeltsjekk at informasjonen er riktig, og fjern eventuelle sensitive data.', - recoveredEntry: { - heading: 'Gjenopprettet dokument', - warning: 'Det kan være lurt å ta kopi av innholdet før navigerer bort fra denne siden!', - copyButtonLabel: 'Kopier til utklippstavle', - }, - }, - settingsDropdown: { - logOut: 'Logg ut', - }, - toast: { - onFailToLoadEntries: 'Kunne ikke laste innlegg: %{details}', - onFailToLoadDeployPreview: 'Kunne ikke laste forhåndsvisning: %{details}', - onFailToPersist: 'Kunne ikke lagre: %{details}', - onFailToDelete: 'Kunne ikke slette: %{details}', - onFailToUpdateStatus: 'Kunne ikke laste opp: %{details}', - missingRequiredField: - 'Oisann, ser ut som du glemte et påkrevd felt. Du må fylle det ut før du kan fortsette.', - entrySaved: 'Innlegg lagret', - entryPublished: 'Innlegg publisert', - entryUnpublished: 'Innlegg avpublisert', - onFailToPublishEntry: 'Kunne ikke publisere: %{details}', - onFailToUnpublishEntry: 'Kunne ikke avpublisere: %{details}', - entryUpdated: 'Innleggsstatus oppdatert', - onDeleteUnpublishedChanges: 'Avpubliserte endringer slettet', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Laster innlegg for redaksjonell arbeidsflyt', - workflowHeading: 'Redaksjonell arbeidsflyt', - newPost: 'Nytt innlegg', - description: - '%{smart_count} innlegg trenger gjennomgang, og %{readyCount} er klar til publisering. |||| %{smart_count} innlegg trenger gjennomgang, og %{readyCount} er klar til publisering ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} av %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'av %{author}', - deleteChanges: 'Slett endringer', - deleteNewEntry: 'Slett nytt innlegg', - publishChanges: 'Publiser endringer', - publishNewEntry: 'Publiser nytt innlegg', - }, - workflowList: { - onDeleteEntry: 'Er du sikker på du vil slette innlegget?', - onPublishingNotReadyEntry: - 'Du kan bare publisere innlegg i "Klar" kolonnen. Trekk kortet til riktig kolonne for å fortsette.', - onPublishEntry: 'Er du sikker på du vil publisere innlegget?', - draftHeader: 'Kladd', - inReviewHeader: 'Gjennomgås', - readyHeader: 'Klar', - currentEntries: '%{smart_count} innlegg |||| %{smart_count} innlegg', - }, - }, -}; - -export default nb_no; diff --git a/packages/netlify-cms-locales/src/nl/index.js b/packages/netlify-cms-locales/src/nl/index.js deleted file mode 100644 index ba4b96b5..00000000 --- a/packages/netlify-cms-locales/src/nl/index.js +++ /dev/null @@ -1,303 +0,0 @@ -const nl = { - auth: { - login: 'Inloggen', - loggingIn: 'Inloggen...', - loginWithNetlifyIdentity: 'Inloggen met Netlify Identity', - loginWithAzure: 'Inloggen met Azure', - loginWithBitbucket: 'Inloggen met Bitbucket', - loginWithGitHub: 'Inloggen met GitHub', - loginWithGitLab: 'Inloggen met GitLab', - errors: { - email: 'Voer uw email in.', - password: 'Voer uw wachtwoord in.', - identitySettings: - 'Netlify Identity instellingen niet gevonden. Wanneer u git-gateway als backend gebruikt moet u de Identity service en Git Gateway activeren in uw Netlify instellingen.', - }, - }, - app: { - header: { - content: 'Inhoud', - workflow: 'Workflow', - media: 'Media', - quickAdd: 'Snel toevoegen', - }, - app: { - errorHeader: 'Fout bij het laden van de CMS configuratie', - configErrors: 'configuratiefouten', - checkConfigYml: 'Controleer je config.yml bestand', - loadingConfig: 'Configuatie laden...', - waitingBackend: 'Wachten op server...', - }, - notFoundPage: { - header: 'Niet gevonden', - }, - }, - collection: { - sidebar: { - collections: 'Inhoudstypen', - allCollections: 'Alle inhoudstypen', - searchAll: 'Zoeken', - searchIn: 'Zoeken in', - }, - collectionTop: { - sortBy: 'Sorteer op', - viewAs: 'Bekijk als', - newButton: 'Voeg %{collectionLabel} toe', - ascending: 'Oplopend', - descending: 'Aflopend', - searchResults: 'Zoekresultaten voor "%{searchTerm}"', - searchResultsInCollection: 'Zoekresultaten voor "%{searchTerm}" in %{collection}', - filterBy: 'Filteren op', - groupBy: 'Groepeer op', - }, - entries: { - loadingEntries: 'Items laden', - cachingEntries: 'Items cachen', - longerLoading: 'Dit kan een paar minuten duren', - noEntries: 'Geen items', - }, - groups: { - other: 'Anders', - negateLabel: 'Geen %{label}', - }, - defaultFields: { - author: { - label: 'Auteur', - }, - updatedOn: { - label: 'Bijgewerkt op', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'optioneel', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} is vereist.', - regexPattern: '%{fieldLabel} komt niet overeen met het patroon: %{pattern}.', - processing: '%{fieldLabel} wordt verwerkt.', - range: '%{fieldLabel} moet tussen %{minValue} en %{maxValue} liggen.', - min: '%{fieldLabel} moet tenminste %{minValue} bevatten.', - max: '%{fieldLabel} moet hoogstens %{maxValue} bevatten.', - rangeCount: '%{fieldLabel} moet tussen %{minCount} en %{maxCount} item(s) bevatten.', - rangeCountExact: '%{fieldLabel} moet exact %{count} item(s) bevatten.', - rangeMin: '%{fieldLabel} moet tenminste %{minCount} item(s) bevatten.', - rangeMax: '%{fieldLabel} moet hoogstens %{maxCount} item(s) bevatten.', - }, - i18n: { - writingInLocale: '%{locale} aan het bewerken', - }, - }, - editor: { - onLeavePage: 'Weet je zeker dat je deze pagina wilt verlaten?', - onUpdatingWithUnsavedChanges: - 'Er zijn nog niet-opgeslagen wijzigingen. Bewaar ze voordat u de status bijwerkt.', - onPublishingNotReady: 'Stel de status in op "Voltooid" voordat u publiceert.', - onPublishingWithUnsavedChanges: - 'Er zijn nog niet-opgeslagen wijzigingen. Bewaar deze voordat u publiceert.', - onPublishing: 'Weet u zeker dat u dit item wil publiceren?', - onUnpublishing: 'Weet u zeker dat u de publicatie voor dit item ongedaan wilt maken?', - onDeleteWithUnsavedChanges: - 'Weet u zeker dat u dit gepubliceerde item en uw niet-opgeslagen wijzigingen uit de huidige sessie wilt verwijderen?', - onDeletePublishedEntry: 'Weet u zeker dat u dit gepubliceerde item wilt verwijderen?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Alle niet-gepubliceerde wijzigingen in dit item worden verwijderd, evenals uw niet-opgeslagen wijzigingen uit de huidige sessie. Wilt u nog steeds verwijderen?', - onDeleteUnpublishedChanges: - 'Alle niet-gepubliceerde wijzigingen in dit item worden verwijderd. Wilt u nog steeds verwijderen?', - loadingEntry: 'Item laden...', - confirmLoadBackup: 'Voor dit item is een lokale back-up hersteld, wilt u deze gebruiken?', - }, - editorInterface: { - toggleI18n: 'Wissel i18n', - togglePreview: 'Wissel voorvertoning', - toggleScrollSync: 'Synchroniseer scrollen', - }, - editorToolbar: { - publishing: 'Publiceren...', - publish: 'Publiceer', - published: 'Gepubliceerd', - unpublish: 'Publicatie terugtrekken', - duplicate: 'Dupliceren', - unpublishing: 'Publicatie ongedaan maken...', - publishAndCreateNew: 'Publiceer en maak nieuw item aan', - publishAndDuplicate: 'Publiceer en dupliceer item', - deleteUnpublishedChanges: 'Verwijder niet-gepubliceerde wijzigingen', - deleteUnpublishedEntry: 'Niet-gepubliceerd item verwijderen', - deletePublishedEntry: 'Gepubliceerd item verwijderen', - deleteEntry: 'Item verwijderen', - saving: 'Opslaan...', - save: 'Opslaan', - deleting: 'Verwijderen...', - updating: 'Bijwerken...', - status: 'Status: %{status}', - backCollection: ' Terug naar %{collectionLabel}', - unsavedChanges: 'Niet-opgeslagen wijzigingen', - changesSaved: 'Wijzigingen opgeslagen', - draft: 'Concept', - inReview: 'Wordt beoordeeld', - ready: 'Klaar', - publishNow: 'Publiceer nu', - deployPreviewPendingButtonLabel: 'Controleer of voorvertoning geladen is', - deployPreviewButtonLabel: 'Bekijk voorvertoning', - deployButtonLabel: 'Bekijk Live', - }, - editorWidgets: { - markdown: { - bold: 'Vet', - italic: 'Cursief', - code: 'Code', - link: 'Link', - linkPrompt: 'Voer de URL in', - headings: 'Hoofdtekst', - quote: 'Quote', - bulletedList: 'Lijst met opsommingstekens', - numberedList: 'Genummerde lijst', - addComponent: 'Voeg component toe', - richText: 'Rijke tekst', - markdown: 'Markdown', - }, - image: { - choose: 'Kies een afbeelding', - chooseUrl: 'Voeg toe via URL', - replaceUrl: 'Vervang met URL', - promptUrl: 'Voer de URL van de afbeelding in', - chooseDifferent: 'Kies een andere afbeelding', - remove: 'Verwijder afbeelding', - }, - file: { - choose: 'Kies een bestand', - chooseUrl: 'Voeg toe via URL', - replaceUrl: 'Vervang met URL', - promptUrl: 'Voer de URL van het bestand in', - chooseDifferent: 'Kies een ander bestand', - remove: 'Verwijder bestand', - }, - unknownControl: { - noControl: "Geen control voor widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Geen voorvertoning voor widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - datetime: { - now: 'Nu', - }, - list: { - add: 'Voeg %{item} toe', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Concept', - copy: 'Kopieer', - copyUrl: 'Kopieer URL', - copyPath: 'Kopieer pad', - copyName: 'Kopieer naam', - copied: 'Gekopieerd', - }, - mediaLibrary: { - onDelete: 'Weet u zeker dat u de geselecteerde media wilt verwijderen?', - fileTooLarge: - 'Het bestand is te groot.\n De instellingen staan geen bestanden toe groter dan %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Laden...', - noResults: 'Geen resultaten.', - noAssetsFound: 'Geen media gevonden.', - noImagesFound: 'Geen afbeeldingen gevonden.', - private: 'Privé', - images: 'Afbeeldingen', - mediaAssets: 'Media', - search: 'Zoeken...', - uploading: 'Uploaden...', - upload: 'Nieuwe uploaden', - download: 'Downloaden', - deleting: 'Verwijderen...', - deleteSelected: 'Verwijder selectie', - chooseSelected: 'Gebruik selectie', - }, - }, - ui: { - default: { - goBackToSite: 'Ga terug naar site', - }, - errorBoundary: { - title: 'Fout', - details: 'Er is een fout opgetreden - ', - reportIt: 'maak er alstublieft een melding van.', - detailsHeading: 'Details', - privacyWarning: - 'Als u een probleem opent, wordt het vooraf gevuld met het foutbericht en foutopsporingsgegevens. \nControleer of de informatie correct is en verwijder, indien aanwezig, gevoelige gegevens.', - recoveredEntry: { - heading: 'Hersteld document', - warning: 'Kopieer / plak dit ergens voordat u weggaat!', - copyButtonLabel: 'Kopieer naar klembord', - }, - }, - settingsDropdown: { - logOut: 'Uitloggen', - }, - toast: { - onFailToLoadEntries: 'Kan item niet laden: %{details}', - onFailToLoadDeployPreview: 'Kan voorvertoning niet laden: %{details}', - onFailToPersist: 'Kan item niet opslaan: %{details}', - onFailToDelete: 'Kan item niet verwijderen: %{details}', - onFailToUpdateStatus: 'Kan status niet updaten: %{details}', - missingRequiredField: 'Oeps, sommige verplichte velden zijn niet ingevuld.', - entrySaved: 'Item opgeslagen', - entryPublished: 'Item gepubliceerd', - entryUnpublished: 'Publicatie teruggetrokken', - onFailToPublishEntry: 'Kan item niet publiceren: %{details}', - onFailToUnpublishEntry: 'Kan item niet terugtrekken: %{details}', - entryUpdated: 'Status van item geüpdatet', - onDeleteUnpublishedChanges: 'Niet-gepubliceerde wijzigingen verwijderd', - onFailToAuth: '%{details}', - onLoggedOut: 'Je bent uitgelogd, back-up alstublieft uw data log daarna in', - onBackendDown: - 'De backend-service ondervindt een storing. Zie% {details} voor meer informatie', - }, - }, - workflow: { - workflow: { - loading: 'Redactionele Workflow items laden', - workflowHeading: 'Redactionele Workflow', - newPost: 'Nieuw bericht', - description: - '%{smart_count} item wacht op beoordeling, %{readyCount} klaar om live te gaan. |||| %{smart_count} items wachten op beoordeling, %{readyCount} klaar om live te gaan. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} door %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'door %{author}', - deleteChanges: 'Verwijder wijzigingen', - deleteNewEntry: 'Verwijder nieuw item', - publishChanges: 'Publiceer wijzigingen', - publishNewEntry: 'Publiceer nieuw item', - }, - workflowList: { - onDeleteEntry: 'Weet u zeker dat u dit item wilt verwijderen?', - onPublishingNotReadyEntry: - 'Alleen items met de status "Gereed" kunnen worden gepubliceerd. Sleep de kaart naar de kolom "Gereed" om publiceren mogelijk te maken.', - onPublishEntry: 'Weet u zeker dat u dit item wilt publiceren?', - draftHeader: 'Concepten', - inReviewHeader: 'Wordt beoordeeld', - readyHeader: 'Klaar', - currentEntries: '%{smart_count} item |||| %{smart_count} items', - }, - }, -}; - -export default nl; diff --git a/packages/netlify-cms-locales/src/nn_no/index.js b/packages/netlify-cms-locales/src/nn_no/index.js deleted file mode 100644 index 6be99524..00000000 --- a/packages/netlify-cms-locales/src/nn_no/index.js +++ /dev/null @@ -1,256 +0,0 @@ -const nn_no = { - auth: { - login: 'Logg inn', - loggingIn: 'Loggar inn..', - loginWithNetlifyIdentity: 'Logg på med Netlify Identity', - loginWithBitbucket: 'Logg på med Bitbucket', - loginWithGitHub: 'Logg på med GitHub', - loginWithGitLab: 'Logg på med GitLab', - errors: { - email: 'Du må skriva inn e-posten din.', - password: 'Du må skriva inn passordet ditt.', - identitySettings: - 'Fann ingen innstillingar for Identity. Om du ynskjer å nytte git-gateway må du hugse å skru på Identity service og Git Gateway', - }, - }, - app: { - header: { - content: 'Innhald', - workflow: 'Arbeidsflyt', - media: 'Media', - quickAdd: 'Hurtiginnlegg', - }, - app: { - errorHeader: 'Noko gjekk gale under lastinga av CMS konfigurasjonen', - configErrors: 'Konfigurasjonsfeil', - checkConfigYml: 'Sjå over config.yml fila.', - loadingConfig: 'Lastar konfigurasjon...', - waitingBackend: 'Ventar på backend...', - }, - notFoundPage: { - header: 'Ikkje funnen', - }, - }, - collection: { - sidebar: { - collections: 'Samlingar', - searchAll: 'Søk i alle', - }, - collectionTop: { - sortBy: 'Sorter etter', - viewAs: 'Vis som', - newButton: 'Ny %{collectionLabel}', - ascending: 'Stigande', - descending: 'Synkande', - }, - entries: { - loadingEntries: 'Laster innlegg...', - cachingEntries: 'Mellomlagrar innlegg...', - longerLoading: 'Dette kan ta fleire minutt', - noEntries: 'Ingen innlegg', - }, - defaultFields: { - author: { - label: 'Forfatter', - }, - updatedOn: { - label: 'Oppdatert', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'valfritt', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} krevast.', - regexPattern: '%{fieldLabel} samsvarar ikkje med mønsteret: %{pattern}.', - processing: '%{fieldLabel} vart prosessert.', - range: '%{fieldLabel} må vera mellom %{minValue} og %{maxValue}.', - min: '%{fieldLabel} må minst vera %{minValue}.', - max: '%{fieldLabel} må vera %{maxValue} eller mindre.', - rangeCount: '%{fieldLabel} må ha mellom %{minCount} og %{maxCount} element.', - rangeCountExact: '%{fieldLabel} må ha nøyaktig %{count} element.', - rangeMin: '%{fieldLabel} må minst ha %{minCount} element.', - rangeMax: '%{fieldLabel} må ha %{maxCount} eller færre element.', - }, - }, - editor: { - onLeavePage: 'Er du sikker på at du vil navigere bort frå denne sida?', - onUpdatingWithUnsavedChanges: 'Du må lagra endringane dine før du endrar status', - onPublishingNotReady: 'Du må endre status til "Klar" før du publiserer', - onPublishingWithUnsavedChanges: 'Du må laga endringane dine før du kan publisere.', - onPublishing: 'Er du sikker på at vil publisere?', - onUnpublishing: 'Er du sikker på at du vil avpublisere innlegget?', - onDeleteWithUnsavedChanges: - 'Er du sikkert på at du vil slette eit publisert innlegg med tilhøyrande ulagra endringar?', - onDeletePublishedEntry: 'Er du sikker på at du vil slette dette publiserte innlegget?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Handlinga slettar endringar som ikkje er publisert eller lagra. Vil du halde fram?', - onDeleteUnpublishedChanges: - 'Alle endringar som ikkje er publisert vil gå tapt. Vil du halde fram?', - loadingEntry: 'Lastar innlegg...', - confirmLoadBackup: - 'Ynskjer du å gjennopprette tidlegare endringar som ikkje har verta lagra?', - }, - editorToolbar: { - publishing: 'Publiserer...', - publish: 'Publiser', - published: 'Publisert', - unpublish: 'Avpubliser', - duplicate: 'Dupliser', - unpublishing: 'Avpubliserer...', - publishAndCreateNew: 'Publiser og lag nytt', - publishAndDuplicate: 'Publiser og dupliser', - deleteUnpublishedChanges: 'Slett upubliserte endringar', - deleteUnpublishedEntry: 'Slett upublisert innlegg', - deletePublishedEntry: 'Slett publisert innlegg', - deleteEntry: 'Slettar innlegg', - saving: 'Lagrar...', - save: 'Lagre', - deleting: 'Slettar...', - updating: 'Oppdaterer...', - status: 'Status: %{status}', - backCollection: ' Skriv i samlinga %{collectionLabel}', - unsavedChanges: 'Ulagra endringar', - changesSaved: 'Endringar lagret', - draft: 'Kladd', - inReview: 'Til godkjenning', - ready: 'Klar', - publishNow: 'Publiser no', - deployPreviewPendingButtonLabel: 'Kontroller førehandsvisning', - deployPreviewButtonLabel: 'Sjå førehandsvisning', - deployButtonLabel: 'Sjå i produksjon', - }, - editorWidgets: { - markdown: { - richText: 'Rik-tekst', - markdown: 'Markdown', - }, - image: { - choose: 'Vel bilete', - chooseDifferent: 'Vel eit anna bilete', - remove: 'Fjern bilete', - }, - file: { - choose: 'Vel fil', - chooseDifferent: 'Vel ei anna fil', - remove: 'Fjern fil', - }, - unknownControl: { - noControl: "Ingen konfigurasjon for widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Ingen førehandsvisning tilgjengeleg for '%{widget}'.", - }, - headingOptions: { - headingOne: 'Overskrift 1', - headingTwo: 'Overskrift 2', - headingThree: 'Overskrift 3', - headingFour: 'Overskrift 4', - headingFive: 'Overskrift 5', - headingSix: 'Overskrift 6', - }, - datetime: { - now: 'No', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Kladd', - }, - mediaLibrary: { - onDelete: 'Er du sikker på at du vil slette markert element?', - fileTooLarge: 'Fila er for stor.\nMaksimal konfiguert filstorleik er %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Lastar...', - noResults: 'Ingen resultat.', - noAssetsFound: 'Ingen elementer funne.', - noImagesFound: 'Ingen bilete funne.', - private: 'Privat ', - images: 'Bileter', - mediaAssets: 'Mediebibliotek', - search: 'Søk...', - uploading: 'Lastar opp...', - upload: 'Last opp', - download: 'Last ned', - deleting: 'Slettar...', - deleteSelected: 'Slett markert', - chooseSelected: 'Vel markert', - }, - }, - ui: { - default: { - goBackToSite: 'Attende til sida', - }, - errorBoundary: { - title: 'Feil', - details: 'Ein feil har oppstått. Det er fint om du ', - reportIt: 'opnar eit issue på GitHub.', - detailsHeading: 'Detaljer', - privacyWarning: - 'Når du opnar eit issue vart feil og feilsøkingsdata automatisk fylt ut. Hugs å sjå over at alt ser greitt ut, og ikkje inneheld sensitive data.', - recoveredEntry: { - heading: 'Gjenopprettet dokument', - warning: 'Det kan vere lurt å ta kopi av innhaldet før du navigerer bort frå denne sida!', - copyButtonLabel: 'Kopier til utklippstavle', - }, - }, - settingsDropdown: { - logOut: 'Logg ut', - }, - toast: { - onFailToLoadEntries: 'Kunne ikkje laste innlegg: %{details}', - onFailToLoadDeployPreview: 'Kunne ikkje laste førehandsvisning: %{details}', - onFailToPersist: 'Kunne ikkje lagre: %{details}', - onFailToDelete: 'Kunne ikkje slette: %{details}', - onFailToUpdateStatus: 'Kunne ikkje laste opp: %{details}', - missingRequiredField: - 'Oisann, gløymte du noko? Alle påkrevde felt må fyllast ut før du kan halde fram', - entrySaved: 'Innlegg lagra', - entryPublished: 'Innlegg publisert', - entryUnpublished: 'Innlegg avpublisert', - onFailToPublishEntry: 'Kunne ikkje publisere: %{details}', - onFailToUnpublishEntry: 'Kunne ikkje avpublisere: %{details}', - entryUpdated: 'Innleggsstatus oppdatert', - onDeleteUnpublishedChanges: 'Avpubliserte endringar sletta', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Lastar innlegg for redaksjonell arbeidsflyt', - workflowHeading: 'Redaksjonell arbeidsflyt', - newPost: 'Nytt innlegg', - description: - '%{smart_count} innlegg treng gjennomgong, og %{readyCount} er klar til publisering. |||| %{smart_count} innlegg treng gjennomgong, og %{readyCount} er klar til publisering ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} av %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'av %{author}', - deleteChanges: 'Slett endringar', - deleteNewEntry: 'Slett nytt innlegg', - publishChanges: 'Publiser endringar', - publishNewEntry: 'Publiser nytt innlegg', - }, - workflowList: { - onDeleteEntry: 'Er du sikker på du vil slette innlegget?', - onPublishingNotReadyEntry: - 'Du kan berre publisere innlegg i "Klar" kolonna. Dra kortet til riktig stad for å halde fram.', - onPublishEntry: 'Er du sikker på du vil publisere innlegget?', - draftHeader: 'Kladd', - inReviewHeader: 'Gjennomgås', - readyHeader: 'Klar', - currentEntries: '%{smart_count} innlegg |||| %{smart_count} innlegg', - }, - }, -}; - -export default nn_no; diff --git a/packages/netlify-cms-locales/src/pl/index.js b/packages/netlify-cms-locales/src/pl/index.js deleted file mode 100644 index 6d6eba0e..00000000 --- a/packages/netlify-cms-locales/src/pl/index.js +++ /dev/null @@ -1,308 +0,0 @@ -const pl = { - auth: { - login: 'Zaloguj się', - loggingIn: 'Logowanie...', - loginWithNetlifyIdentity: 'Zaloguj przez konto Netlify', - loginWithAzure: 'Zaloguj przez konto Azure', - loginWithBitbucket: 'Zaloguj przez Bitbucket', - loginWithGitHub: 'Zaloguj przez GitHub', - loginWithGitLab: 'Zaloguj przez GitLab', - errors: { - email: 'Wprowadź swój adres email', - password: 'Wprowadź swoje hasło', - identitySettings: - 'Brak dostępu do ustawień tożsamości. Jeśli używasza backendu git-gateway upewnij się, że usługa tożsamośći (Identity service) oraz Git Gateway są włączone.', - }, - }, - app: { - header: { - content: 'Treść', - workflow: 'Przebieg redakcyjny', - media: 'Multimedia', - quickAdd: 'Szybkie dodawanie', - }, - app: { - errorHeader: 'Błąd ładowania konfiguracji CMS', - configErrors: 'Błędy konfiguracji', - checkConfigYml: 'Sprawdź plik config.yml.', - loadingConfig: 'Ładowanie konfiguracji...', - waitingBackend: 'Oczekiwanie na backend...', - }, - notFoundPage: { - header: 'Nie znaleziono', - }, - }, - collection: { - sidebar: { - collections: 'Kolekcje', - allCollections: 'Wszystkie kolekcje', - searchAll: 'Wyszukaj wszystkie', - searchIn: 'Wyszukaj w', - }, - collectionTop: { - sortBy: 'Sortuj po', - viewAs: 'Wyświetl jako', - newButton: 'Nowy %{collectionLabel}', - ascending: 'Rosnąco', - descending: 'Malejąco', - searchResults: 'Wyszukaj wyniki dla %{searchTerm}', - searchResultsInCollection: 'Wyszukaj wyniki dla %{searchTerm} w %{collection}', - filterBy: 'Filtruj po', - groupBy: 'Grupuj po', - }, - entries: { - loadingEntries: 'Ładowanie pozycji...', - cachingEntries: 'Ładowanie pozycji do pamięci podręcznej...', - longerLoading: 'To może zająć kilka minut', - noEntries: 'Brak pozycji', - }, - groups: { - other: 'Inne', - negateLabel: 'Nie %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Zaktualizowano', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opcjonalne', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} jest wymagane.', - regexPattern: '%{fieldLabel} nie pasuje do formatu: %{pattern}.', - processing: '%{fieldLabel} jest przetwarzane.', - range: '%{fieldLabel} musi być pomiędzy %{minValue} a %{maxValue}.', - min: '%{fieldLabel} musi być co najmniej %{minValue}.', - max: '%{fieldLabel} musi być %{maxValue} lub mniej.', - rangeCount: '%{fieldLabel} musi mieć od %{minCount} do %{maxCount} elementów', - rangeCountExact: '%{fieldLabel} musi mieć %{count} elementów', - rangeMin: '%{fieldLabel} musi mieć przynajmniej %{minCount} elementów', - rangeMax: '%{fieldLabel} może mieć maksymalnie %{maxCount} elementów', - invalidPath: `'%{path}' nie jest poprawna`, - pathExists: `Ścieżka '%{path}' już istnieje`, - }, - i18n: { - writingInLocale: 'Pisz w języku %{locale}', - }, - }, - editor: { - onLeavePage: 'Czy na pewno chcesz opuścić tę stronę?', - onUpdatingWithUnsavedChanges: - 'Masz niezapisane zmiany, proszę zapisz je przed aktualizacją statusu.', - onPublishingNotReady: 'Proszę zaktualizować status do "Gotowe" przed publikacją.', - onPublishingWithUnsavedChanges: 'Masz niezapisane zmiany, proszę zapisz je przed publikacją.', - onPublishing: 'Czy na pewno chcesz opublikować tę pozycję?', - onUnpublishing: 'Czy na pewno chcesz cofnąć publikację tej pozycji?', - onDeleteWithUnsavedChanges: - 'Czy na pewno chcesz usunąć tę opublikowaną pozycję, a także niezapisane zmiany z bieżącej sesji?', - onDeletePublishedEntry: 'Czy na pewno chcesz usunąć tę opublikowaną pozycję?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Spowoduje to usunięcie wszystkich nieopublikowanych zmian tej pozycji, a także niezapisanych zmian z bieżącej sesji. Czy nadal chcesz usunąć?', - onDeleteUnpublishedChanges: - 'Wszystkie nieopublikowane zmiany tej pozycji zostaną usunięte. Czy nadal chcesz usunąć?', - loadingEntry: 'Ładowanie pozycji...', - confirmLoadBackup: 'Odzyskano lokalną kopię zapasową tej pozycji, czy chcesz jej użyć?', - }, - editorInterface: { - toggleI18n: 'Przełącz i18n', - togglePreview: 'Przełącz podgląd', - toggleScrollSync: 'Synchroniczne przesuwanie', - }, - editorToolbar: { - publishing: 'Publikowanie...', - publish: 'Opublikuj', - published: 'Opublikowane', - unpublish: 'Cofnij publikację', - duplicate: 'Zduplikuj', - unpublishing: 'Cofanie publikacji...', - publishAndCreateNew: 'Opublikuj i dodaj nowy', - publishAndDuplicate: 'Opublikuj i zduplikuj', - deleteUnpublishedChanges: 'Usuń nieopublikowane zmiany', - deleteUnpublishedEntry: 'Usuń nieopublikowaną pozycję', - deletePublishedEntry: 'Usuń opublikowaną pozycję', - deleteEntry: 'Usuń pozycję', - saving: 'Zapisywanie...', - save: 'Zapisz', - statusInfoTooltipDraft: - 'Dodano jako wersję roboczą. Aby zakończyć i oddać do recenzji zmień status na `Do recenzji`', - statusInfoTooltipInReview: - 'Wpis jest w trakcie recenzji, żadne dodatkowe akcje nie są wymagane. Jeśli chcesz, możesz jeszcze nanieść zmiany.', - deleting: 'Usuwanie...', - updating: 'Uaktualnianie...', - status: 'Status: %{status}', - backCollection: ' Edycja treści w zbiorze %{collectionLabel}', - unsavedChanges: 'Niezapisane zmiany', - changesSaved: 'Zmiany zapisane', - draft: 'Wersja robocza', - inReview: 'W recenzji', - ready: 'Gotowe', - publishNow: 'Opublikuj teraz', - deployPreviewPendingButtonLabel: 'Sprawdź, czy istnieje podgląd', - deployPreviewButtonLabel: 'Zobacz podgląd', - deployButtonLabel: 'Zobacz na żywo', - }, - editorWidgets: { - markdown: { - bold: 'Pogrubienie', - italic: 'Kursywa', - code: 'Kod', - link: 'Link', - linkPrompt: 'Dodaj adres URL', - headings: 'Nagłówki', - quote: 'Cytat', - bulletedList: 'Lista punktowana', - numberedList: 'Lista numerowana', - addComponent: 'Dodaj komponent', - richText: 'Tekst sformatowany', - markdown: 'Markdown', - }, - image: { - choose: 'Wybierz zdjęcie', - chooseUrl: 'Dodaj adres URL zdjęcia', - replaceUrl: 'Zmień adres URL zdjęcia', - promptUrl: 'Wprować adres URL zdjęcia', - chooseDifferent: 'Zmień zdjęcie', - remove: 'Usuń zdjęcie', - }, - file: { - choose: 'Wybierz plik', - chooseUrl: 'Dodaj adres URL pliku', - replaceUrl: 'Zmień adres URL zdjęcia', - promptUrl: 'Dodaj adres URL pliku', - chooseDifferent: 'Wybierz inny plik', - remove: 'Usuń plik', - }, - unknownControl: { - noControl: "Brak kontrolki dla widżetu '%{widget}'.", - }, - unknownPreview: { - noPreview: "Brak podglądu dla widżetu '%{widget}'.", - }, - headingOptions: { - headingOne: 'Nagłówek 1', - headingTwo: 'Nagłówek 2', - headingThree: 'Nagłówek 3', - headingFour: 'Nagłówek 4', - headingFive: 'Nagłówek 5', - headingSix: 'Nagłówek 6', - }, - datetime: { - now: 'Teraz', - }, - list: { - add: 'Dodaj %{item}', - addType: 'Dodaj nowy %{item}', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Wersja robocza', - copy: 'Kopiuj', - copyUrl: 'Kopiuj URL', - copyPath: 'Kopiuj ścieżkę', - copyName: 'Kopiuj nazwę', - copied: 'Skopiowano', - }, - mediaLibrary: { - onDelete: 'Czy na pewno chcesz usunąć zaznaczone multimedia?', - fileTooLarge: 'Plik jest za duży.\nUstawiony maksymalny rozmiar pliku: %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Ładowanie...', - noResults: 'Brak wyników.', - noAssetsFound: 'Nie znaleziono żadnych zasobów.', - noImagesFound: 'Nie znaleziono żadnych obrazów.', - private: 'Prywatne ', - images: 'Obrazy', - mediaAssets: 'Zasoby multimedialne', - search: 'Szukaj...', - uploading: 'Przesyłanie...', - upload: 'Prześlij nowe', - download: 'Pobierz', - deleting: 'Usuwanie...', - deleteSelected: 'Usuń zaznaczone', - chooseSelected: 'Wybierz zaznaczone', - }, - }, - ui: { - default: { - goBackToSite: 'Wróć do strony', - }, - errorBoundary: { - title: 'Błąd', - details: 'Wystąpił błąd - proszę ', - reportIt: 'zgłoś to.', - detailsHeading: 'Szczegóły', - privacyWarning: - 'Nowe zgłoszenie zostanie wstępnie wypełnione danymi o błędzie.\nZweryfikuj czy dane są poprawne i usuń wrażliwe informacje jeśli takie zostały dodane.', - recoveredEntry: { - heading: 'Odzyskany dokument', - warning: 'Proszę skopiuj/wklej to gdzieś zanim opuścisz tę stronę!', - copyButtonLabel: 'Skopiuj do schowka', - }, - }, - settingsDropdown: { - logOut: 'Wyloguj się', - }, - toast: { - onFailToLoadEntries: 'Nie udało się załadować pozycji: %{details}', - onFailToLoadDeployPreview: 'Nie udało się załadować podglądu: %{details}', - onFailToPersist: 'Nie udało się zapisać pozycji: %{details}', - onFailToDelete: 'Nie udało się usunąć pozycji: %{details}', - onFailToUpdateStatus: 'Nie udało się zaktualizować statusu: %{details}', - missingRequiredField: 'Ups, przegapiłeś wymagane pole. Proszę uzupełnij przed zapisaniem.', - entrySaved: 'Pozycja zapisana', - entryPublished: 'Pozycja opublikowana', - entryUnpublished: 'Cofnięto publikację pozycji', - onFailToPublishEntry: 'Nie udało się opublikować: %{details}', - onFailToUnpublishEntry: 'Nie udało się cofnąć publikacji pozycji: %{details}', - entryUpdated: 'Zaktualizowano status pozycji', - onDeleteUnpublishedChanges: 'Nieopublikowane zmiany zostały usunięte', - onFailToAuth: '%{details}', - onLoggedOut: 'Zostałeś wylogowany, utwórz kopię zapasową danych i zaloguj się ponownie.', - onBackendDown: 'Usługa backendu uległa awarii. Zobacz więcej informacji: %{details}', - }, - }, - workflow: { - workflow: { - loading: 'Ładowanie pozycji przebiegu redakcyjnego', - workflowHeading: 'Przebieg redakcyjny', - newPost: 'Nowa pozycja', - description: - '%{smart_count} pozycja oczekuje na recenzję, %{readyCount} oczekuje na publikacje. |||| %{smart_count} pozycje oczekują na recenzję, %{readyCount} oczekuje na publikacje. |||| %{smart_count} pozycji oczekuje na recenzje, %{readyCount} oczekuje na publikacje. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} przez %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'przez %{author}', - deleteChanges: 'Usuń zmiany', - deleteNewEntry: 'Usuń nową pozycję', - publishChanges: 'Opublikuj zmiany', - publishNewEntry: 'Opublikuj nową pozycję', - }, - workflowList: { - onDeleteEntry: 'Czy na pewno chcesz usunąć tę pozycję?', - onPublishingNotReadyEntry: - 'Tylko pozycje o statusie „Gotowe” mogą być publikowane. Przeciągnij proszę kartę do kolumny „Gotowe do publikacji”, aby umożliwić publikowanie.', - onPublishEntry: 'Czy na pewno chcesz opublikować tę pozycję?', - draftHeader: 'Wersje robocze', - inReviewHeader: 'W recenzji', - readyHeader: 'Gotowe do publikacji', - currentEntries: - '%{smart_count} pozycja |||| %{smart_count} pozycje |||| %{smart_count} pozycji', - }, - }, -}; - -export default pl; diff --git a/packages/netlify-cms-locales/src/pt/index.js b/packages/netlify-cms-locales/src/pt/index.js deleted file mode 100644 index 96ee9205..00000000 --- a/packages/netlify-cms-locales/src/pt/index.js +++ /dev/null @@ -1,310 +0,0 @@ -const pt = { - auth: { - login: 'Entrar', - loggingIn: 'Entrando...', - loginWithNetlifyIdentity: 'Entrar com o Netlify Identity', - loginWithAzure: 'Entrar com o Azure', - loginWithBitbucket: 'Entrar com o Bitbucket', - loginWithGitHub: 'Entrar com o GitHub', - loginWithGitLab: 'Entrar com o GitLab', - errors: { - email: 'Certifique-se de inserir seu e-mail.', - password: 'Por favor, insira sua senha.', - identitySettings: - 'Não foi possível acessar as configurações de identidade. Ao usar o back-end git-gateway, certifique-se de habilitar o serviço Identity e o Git Gateway.', - }, - }, - app: { - header: { - content: 'Conteúdos', - workflow: 'Fluxo de Trabalho', - media: 'Mídia', - quickAdd: 'Adição rápida', - }, - app: { - errorHeader: 'Erro ao carregar a configuração do CMS', - configErrors: 'Erros de configuração', - checkConfigYml: 'Verifique o arquivo config.yml.', - loadingConfig: 'Carregando configuração...', - waitingBackend: 'Aguardando o back-end...', - }, - notFoundPage: { - header: 'Não Encontrado', - }, - }, - collection: { - sidebar: { - collections: 'Coleções', - allCollections: 'Todas as Coleções', - searchAll: 'Pesquisar em todos', - searchIn: 'Pesquisar em', - }, - collectionTop: { - sortBy: 'Ordenar por', - viewAs: 'Visualizar como', - newButton: 'Novo(a) %{collectionLabel}', - ascending: 'Ascendente', - descending: 'Descendente', - searchResults: 'Resultados da busca por "%{searchTerm}"', - searchResultsInCollection: 'Resultados da busca por "%{searchTerm}" em %{collection}', - filterBy: 'Filtrar por', - groupBy: 'Agrupar por', - }, - entries: { - loadingEntries: 'Carregando Entradas', - cachingEntries: 'Armazenando Entradas em Cache', - longerLoading: 'Isso pode levar alguns minutos', - noEntries: 'Nenhuma Entrada', - }, - groups: { - other: 'Outro', - negateLabel: 'Não %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Atualizado em', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opcional', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} é obrigatório.', - regexPattern: '%{fieldLabel} não corresponde com o padrão: %{pattern}.', - processing: '%{fieldLabel} está processando.', - range: '%{fieldLabel} deve estar entre %{minValue} e %{maxValue}.', - min: '%{fieldLabel} deve ser, no mínimo, %{minValue}.', - max: '%{fieldLabel} deve ser igual ou menor que %{maxValue}.', - rangeCount: '%{fieldLabel} deve ser entre %{minCount} e %{maxCount}.', - rangeCountExact: '%{fieldLabel} deve ser exatamente %{count}.', - rangeMin: '%{fieldLabel} deve ter, pelo menos, %{minCount}.', - rangeMax: '%{fieldLabel} deve ter %{maxCount} ou menos.', - invalidPath: `'%{path}' não é um caminho válido`, - pathExists: `O caminho '%{path}' já existe`, - }, - i18n: { - writingInLocale: 'Escrevendo em %{locale}', - }, - }, - editor: { - onLeavePage: 'Tem certeza que deseja sair desta página?', - onUpdatingWithUnsavedChanges: - 'Há mudanças não salvas. Por favor, salve-as antes de atualizar o status.', - onPublishingNotReady: 'Por favor, altere o status para "Pronto" antes de publicar.', - onPublishingWithUnsavedChanges: - 'Há mudanças não salvas. Por favor, salve-as antes de publicar.', - onPublishing: 'Tem certeza que deseja publicar essa entrada?', - onUnpublishing: 'Tem certeza que deseja cancelar a publicação dessa entrada?', - onDeleteWithUnsavedChanges: - 'Tem certeza de que deseja excluir esta entrada publicada, bem como as alterações não salvas da sessão atual?', - onDeletePublishedEntry: 'Tem certeza de que deseja excluir esta entrada publicada?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Isso excluirá todas as alterações não publicadas nesta entrada, bem como as alterações não salvas da sessão atual. Você ainda deseja excluir?', - onDeleteUnpublishedChanges: - 'Todas as alterações não publicadas nesta entrada serão excluídas. Você ainda deseja excluir?', - loadingEntry: 'Carregando entrada...', - confirmLoadBackup: 'Um backup local foi recuperado para esta entrada. Deseja usá-lo?', - }, - editorInterface: { - toggleI18n: 'Mudar i18n', - togglePreview: 'Mudar pré-visualização', - toggleScrollSync: 'Sincronizar rolagem', - }, - editorToolbar: { - publishing: 'Publicando...', - publish: 'Publicar', - published: 'Publicado', - unpublish: 'Despublicar', - duplicate: 'Duplicado', - unpublishing: 'Despublicando...', - publishAndCreateNew: 'Publicar e criar novo(a)', - publishAndDuplicate: 'Publicar e duplicar', - deleteUnpublishedChanges: 'Excluir alterações não publicadas', - deleteUnpublishedEntry: 'Excluir entrada não publicada', - deletePublishedEntry: 'Excluir entrada publicada', - deleteEntry: 'Excluir entrada', - saving: 'Salvando...', - save: 'Salvar', - statusInfoTooltipDraft: - "Entrada definida como rascunho. Para finalizar e enviá-la a revisão, mude seu estado para 'Em revisão'", - statusInfoTooltipInReview: - 'Entrada está sendo revisada, nenhuma ação extra é requirida. Porém, você ainda pode fazer mudanças adicionais enquanto ela está sendo revisada.', - deleting: 'Excluindo...', - updating: 'Atualizando...', - status: 'Status: %{status}', - backCollection: ' Escrevendo na coleção %{collectionLabel}', - unsavedChanges: 'Alterações não salvas', - changesSaved: 'Alterações salvas', - draft: 'Rascunho', - inReview: 'Em revisão', - ready: 'Pronto', - publishNow: 'Publicar agora', - deployPreviewPendingButtonLabel: 'Verificar se há Pré-visualização', - deployPreviewButtonLabel: 'Ver Pré-visualização', - deployButtonLabel: 'Ver em Produção', - }, - editorWidgets: { - markdown: { - bold: 'Negrito', - italic: 'Itálico', - code: 'Código', - link: 'Link', - linkPrompt: 'Insira a URL do link', - headings: 'Cabeçalho', - quote: 'Citação', - bulletedList: 'Lista Pontilhada', - numberedList: 'Lista Numerada', - addComponent: 'Adicionar Componente', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'Escolha uma imagem', - chooseUrl: 'Inserir de uma URL', - replaceUrl: 'Substituir com uma URL', - promptUrl: 'Insira a URL da imagem', - chooseDifferent: 'Escolha uma imagem diferente', - remove: 'Remover imagem', - }, - file: { - choose: 'Escolha um arquivo', - chooseUrl: 'Inserir de uma URL', - replaceUrl: 'Substituir com uma URL', - promptUrl: 'Insira a URL do arquivo', - chooseDifferent: 'Escolha um arquivo diferente', - remove: 'Remover arquivo', - }, - unknownControl: { - noControl: "Nenhum controle para o widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Nenhuma pré-visualização para o widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Título nível 1', - headingTwo: 'Título nível 2', - headingThree: 'Título nível 3', - headingFour: 'Título nível 4', - headingFive: 'Título nível 5', - headingSix: 'Título nível 6', - }, - datetime: { - now: 'Agora', - }, - list: { - add: 'Adicionar %{item}', - addType: 'Adicionar %{item} item', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Rascunho', - copy: 'Copiar', - copyUrl: 'Copiar URL', - copyPath: 'Copiar Caminho', - copyName: 'Copiar Nome', - copied: 'Copiado', - }, - mediaLibrary: { - onDelete: 'Tem certeza de que deseja excluir a mídia selecionada?', - fileTooLarge: - 'Arquivo muito grande.\nConfigurado para não permitir arquivos maiores que %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Carregando...', - noResults: 'Nenhum resultado.', - noAssetsFound: 'Nenhum recurso encontrado.', - noImagesFound: 'Nenhuma imagem encontrada.', - private: 'Privado ', - images: 'Imagens', - mediaAssets: 'Recursos de mídia', - search: 'Pesquisar...', - uploading: 'Enviando...', - upload: 'Enviar novo', - download: 'Download', - deleting: 'Excluindo...', - deleteSelected: 'Excluir selecionado', - chooseSelected: 'Escolher selecionado', - }, - }, - ui: { - default: { - goBackToSite: 'Voltar ao site', - }, - errorBoundary: { - title: 'Erro', - details: 'Ocorreu um erro - por favor ', - reportIt: 'relatar.', - detailsHeading: 'Detalhes', - privacyWarning: - 'Ao abrir uma issue, ela é preenchida com a mensagem de erro e o log de debug.\nPor favor, verifique se a informação está correta e remova dados sensíveis caso existam.', - recoveredEntry: { - heading: 'Documento recuperado', - warning: 'Copie/cole isso em algum lugar antes de sair!', - copyButtonLabel: 'Copiar para área de transferência', - }, - }, - settingsDropdown: { - logOut: 'Sair', - }, - toast: { - onFailToLoadEntries: 'Falha ao carregar a entrada: %{details}', - onFailToLoadDeployPreview: 'Falha ao carregar a pré-visualização: %{details}', - onFailToPersist: 'Falha ao persistir na entrada: %{details}', - onFailToDelete: 'Falha ao excluir a entrada: %{details}', - onFailToUpdateStatus: 'Falha ao atualizar status: %{details}', - missingRequiredField: - 'Ops, você perdeu um campo obrigatório. Por favor, preencha antes de salvar.', - entrySaved: 'Entrada salva', - entryPublished: 'Entrada publicada', - entryUnpublished: 'Entrada despublicada', - onFailToPublishEntry: 'Falha ao publicar: %{details}', - onFailToUnpublishEntry: 'Falha ao cancelar a publicação da entrada: %{details}', - entryUpdated: 'Status da entrada atualizado', - onDeleteUnpublishedChanges: 'Alterações não publicadas excluídas', - onFailToAuth: '%{details}', - onLoggedOut: 'Você foi desconectado. Por favor, salve as alterações e entre novamente', - onBackendDown: 'O serviço de back-end está fora do ar. Veja %{details} para mais informações', - }, - }, - workflow: { - workflow: { - loading: 'Carregando entradas do Fluxo de Trabalho Editorial', - workflowHeading: 'Fluxo de Trabalho Editorial', - newPost: 'Nova Publicação', - description: - '%{smart_count} entrada aguardando revisão, %{readyCount} pronta para publicação. |||| %{smart_count} entradas aguardando revisão, %{readyCount} pronta para publicação.', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} por %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'por %{author}', - deleteChanges: 'Excluir alterações', - deleteNewEntry: 'Excluir nova entrada', - publishChanges: 'Publicar alterações', - publishNewEntry: 'Publicar nova entrada', - }, - workflowList: { - onDeleteEntry: 'Tem certeza de que deseja excluir esta entrada?', - onPublishingNotReadyEntry: - 'Somente itens com o status "Pronto" podem ser publicados. Arraste o cartão para a coluna "Pronto" para poder publicar.', - onPublishEntry: 'Tem certeza de que quer publicar esta entrada?', - draftHeader: 'Rascunhos', - inReviewHeader: 'Em Revisão', - readyHeader: 'Prontos', - currentEntries: '%{smart_count} entrada |||| %{smart_count} entradas', - }, - }, -}; - -export default pt; diff --git a/packages/netlify-cms-locales/src/ro/index.js b/packages/netlify-cms-locales/src/ro/index.js deleted file mode 100644 index 266101b5..00000000 --- a/packages/netlify-cms-locales/src/ro/index.js +++ /dev/null @@ -1,301 +0,0 @@ -const ro = { - auth: { - login: 'Autentifică-te', - loggingIn: 'Te autentificăm...', - loginWithNetlifyIdentity: 'Autentifică-te cu Netlify Identity', - loginWithAzure: 'Autentifică-te cu Azure', - loginWithBitbucket: 'Autentifică-te cu Bitbucket', - loginWithGitHub: 'Autentifică-te cu GitHub', - loginWithGitLab: 'Autentifică-te cu GitLab', - errors: { - email: 'Asigură-te că ai introdus email-ul.', - password: 'Te rugăm introdu parola.', - identitySettings: - 'Nu s-a putut accesa serviciul de autentificare. Dacă folosești git-gateway, asigură-te că ai activat serviciul Identity și Git-Gateway.', - }, - }, - app: { - header: { - content: 'Conținut', - workflow: 'Workflow', - media: 'Fișiere', - quickAdd: 'Adaugă', - }, - app: { - errorHeader: 'A apărut o eroare cu configurarea CMS-ului.', - configErrors: 'Au apărut erori de configurare.', - checkConfigYml: 'Verifică fișierul de configurare (config.yml).', - loadingConfig: 'Se încarcă configurările...', - waitingBackend: 'Așteptăm după backend...', - }, - notFoundPage: { - header: 'Pagină inexistentă.', - }, - }, - collection: { - sidebar: { - collections: 'Colecții', - allCollections: 'Toate colecțiile', - searchAll: 'Căutare', - searchIn: 'Caută în', - }, - collectionTop: { - sortBy: 'Sortează', - viewAs: 'Vizualizează ca', - newButton: 'Adaugă %{collectionLabel}', - ascending: 'Ascendent', - descending: 'Descendent', - searchResults: 'Rezultatele căutării pentru "%{searchTerm}"', - searchResultsInCollection: 'Rezultatele căutării pentru "%{searchTerm}" în %{collection}', - filterBy: 'Filtrează după', - groupBy: 'Grupează după', - }, - entries: { - loadingEntries: 'Se încarcă intrările...', - cachingEntries: 'Se salvează temporar intrările...', - longerLoading: 'Ar putea dura câteva minute.', - noEntries: 'Nu există intrări.', - }, - groups: { - other: 'Altul', - negateLabel: 'Nu %{label}', - }, - defaultFields: { - author: { - label: 'Autor', - }, - updatedOn: { - label: 'Actualizat la', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'opțional', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel}” este obligatoriu.', - regexPattern: '%{fieldLabel} nu se potrivește după modelul: %{pattern}.', - processing: '%{fieldLabel} se procesează.', - range: '%{fieldLabel} poate fi între %{minValue} și %{maxValue}.', - min: '%{fieldLabel} poate fi mai mare sau egal cu %{minValue}.', - max: '%{fieldLabel} poate fi mai mic sau egal cu %{maxValue}.', - rangeCount: '%{fieldLabel} poate avea între %{minCount} și %{maxCount} intrări.', - rangeCountExact: '%{fieldLabel} trebuie să conțină exact %{count} intrări.', - minCount: '%{fieldLabel} trebuie să conțină cel puțin %{minCount} intrări.', - maxCount: '%{fieldLabel} trebuie să conțină cel mult %{maxCount} intrări.', - invalidPath: `'%{path}' nu este o cale validă.`, - pathExists: `Calea '%{path}' există deja.`, - }, - i18n: { - writingInLocale: 'Scrii în limba %{locale}', - }, - }, - editor: { - onLeavePage: 'Ești sigur/ă că dorești să părăsești pagina?', - onUpdatingWithUnsavedChanges: - 'Există modificări nesalvate! Te rugăm salvează înainte de a actualiza statusul.', - onPublishingNotReady: 'Actualizează statusul la „Gata” înainte de publicare.', - onPublishingWithUnsavedChanges: - 'Există modificări nesalvate, salvează-le înainte de publicare.', - onPublishing: 'Ești sigur/ă că dorești să publici acest articol?', - onUnpublishing: 'Ești sigur/ă că dorești să anulezi publicarea acestui articol?', - onDeleteWithUnsavedChanges: - 'Ești sigur/ă că dorești să ștergi această publicare, dar și modificările nesalvate din sesiunea curentă?', - onDeletePublishedEntry: 'Ești sigur/ă că dorești să ștergi această publicare?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Se vor șterge toate modificările nepublicate din aceast articol și modificările nesalvate din sesiunea curentă. Continui cu ștergerea?', - onDeleteUnpublishedChanges: - 'Toate modificările nepublicate din acest articol vor fi șterse. Continui cu ștergerea?', - loadingEntry: 'Se încarcă...', - confirmLoadBackup: - 'Un backup local a fost recuperat pentru această intrare, dorești să îl folosești?', - }, - editorInterface: { - toggleI18n: 'Comută limba', - togglePreview: 'Comută previzualizarea', - toggleScrollSync: 'Sincronizează scroll-ul', - }, - editorToolbar: { - publishing: 'Se publică...', - publish: 'Publicare', - published: 'Publicat', - unpublish: 'Anulează publicarea', - duplicate: 'Duplifică', - unpublishing: 'Se anulează publicarea...', - publishAndCreateNew: 'Publicare apoi crează altul', - publishAndDuplicate: 'Publicare apoi duplifică', - deleteUnpublishedChanges: 'Șterge modificări nepublicate', - deleteUnpublishedEntry: 'Șterge intrarea nepublicată', - deletePublishedEntry: 'Șterge intrarea publicată', - deleteEntry: 'Șterge intrare', - saving: 'Se salvează...', - save: 'Salvează', - deleting: 'Se șterge...', - updating: 'Se actualizează...', - status: 'Status: %{status}', - backCollection: ' Scrii în colecția „%{collectionLabel}”', - unsavedChanges: 'Modificări nesalvate', - changesSaved: 'Modificări salvate', - draft: 'Ciornă', - inReview: 'În revizuire', - ready: 'Gata', - publishNow: 'Publicare', - deployPreviewPendingButtonLabel: 'Verifică publicare', - deployPreviewButtonLabel: 'Previzualizare', - deployButtonLabel: 'Vezi publicarea', - }, - editorWidgets: { - markdown: { - bold: 'Bold', - italic: 'Italic', - code: 'Cod sursă', - link: 'Link', - linkPrompt: 'Scrie URL-ul', - headings: 'Titluri', - quote: 'Citat', - bulletedList: 'Listă cu puncte', - numberedList: 'Listă cu numere', - addComponent: 'Adaugă componentă', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'Alege o imagine', - chooseUrl: 'Inserează din URL', - replaceUrl: 'Schimbă cu URL', - promptUrl: 'Introdu URL-ul imaginii', - chooseDifferent: 'Alege altă imagine', - remove: 'Șterge imaginea', - }, - file: { - choose: 'Alege un fișier', - chooseUrl: 'Inserează din URL', - replaceUrl: 'Schimbă cu URL', - promptUrl: 'Introdu URL-ul fișierului', - chooseDifferent: 'Alege alt fișier', - remove: 'Șterge fișier', - }, - unknownControl: { - noControl: 'Widget-ul „%{widget}” nu are configurări valabile.', - }, - unknownPreview: { - noPreview: 'Nu există previzualizare pentru widget-ul „%{widget}”.', - }, - headingOptions: { - headingOne: 'Titlu 1', - headingTwo: 'Titlu 2', - headingThree: 'Titlu 3', - headingFour: 'Titlu 4', - headingFive: 'Titlu 5', - headingSix: 'Titlu 6', - }, - datetime: { - now: 'Acum', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Ciornă', - copy: 'Copiază', - copyUrl: 'Copiază URL', - copyPath: 'Copiază cale', - copyName: 'Copiaza nume', - copied: 'Copiat', - }, - mediaLibrary: { - onDelete: 'Ești sigur/ă că dorești să ștergi fișierul selectat?', - fileTooLarge: 'Fișier prea mare.\nConfigurarea nu permite fișiere mai mari de %{size} KB.', - }, - mediaLibraryModal: { - loading: 'Se încarcă...', - noResults: 'Nu sunt rezultate.', - noAssetsFound: 'Nu s-au găsit fișiere.', - noImagesFound: 'Nu s-au găsit imagini.', - private: 'Privat ', - images: 'Imagini', - mediaAssets: 'Fișiere media', - search: 'Caută...', - uploading: 'Se încarcă...', - upload: 'Încarcă', - download: 'Descarcă', - deleting: 'Se șterge...', - deleteSelected: 'Șterge fișierele selectate', - chooseSelected: 'Alege fișierele selectate', - }, - }, - ui: { - default: { - goBackToSite: 'Înapoi la site', - }, - errorBoundary: { - title: 'Eroare', - details: 'A apărut o eroare - te rugăm ', - reportIt: 'Deschide o problemă pe GitHub.', - detailsHeading: 'Detalii', - privacyWarning: - 'Problema deschisă va fi precompletată cu mesajul de eroare și datele de depanare.\nTe rugăm verifică datele să fie corecte și șterge orice fel de date personale.', - recoveredEntry: { - heading: 'Document recuperat', - warning: 'Te rugăm să faci copy/paste la datele acestea undeva înainte de ieșire!', - copyButtonLabel: 'Copiază în clipboard', - }, - }, - settingsDropdown: { - logOut: 'Ieșire din cont', - }, - toast: { - onFailToLoadEntries: 'A eșuat încărcarea intrării: %{details}', - onFailToLoadDeployPreview: 'A eșuat încărcarea previzualizării: %{details}', - onFailToPersist: 'A eșuat persistarea intrării: %{details}', - onFailToDelete: 'A eșuat ștergerea intrării: %{details}', - onFailToUpdateStatus: 'A eșuat actualizarea status-ului: %{details}', - missingRequiredField: 'Oops, ai ratat un câmp obligatoriu. Completează-l pentru a salva.', - entrySaved: 'Intrare salvată', - entryPublished: 'Intrare publicată', - entryUnpublished: 'Publicare anulată', - onFailToPublishEntry: 'A eșuat publicarea: %{details}', - onFailToUnpublishEntry: 'A eșuat anularea publicării: %{details}', - entryUpdated: 'S-a actualizat status-ul intrării', - onDeleteUnpublishedChanges: 'Modificări nepublicate șterse', - onFailToAuth: '%{details}', - onLoggedOut: 'Ai fost delogat, te rugăm salvează orice date și autentifică-te din nou.', - onBackendDown: 'Există probleme la server. Vezi %{details} pentru mai multe informații.', - }, - }, - workflow: { - workflow: { - loading: 'Se încarcă intrările din Workflow-ul Editorial', - workflowHeading: 'Workflow Editorial', - newPost: 'Postare nouă', - description: - '%{smart_count} pregătite de revizuire, %{readyCount} gata de publicare. |||| %{smart_count} pregătite de revizuire, %{readyCount} gata de publicare. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} de %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'de %{author}', - deleteChanges: 'Modificări șterse', - deleteNewEntry: 'Șterge intrarea nouă', - publishChanges: 'Publicare modificări', - publishNewEntry: 'Publicare intrare nouă', - }, - workflowList: { - onDeleteEntry: 'Ești sigur/ă că dorești ștergerea intrării?', - onPublishingNotReadyEntry: - 'Numai intrări cu status-ul „Gata” pot fi publicate. Trage un card în coloana „Gata” pentru a putea publica.', - onPublishEntry: 'Ești sigur/ă că dorești să faci publicarea?', - draftHeader: 'Ciorne', - inReviewHeader: 'În revizuire', - readyHeader: 'Gata', - currentEntries: '%{smart_count} intrări |||| %{smart_count} intrări', - }, - }, -}; - -export default ro; diff --git a/packages/netlify-cms-locales/src/ru/index.js b/packages/netlify-cms-locales/src/ru/index.js deleted file mode 100644 index b39d0249..00000000 --- a/packages/netlify-cms-locales/src/ru/index.js +++ /dev/null @@ -1,298 +0,0 @@ -const ru = { - auth: { - login: 'Войти', - loggingIn: 'Вхожу...', - loginWithNetlifyIdentity: 'Войти через Netlify Identity', - loginWithAzure: 'Войти через Azure', - loginWithBitbucket: 'Войти через Bitbucket', - loginWithGitHub: 'Войти через GitHub', - loginWithGitLab: 'Войти через GitLab', - errors: { - email: 'Введите ваш email.', - password: 'Введите пароль.', - identitySettings: - 'Нет доступа к настройкам. Если используете git-gateway, убедитесь, что включили Identity service и Git Gateway.', - }, - }, - app: { - header: { - content: 'Записи', - workflow: 'Документооборот', - media: 'Медиафайлы', - quickAdd: 'Быстрое добавление', - }, - app: { - errorHeader: 'Ошибка загрузки конфигурации CMS', - configErrors: 'Ошибки конфигурации', - checkConfigYml: 'Проверьте свой config.yml файл.', - loadingConfig: 'Загрузка конфигурации…', - waitingBackend: 'Ожидание ответа от бэкенда…', - }, - notFoundPage: { - header: 'Не найден', - }, - }, - collection: { - sidebar: { - collections: 'Коллекции', - allCollections: 'Все коллекции', - searchAll: 'Искать повсюду', - searchIn: 'Искать в', - }, - collectionTop: { - sortBy: 'Сортировать по', - viewAs: 'Вид', - newButton: 'Создать %{collectionLabel}', - ascending: 'По возрастанию', - descending: 'По убывания', - searchResults: 'Результаты по запросу "%{searchTerm}"', - searchResultsInCollection: 'Результаты по запросу "%{searchTerm}" в %{collection}', - filterBy: 'Фильтровать по', - groupBy: 'Группировать по', - }, - entries: { - loadingEntries: 'Загрузка записей…', - cachingEntries: 'Кэширование записей…', - longerLoading: 'Это может занять несколько минут', - noEntries: 'Нет записей', - }, - groups: { - other: 'Другая', - negateLabel: 'Не %{label}', - }, - defaultFields: { - author: { - label: 'Автор', - }, - updatedOn: { - label: 'Обновлено', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'необязательный', - }, - }, - editorControlPane: { - widget: { - required: 'Необходимо указать значение поля %{fieldLabel}.', - regexPattern: 'Значение поля %{fieldLabel} не соответствует шаблону: %{pattern}.', - processing: 'Значение поля %{fieldLabel} обрабатывается…', - range: 'Значение поля %{fieldLabel} должно быть между %{minValue} и %{maxValue}.', - min: 'Значение поля %{fieldLabel} должно быть не менее %{minValue}.', - max: 'Значение поля %{fieldLabel} должно быть %{maxValue} или менее.', - rangeCount: '%{fieldLabel} должно содержать от %{minCount} до %{maxCount} элементов.', - rangeCountExact: '%{fieldLabel} должно содержать строго %{count} элементов.', - rangeMin: '%{fieldLabel} должно содержать не менее %{minCount} элементов.', - rangeMax: '%{fieldLabel} должно содержать %{maxCount} или менее элементов.', - invalidPath: `Путь '%{path}' содежрит ошибки`, - pathExists: `Путь '%{path}' уже существует`, - }, - i18n: { - writingInLocale: 'Пишем на %{locale}', - }, - }, - editor: { - onLeavePage: 'Вы уверены, что хотите покинуть эту страницу?', - onUpdatingWithUnsavedChanges: - 'У вас есть несохраненные изменения, сохраните их перед обновлением статуса.', - onPublishingNotReady: 'Пожалуйста, измените статус на «Готов» перед публикацией.', - onPublishingWithUnsavedChanges: - 'У вас есть несохраненные изменения, сохраните их перед публикацией.', - onPublishing: 'Вы уверены, что хотите опубликовать эту запись?', - onUnpublishing: 'Вы уверены, что хотите отменить публикацию этой записи?', - onDeleteWithUnsavedChanges: - 'Вы уверены, что хотите удалить эту опубликованную запись, а также несохраненные изменения из текущего сеанса?', - onDeletePublishedEntry: 'Вы уверены, что хотите удалить эту опубликованную запись?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Это удалит все неопубликованные изменения в этой записи, а также ваши несохраненные изменения из текущего сеанса. Вы все еще хотите удалить?', - onDeleteUnpublishedChanges: - 'Все неопубликованные изменения в этой записи будут удалены. Вы все еще хотите удалить?', - loadingEntry: 'Загрузка записи…', - confirmLoadBackup: - 'Для этой записи была восстановлена локальная резервная копия, хотите ли вы ее использовать?', - }, - editorToolbar: { - publishing: 'Публикация…', - publish: 'Опубликовать', - published: 'Опубликовано', - unpublish: 'Отменить публикацию', - duplicate: 'Дублировать', - unpublishing: 'Отмена публикации…', - publishAndCreateNew: 'Опубликовать и создать новую', - publishAndDuplicate: 'Опубликовать и дублировать', - deleteUnpublishedChanges: 'Удалить неопубликованные изменения', - deleteUnpublishedEntry: 'Удалить неопубликованную запись', - deletePublishedEntry: 'Удалить опубликованную запись', - deleteEntry: 'Удалить запись', - saving: 'Сохранение…', - save: 'Сохранить', - deleting: 'Удаление…', - updating: 'Обновление…', - status: 'Cтатус: %{status}', - backCollection: 'Запись в коллекцию %{collectionLabel}', - unsavedChanges: 'Несохраненные изменения', - changesSaved: 'Изменения сохранены', - draft: 'Черновик', - inReview: 'На рассмотрении', - ready: 'Одобрен', - publishNow: 'Опубликовать сейчас', - deployPreviewPendingButtonLabel: 'Проверить предварительный просмотр', - deployPreviewButtonLabel: 'Предварительный просмотр', - deployButtonLabel: 'Просмотр', - }, - editorWidgets: { - markdown: { - bold: 'Полужиный', - italic: 'Курсив', - code: 'Код', - link: 'Ссылка', - linkPrompt: 'Укажите URL ссылки', - headings: 'Заголовки', - quote: 'Цитата', - bulletedList: 'Маркированный список', - numberedList: 'Нумерованный список', - addComponent: 'Добавить компонент', - richText: 'Форматированный текст', - markdown: 'Markdown', - }, - image: { - choose: 'Выберите изображение', - chooseUrl: 'Вставить из URL', - replaceUrl: 'Заменить на URL', - promptUrl: 'Введите URL изображения', - chooseDifferent: 'Выберите другое изображение', - remove: 'Удалить изображение', - }, - file: { - choose: 'Выберите файл', - chooseUrl: 'Вставить из URL', - replaceUrl: 'Заменить на URL', - promptUrl: 'Введите URL файла', - chooseDifferent: 'Выберите другой файл', - remove: 'Удалить файл', - }, - unknownControl: { - noControl: "Нет контрола для виджета '%{widget}'.", - }, - unknownPreview: { - noPreview: "Нет превью для виджета '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - datetime: { - now: 'Сейчас', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Черновик', - copy: 'Копировать', - copyUrl: 'Копировать URL', - copyPath: 'Копировать путь', - copyName: 'Копировать имя', - copied: 'Скопировано', - }, - mediaLibrary: { - onDelete: 'Вы уверены, что хотите удалить выбранный медиафайл?', - fileTooLarge: - 'Файл слишком большой.\nНастройки не позволяют сохранять файлы более %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Загрузка медифайлов…', - noResults: 'Нет результатов.', - noAssetsFound: 'Ресурсы не найдены.', - noImagesFound: 'Изображения не найдены.', - private: 'Приватные ', - images: 'Изображения', - mediaAssets: 'Медиаресурсы', - search: 'Идёт поиск…', - uploading: 'Загрузка…', - upload: 'Загрузить новый', - download: 'Скачать', - deleting: 'Удаление…', - deleteSelected: 'Удалить помеченные', - chooseSelected: 'Выбрать помеченные', - }, - }, - ui: { - default: { - goBackToSite: 'Вернуться на сайт', - }, - errorBoundary: { - title: 'Ошибка', - details: 'Произошла ошибка. Пожалуйста, ', - reportIt: 'сообщите о ней.', - detailsHeading: 'Подробности', - privacyWarning: - 'При открытии тикет автоматически предзаполняется сообщением об ошибке и отладочной информацией.\nПожалуйста, проверьте, что данные верны и не содержат конфиденциальной информации.', - recoveredEntry: { - heading: 'Восстановленный документ', - warning: 'Пожалуйста, скопируйте это сообщение куда-нибудь, прежде чем уйти со страницы!', - copyButtonLabel: 'Скопировать в буфер обмена', - }, - }, - settingsDropdown: { - logOut: 'Выйти', - }, - toast: { - onFailToLoadEntries: 'Не удалось загрузить запись: %{details}', - onFailToLoadDeployPreview: 'Не удалось загрузить превью: %{details}', - onFailToPersist: 'Не удалось сохранить запись: %{details}', - onFailToDelete: 'Не удалось удалить запись: %{details}', - onFailToUpdateStatus: 'Не удалось обновить статус: %{details}', - missingRequiredField: - 'К сожалению, вы пропустили обязательное поле. Пожалуйста, заполните перед сохранением.', - entrySaved: 'Запись сохранена', - entryPublished: 'Запись опубликована', - entryUnpublished: 'Публикация записи отменена', - onFailToPublishEntry: 'Не удалось опубликовать запись: %{details}', - onFailToUnpublishEntry: 'Не удалось отменить публикацию записи: %{details}', - entryUpdated: 'Статус записи обновлен', - onDeleteUnpublishedChanges: 'Неопубликованные изменения удалены', - onFailToAuth: '%{details}', - onLoggedOut: 'Вы вышли. Пожалуйста, сохраните все данные и войдите снова', - onBackendDown: 'Происходят перебои в работе бекенда. См. %{details}', - }, - }, - workflow: { - workflow: { - loading: 'Загрузка записей редакционного документооборота', - workflowHeading: 'Редакционный документооборот', - newPost: 'Новая запись', - description: - 'Число записей, ожидающих проверки — %{smart_count}, готовых к публикации — %{readyCount}. |||| Число записей, ожидающих проверки — %{smart_count}, готовых к публикации — %{readyCount}. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date}, %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '%{author}', - deleteChanges: 'Удалить изменения', - deleteNewEntry: 'Удалить новую запись', - publishChanges: 'Опубликовать изменения', - publishNewEntry: 'Опубликовать новую запись', - }, - workflowList: { - onDeleteEntry: 'Вы уверены, что хотите удалить эту запись?', - onPublishingNotReadyEntry: - 'Только элементы со статусом «Готов» могут быть опубликованы. Перетащите карточку в столбец «Одобренные», чтобы разрешить публикацию.', - onPublishEntry: 'Вы уверены, что хотите опубликовать эту запись?', - draftHeader: 'Черновики', - inReviewHeader: 'На рассмотрении', - readyHeader: 'Одобренные', - currentEntries: '%{smart_count} entry |||| %{smart_count} entries', - }, - }, -}; - -export default ru; diff --git a/packages/netlify-cms-locales/src/sv/index.js b/packages/netlify-cms-locales/src/sv/index.js deleted file mode 100644 index ef63f30e..00000000 --- a/packages/netlify-cms-locales/src/sv/index.js +++ /dev/null @@ -1,303 +0,0 @@ -const sv = { - auth: { - login: 'Logga in', - loggingIn: 'Loggar in...', - loginWithNetlifyIdentity: 'Logga in med Netlify Identity', - loginWithAzure: 'Logga in med Azure', - loginWithBitbucket: 'Logga in med Bitbucket', - loginWithGitHub: 'Logga in med GitHub', - loginWithGitLab: 'Logga in med GitLab', - errors: { - email: 'Fyll i din epostadress.', - password: 'Vänligen skriv ditt lösenord.', - identitySettings: - 'Kan inte hämta inställningar för Identity. Vid användade av git-gateway backend, kontrollera att Identity service och Git Gateway är aktiverade.', - }, - }, - app: { - header: { - content: 'Innehåll', - workflow: 'Arbetsflöde', - media: 'Media', - quickAdd: 'Snabbt tillägg', - }, - app: { - errorHeader: 'Ett fel uppstod vid hämtning av CMS-konfigurationen', - configErrors: 'Konfigurationsfel', - checkConfigYml: 'Kontrollera din config.yml-fil.', - loadingConfig: 'Hämtar konfiguration...', - waitingBackend: 'Väntar på backend...', - }, - notFoundPage: { - header: 'Sidan finns inte', - }, - }, - collection: { - sidebar: { - collections: 'Samlingar', - allCollections: 'Alla Samlingar', - searchAll: 'Sök', - searchIn: 'Sök i', - }, - collectionTop: { - sortBy: 'Sortera efter', - viewAs: 'Visa som', - newButton: 'Ny %{collectionLabel}', - ascending: 'Stigande', - descending: 'Fallande', - searchResults: 'Sökresultat för "%{searchTerm}"', - searchResultsInCollection: 'Sökresultat för "%{searchTerm}" i %{collection}', - filterBy: 'Filtrera efter', - groupBy: 'Gruppera efter', - }, - entries: { - loadingEntries: 'Hämtar inlägg...', - cachingEntries: 'Sparar inlägg i cache...', - longerLoading: 'Det här kan ta några minuter', - noEntries: 'Inga inlägg', - }, - groups: { - other: 'Annat', - negateLabel: 'Inte %{label}', - }, - defaultFields: { - author: { - label: 'Författare', - }, - updatedOn: { - label: 'Uppdaterad vid', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'frivillig', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} är obligatoriskt.', - regexPattern: '%{fieldLabel} matchar inte mönstret: %{pattern}.', - processing: '%{fieldLabel} bearbetas.', - range: '%{fieldLabel} måste vara mellan %{minValue} och %{maxValue}.', - min: '%{fieldLabel} måste vara åtminstone %{minValue}.', - max: '%{fieldLabel} måste vara %{maxValue} eller mindre.', - rangeCount: '%{fieldLabel} måste ha mellan %{minCount} och %{maxCount} element.', - rangeCountExact: '%{fieldLabel} måste ha exakt %{count} element.', - rangeMin: '%{fieldLabel} måste ha åtminstone %{minCount} element.', - rangeMax: '%{fieldLabel} måste ha %{maxCount} eller färre element.', - invalidPath: `'%{path}' är inte en giltig sökväg`, - pathExists: `Sökvägen '%{path}' existerar redan`, - }, - i18n: { - writingInLocale: 'Skriver i %{locale}', - }, - }, - editor: { - onLeavePage: 'Är du säker på att du vill lämna sidan?', - onUpdatingWithUnsavedChanges: - 'Du har osparade ändringar, vänligen spara dem innan du uppdaterar status.', - onPublishingNotReady: 'Vänligen uppdatera status till "Redo" innan du publicerar.', - onPublishingWithUnsavedChanges: - 'Du har osparade ändringar, vänligen spara innan du publicerar.', - onPublishing: 'Är du säker på att du vill publicera det här inlägget?', - onUnpublishing: 'Är du säker på att du vill avpublicera det här inlägget?', - onDeleteWithUnsavedChanges: - 'Är du säker på att du vill radera det här publicerade inlägget, inklusive dina osparade ändringar från nuvarande session?', - onDeletePublishedEntry: 'Är du säker på att du vill radera det här publicerade inlägget?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Du är på väg att radera alla opublicerade ändringar för det här inlägget, inklusive dina osparade ändringar från nuvarande session. Vill du fortfarande radera?', - onDeleteUnpublishedChanges: - 'Alla opublicerade ändringar kommer raderas. Vill du fortfarande radera?', - loadingEntry: 'Hämtar inlägg...', - confirmLoadBackup: 'En lokal kopia hittades för det här inlägget, vill du använda den?', - }, - editorInterface: { - toggleI18n: 'Slå på/av i18n', - togglePreview: 'Visa/Dölj förhandsvisning', - toggleScrollSync: 'Synka scrollning', - }, - editorToolbar: { - publishing: 'Publicerar...', - publish: 'Publicera', - published: 'Publicerad', - unpublish: 'Avpublicera', - duplicate: 'Duplicera', - unpublishing: 'Avpublicerar...', - publishAndCreateNew: 'Publicera och skapa ny', - publishAndDuplicate: 'Publicera och duplicera', - deleteUnpublishedChanges: 'Radera opublicerade ändringar', - deleteUnpublishedEntry: 'Radera opublicerat inlägg', - deletePublishedEntry: 'Radera publicerat inlägg', - deleteEntry: 'Radera inlägg', - saving: 'Sparar...', - save: 'Spara', - deleting: 'Raderar...', - updating: 'Updaterar...', - status: 'Status: %{status}', - backCollection: ' Redigerar i samlingen %{collectionLabel}', - unsavedChanges: 'Osparade ändringar', - changesSaved: 'Ändringar sparade', - draft: 'Utkast', - inReview: 'Under granskning', - ready: 'Redo', - publishNow: 'Publicera nu', - deployPreviewPendingButtonLabel: 'Kontrollera förhandsvisning', - deployPreviewButtonLabel: 'Visa förhandsvisning', - deployButtonLabel: 'Visa Live', - }, - editorWidgets: { - markdown: { - bold: 'Fetstil', - italic: 'Kursiv', - code: 'Kod', - link: 'Länk', - linkPrompt: 'Ange en URL för länken', - headings: 'Rubriker', - quote: 'Citat', - bulletedList: 'Punktlista', - numberedList: 'Numrerad lista', - addComponent: 'Lägg till komponent', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'Välj en bild', - chooseUrl: 'Infoga från URL', - replaceUrl: 'Ersätt med URL', - promptUrl: 'Ange en URL för bilden', - chooseDifferent: 'Välj en annan bild', - remove: 'Ta bort bild', - }, - file: { - choose: 'Välj en fil', - chooseUrl: 'Infoga från URL', - replaceUrl: 'Ersätt med URL', - promptUrl: 'Ange en URL för filen', - chooseDifferent: 'Välj en annan fil', - remove: 'Ta bort fil', - }, - unknownControl: { - noControl: "Inget reglage för widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Ingen förhandsvisning för widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Rubrik 1', - headingTwo: 'Rubrik 2', - headingThree: 'Rubrik 3', - headingFour: 'Rubrik 4', - headingFive: 'Rubrik 5', - headingSix: 'Rubrik 6', - }, - datetime: { - now: 'Nu', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Utkast', - copy: 'Kopiera', - copyUrl: 'Kopiera URL', - copyPath: 'Kopiera Sökväg', - copyName: 'Kopiera Namn', - copied: 'Kopierad', - }, - mediaLibrary: { - onDelete: 'Är du säker på att du vill radera valt mediaobjekt?', - fileTooLarge: - 'Maximal filstorlek överskriden.\nKonfigurerad att inte tillåta filer större än %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Hämtar...', - noResults: 'Inga resultat.', - noAssetsFound: 'Hittade inga mediaobjekt.', - noImagesFound: 'Hittade inga bilder.', - private: 'Privat ', - images: 'Bilder', - mediaAssets: 'Mediaobjekt', - search: 'Sök...', - uploading: 'Laddar upp...', - upload: 'Ladda upp', - download: 'Ladda ner', - deleting: 'Raderar...', - deleteSelected: 'Radera markerad', - chooseSelected: 'Välj markerad', - }, - }, - ui: { - default: { - goBackToSite: 'Tillbaka till sida', - }, - errorBoundary: { - title: 'Fel', - details: 'Ett fel har uppstått - vänligen ', - reportIt: 'öppna ett ärende på GitHub.', - detailsHeading: 'Detaljer', - privacyWarning: - 'När ett ärende öppnas bifogas felsökningsdata automatiskt.\nVänligen kontrollera att informationen är korrekt och ta bort känslig data om det skulle finnas sådan.', - recoveredEntry: { - heading: 'Återskapade dokument', - warning: 'Vänligen kopiera materialet någon annanstans innan du navigerar från sidan!', - copyButtonLabel: 'Kopiera till urklipp', - }, - }, - settingsDropdown: { - logOut: 'Logga ut', - }, - toast: { - onFailToLoadEntries: 'Kunde inte hämta inlägg: %{details}', - onFailToLoadDeployPreview: 'Kunde inte ladda förhandsvisning: %{details}', - onFailToPersist: 'Kunde inte spara inlägg: %{details}', - onFailToDelete: 'Kunde inte radera inlägg: %{details}', - onFailToUpdateStatus: 'Kunde inte uppdatera status: %{details}', - missingRequiredField: - 'Oops, du har missat ett obligatoriskt fält. Vänligen fyll i det innan du sparar.', - entrySaved: 'Inlägg sparat', - entryPublished: 'Inlägg publicerat', - entryUnpublished: 'Inlägg avpublicerat', - onFailToPublishEntry: 'Kunde inte publicera: %{details}', - onFailToUnpublishEntry: 'Kunde inte avpublicera inlägg: %{details}', - entryUpdated: 'Inläggsstatus uppdaterad', - onDeleteUnpublishedChanges: 'Opublicerade ändringar raderade', - onFailToAuth: '%{details}', - onLoggedOut: - 'Du har blivit utloggad, vänligen spara en kopia av eventuella ändringar och logga in på nytt', - onBackendDown: 'Tjänsten är drabbad av en störning. Se %{details} för mer information', - }, - }, - workflow: { - workflow: { - loading: 'Hämtar inlägg för redaktionellt arbetsflöde', - workflowHeading: 'Redaktionellt arbetsflöde', - newPost: 'Nytt inlägg', - description: - '%{smart_count} inlägg väntar på granskning, %{readyCount} redo att publiceras. |||| %{smart_count} inlägg väntar på granskning, %{readyCount} redo att publiceras. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} av %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'av %{author}', - deleteChanges: 'Radera ändringar', - deleteNewEntry: 'Radera nytt inlägg', - publishChanges: 'Publicera ändringar', - publishNewEntry: 'Publicera nytt inlägg', - }, - workflowList: { - onDeleteEntry: 'Är du säker på att du vill radera det här inlägget?', - onPublishingNotReadyEntry: - 'Bara inlägg med statusen "Redo" kan publiceras. Vänligen dra kortet till "Redo"-kolumnen för att möjliggöra publicering', - onPublishEntry: 'Är du säker på att du vill publicera det här inlägget?', - draftHeader: 'Utkast', - inReviewHeader: 'Under granskning', - readyHeader: 'Redo', - currentEntries: '%{smart_count} inlägg |||| %{smart_count} inlägg', - }, - }, -}; - -export default sv; diff --git a/packages/netlify-cms-locales/src/th/index.js b/packages/netlify-cms-locales/src/th/index.js deleted file mode 100644 index d71b828d..00000000 --- a/packages/netlify-cms-locales/src/th/index.js +++ /dev/null @@ -1,266 +0,0 @@ -const th = { - auth: { - login: 'เข้าสู่ระบบ', - loggingIn: 'กำลังเข้าสู่ระบบ...', - loginWithNetlifyIdentity: 'เข้าสู่ระบบด้วย Netlify Identity', - loginWithBitbucket: 'เข้าสู่ระบบด้วย Bitbucket', - loginWithGitHub: 'เข้าสู่ระบบด้วย GitHub', - loginWithGitLab: 'เข้าสู่ระบบด้วย GitLab', - errors: { - email: 'ตรวจสอบให้แน่ใจว่าได้ใส่อีเมลล์แล้ว', - password: 'โปรดใส่รหัสผ่านของคุณ', - identitySettings: - 'ไม่สามารถเข้าถึงการตั้งค่าส่วนตัว เมื่อใช้ git-gateway backend ตรวจสอบให้แน่ใจว่าได้เปิดใช้งานระบบยืนยันตัวตนและ Git Gateway.', - }, - }, - app: { - header: { - content: 'เนื้อหา', - workflow: 'ขั้นตอนการทำงาน', - media: 'มีเดีย', - quickAdd: 'เพิ่มเนื้อหา อย่างเร็ว', - }, - app: { - errorHeader: 'เกิดข้อผิดพลาดในการโหลดการตั้งค่า CMS', - configErrors: 'คอนฟิกมีข้อผิดพลาด', - checkConfigYml: 'กรุณาตรวจสอบไฟล์ config.yml ของคุณ', - loadingConfig: 'กำลังโหลดการตั้งค่า...', - waitingBackend: 'กำลังรอการตอบกลับจาก backend...', - }, - notFoundPage: { - header: 'ไม่พบหน้านี้', - }, - }, - collection: { - sidebar: { - collections: 'กลุ่ม', - allCollections: 'ทุกกลุ่ม', - searchAll: 'ค้นหาทั้งหมด', - searchIn: 'ค้าหาใน', - }, - collectionTop: { - sortBy: 'จัดเรียงตาม', - viewAs: 'ดูในฐานะ', - newButton: 'สร้าง %{collectionLabel}', - ascending: 'น้อยไปมาก', - descending: 'มากไปน้อย', - searchResults: 'ค้นหาผลลัพธ์สำหรับ "%{searchTerm}"', - searchResultsInCollection: 'ค้นหาผลลัพธ์สำหรับ "%{searchTerm}" ใน %{collection}', - filterBy: 'กรองตาม', - }, - entries: { - loadingEntries: 'กำลังโหลดเนิ้อหา...', - cachingEntries: 'กำลังแคชข้อมูลเนื้อหา...', - longerLoading: 'อาจจะโหลดนานหลายนาที', - noEntries: 'ไม่มีเนื้อหา', - }, - defaultFields: { - author: { - label: 'ผู้เขียน', - }, - updatedOn: { - label: 'อัพเดตเมื่อ', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'ทางเลือก', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} ต้องระบุ', - regexPattern: '%{fieldLabel} ไม่ตรงกับรูปแบบ: %{pattern}', - processing: '%{fieldLabel} กำลังประมวลผล', - range: '%{fieldLabel} ต้องอยู่ระหว่าง %{minValue} และ %{maxValue}', - min: '%{fieldLabel} จะต้องมีค่าไม่ต่ำกว่า %{minValue}', - max: '%{fieldLabel} จะต้องมีค่าไม่มากกว่า %{maxValue}', - rangeCount: '%{fieldLabel} จะต้องอยู่ระหว่าง %{minCount} และ %{maxCount} รายการ', - rangeCountExact: '%{fieldLabel} จะต้องมี %{count} รายการ', - rangeMin: '%{fieldLabel} จะต้องมีไม่ต่ำกว่า %{minCount} รายการ', - rangeMax: '%{fieldLabel} จะต้องมีไม่มากกว่า %{maxCount} รายการ', - invalidPath: `'%{path}' พาทไม่ถูกต้อง`, - pathExists: `พาท '%{path}' มีอยู่แล้ว`, - }, - i18n: { - writingInLocale: 'เขียนด้วยภาษา %{locale}', - }, - }, - editor: { - onLeavePage: 'คุณแน่ใจหรือว่าจะออกจากหน้านี้?', - onUpdatingWithUnsavedChanges: - 'คุณมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก โปรดบันทึกก่อนอัปเดตสถานะ', - onPublishingNotReady: 'โปรดอัปเดตสถานะเป็น "พร้อม" ก่อนจะเผยแพร่', - onPublishingWithUnsavedChanges: - 'คุณมีการเปลี่ยนแปลงที่ยังไม่ได้บันทึก โปรดบันทึกก่อนจะเผยแพร่', - onPublishing: 'คุณแน่ใจหรือว่าจะเผยแพร่เนื้อหานี้?', - onUnpublishing: 'คุณแน่ใจหรือว่าจะไม่ต้องการเผยแพร่เนื้อหานี้?', - onDeleteWithUnsavedChanges: - 'คุณแน่ใจหรือว่าจะต้องการลบการเผยแพร่เนื้อหานี้ รวมถึงการเปลี่ยนแปลงที่ยังไม่ได้บันทึก?', - onDeletePublishedEntry: 'คุณแน่ใจหรือว่าจะต้องการลบการเผยแพร่เนื้อหานี้?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'คุณแน่ใจหรือว่าจะต้องการลบเนื้อหาที่ยังไม่ได้เผยแพร่ทั้งหมดนี้ รวมถึงการเปลี่ยนแปลงที่ยังไม่ได้บันทึก?', - onDeleteUnpublishedChanges: 'คุณแน่ใจหรือว่าจะต้องการลบเนื้อหาที่ยังไม่ได้เผยแพร่ทั้งหมดนี้?', - loadingEntry: 'กำลังโหลดเนื้อหา...', - confirmLoadBackup: 'ข้อมูลสำรองได้ถูกกู้คืนสำหรับเนื้อหานี้ คุณต้องการใช้มันไหม?', - }, - editorToolbar: { - publishing: 'กำลังเผยแพร่...', - publish: 'เผยแพร่', - published: 'เผยแพร่แล้ว', - unpublish: 'ไม่ได้เผยแพร่', - duplicate: 'ทำซ้ำ', - unpublishing: 'ไม่ทำการเผยแพร่...', - publishAndCreateNew: 'เผยแพร่ และ สร้างใหม่', - publishAndDuplicate: 'เผยแพร่ และ ทำซ้ำ', - deleteUnpublishedChanges: 'ลบการเปลี่ยแปลงเนื้อหาที่ยังไม่ได้เผยแพร่', - deleteUnpublishedEntry: 'ลบเนื้อหาที่ยังไม่ได้เผยแพร่', - deletePublishedEntry: 'ลบเนื้อหาที่เผยแพร่', - deleteEntry: 'ลบเนื้อหา', - saving: 'กำลังบันทึก...', - save: 'บันทึก', - deleting: 'กำลังลบ...', - updating: 'กำลังอัปเดต...', - status: 'สถานะ: %{status}', - backCollection: ' เขียนในกลุ่ม %{collectionLabel}', - unsavedChanges: 'การเปลี่ยนแปลงยังไม่ได้บันทึก', - changesSaved: 'การเปลี่ยนเปลงถูกบันทึกแล้ว', - draft: 'ร่าง', - inReview: 'อยู่ระหว่างการตรวจสอบ', - ready: 'พร้อม', - publishNow: 'เผยแพร่ตอนนี้', - deployPreviewPendingButtonLabel: 'ตรวจสอบตัวอย่าง', - deployPreviewButtonLabel: 'ดูตัวอย่าง', - deployButtonLabel: 'ดูตัวอย่างจากหน้าจริง', - }, - editorWidgets: { - markdown: { - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: 'เลือกรูปภาพ', - chooseDifferent: 'เลือกรูปภาพอื่น', - remove: 'เอารูปภาพออก', - }, - file: { - choose: 'เลือกไฟล์', - chooseDifferent: 'เลือกไฟล์อื่น', - remove: 'เอาไฟล์ออก', - }, - unknownControl: { - noControl: "ไม่มีการควบคุม widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "ไม่มีตัวอย่างสำหรับ widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - datetime: { - now: 'เวลาตอนนี้', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'ร่าง', - }, - mediaLibrary: { - onDelete: 'คุณแน่ใจหรือว่าจะลบมีเดียที่ถูกเลือก?', - fileTooLarge: 'ไฟล์ใหญ่เกินไป\n ค่าที่ตั้งไว้ไม่ยอมรับไฟล์ที่ใหญ่กว่า %{size} kB.', - }, - mediaLibraryModal: { - loading: 'กำลังโหลด...', - noResults: 'ไม่มีผลลัพธ์', - noAssetsFound: 'ไม่พบข้อมูล', - noImagesFound: 'ไม่พบรูปภาพ', - private: 'ส่วนตัว ', - images: 'รูปภาพ', - mediaAssets: 'ข้อมูลมีเดีย', - search: 'ค้นหา...', - uploading: 'กำลังอัปโหลด...', - upload: 'อัปโหลด', - download: 'ดาวน์โหลด', - deleting: 'กำลังลบ...', - deleteSelected: 'ลบข้อมูลที่เลือก', - chooseSelected: 'เลือกข้อมูลที่ถูกเลือก', - }, - }, - ui: { - default: { - goBackToSite: 'กลับไปยังเว็บไซต์', - }, - errorBoundary: { - title: 'มีข้อผิดพลาด', - details: 'มีข้อผิดพลาดเกิดขึ้น', - reportIt: 'แจ้งข้อผิดพลาดบน GitHub', - detailsHeading: 'รายละเอียด', - privacyWarning: - 'การแจ้งปัญหาจะเติมข้อมูลล่วงหน้าด้วยข้อความแสดงข้อผิดพลาดและข้อมูลการดีบัก\nโปรดตรวจสอบข้อมูลว่าถูกต้องและลบข้อมูลที่สำคัญหากมีอยู่', - recoveredEntry: { - heading: 'เอกสารถูกกู้คืน', - warning: 'โปรด คัดลอก/วาง ที่ใดที่หนึ่งก่อนจะทำอย่างอื่น!', - copyButtonLabel: 'คัดลอกไปที่คลิปบอร์ด', - }, - }, - settingsDropdown: { - logOut: 'ออกจากระบบ', - }, - toast: { - onFailToLoadEntries: 'ล้มเหลวในการโหลดเนื้อหา: %{details}', - onFailToLoadDeployPreview: 'ล้มเหลวในการโหลดตัวอย่าง: %{details}', - onFailToPersist: 'ล้มเหลวในการยืนยันเนื้อหา: %{details}', - onFailToDelete: 'ล้มเหลวในการลบเนื้อหา: %{details}', - onFailToUpdateStatus: 'ล้มเหลวในการอัปเดตสถานะ: %{details}', - missingRequiredField: 'คุณไม่ได้ใส่ข้อมูลในช่องที่ต้องการ กรุณาใส่ข้อมูลก่อนบันทึก', - entrySaved: 'เนื้อหาถูกบันทึก', - entryPublished: 'เนื้อหาถูกเผยแพร่', - entryUnpublished: 'เนื้อหาไม่ได้ถูกเผยแพร่', - onFailToPublishEntry: 'ล้มเหลวในการเผยแพร่เนื้อหา: %{details}', - onFailToUnpublishEntry: 'ล้มเหลวในการไม่เผยแพร่เนื้อหา: %{details}', - entryUpdated: 'สถานะเนื้อหาถูกอัปเดต', - onDeleteUnpublishedChanges: 'การเปลี่ยนแปลงเนื้อหาไม่ถูกเผยแพร่ได้ถูกลบ', - onFailToAuth: '%{details}', - onLoggedOut: 'คุณได้ออกจากระบบ โปรดสำรองข้อมูลแล้วเข้าสู่ระบบอีกครั้ง', - onBackendDown: 'บริการแบ็กเอนด์เกิดการขัดข้อง ดู %{details} สำหรับข้อมูลเพิ่มเติม', - }, - }, - workflow: { - workflow: { - loading: 'กำลังโหลดเนื้อหาขั้นตอนการทำงานของบรรณาธิการ', - workflowHeading: 'ขั้นตอนการทำงานของบรรณาธิการ', - newPost: 'สร้างโพสต์ใหม่', - description: '%{smart_count} เนื้อหารอการตรวจสอบ, %{readyCount} พร้อมที่จะเผยแพร่ ่', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} โดย %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'โดย %{author}', - deleteChanges: 'ลบการเปลี่ยนแปลง', - deleteNewEntry: 'ลบเนื้อหาใหม่', - publishChanges: 'เผยแพร่การเปลี่ยนแปลง', - publishNewEntry: 'เผยแพร่เนื้อหาใหม่', - }, - workflowList: { - onDeleteEntry: 'คุณแน่ใจหรือว่าจะต้องการลบเนื้อหานี้?', - onPublishingNotReadyEntry: - 'เฉพาะรายการที่มีสถานะ "พร้อม" สามารถทำการเผยแพร่ โปรดลากเนื้อหาไปยังช่อง "พร้อม" เพื่อจะทำการเผยแพร่.', - onPublishEntry: 'คุณแน่ใจหรือว่าจะต้องการเผยแพร่เนื้อหานี้?', - draftHeader: 'ร่าง', - inReviewHeader: 'อยู่ในการตรวจสอบ', - readyHeader: 'พร้อม', - currentEntries: '%{smart_count} เนื้อหา', - }, - }, -}; - -export default th; diff --git a/packages/netlify-cms-locales/src/tr/index.js b/packages/netlify-cms-locales/src/tr/index.js deleted file mode 100644 index 506e3562..00000000 --- a/packages/netlify-cms-locales/src/tr/index.js +++ /dev/null @@ -1,314 +0,0 @@ -const tr = { - auth: { - login: 'Giriş', - loggingIn: 'Giriş yapılıyor..', - loginWithNetlifyIdentity: 'Netlify Identity ile Giriş', - loginWithAzure: 'Azure ile Giriş', - loginWithBitbucket: 'Bitbucket ile Giriş', - loginWithGitHub: 'GitHub ile Giriş', - loginWithGitLab: 'GitLab ile Giriş', - errors: { - email: 'E-postanızı girdiğinizden emin olun.', - password: 'Lütfen şifrenizi girin.', - identitySettings: - "Identity ayarlarına erişilemiyor. Git-gateway sunucusunu kullanmak için Identity servisi ve Git Gateway'in etkin olduğundan emin olun.", - }, - }, - app: { - header: { - content: 'İçerikler', - workflow: 'İş Akışı', - media: 'Medya', - quickAdd: 'Hızlı ekle', - }, - app: { - errorHeader: 'CMS yapılandırması yüklenirken hata oluştu', - configErrors: 'Yapılandırma Hataları', - checkConfigYml: 'config.yml dosyanızı kontrol edin.', - loadingConfig: 'Yapılandırma yükleniyor...', - waitingBackend: 'Arka uç bekleniyor...', - }, - notFoundPage: { - header: 'Bulunamadı', - }, - }, - collection: { - sidebar: { - collections: 'Koleksiyonlar', - allCollections: 'Bütün Koleksiyonlar', - searchAll: 'Tümünü ara', - searchIn: 'İçinde ara', - }, - collectionTop: { - sortBy: 'Sırala ...', - viewAs: 'Görüntüle', - newButton: 'Yeni %{collectionLabel}', - ascending: 'Artan', - descending: 'Azalan', - searchResults: '"%{searchTerm}" için Arama Sonuçları', - searchResultsInCollection: - '%{collection} koleksiyonunda, "%{searchTerm}" için Arama Sonuçları', - filterBy: 'Filtrele', - groupBy: 'Grupla', - }, - entries: { - loadingEntries: 'Girdiler yükleniyor...', - cachingEntries: 'Girdi önbelleği...', - longerLoading: 'Bu birkaç dakika sürebilir', - noEntries: 'Hiç Girdi Yok', - }, - groups: { - other: 'Diğer', - negateLabel: '%{label} hariç', - }, - defaultFields: { - author: { - label: 'Yazar', - }, - updatedOn: { - label: 'Güncellenme Tarihi', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'isteğe bağlı', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} gerekli.', - regexPattern: '%{fieldLabel} eşleşmeyen kalıp: %{pattern}.', - processing: '%{fieldLabel} işleniyor.', - range: '%{fieldLabel} %{minValue} ve %{maxValue} arasında olmalı.', - min: '%{fieldLabel} en az %{minValue} olmalı.', - max: '%{fieldLabel}, %{maxValue} veya daha az olmalı.', - rangeCount: '%{fieldLabel}, %{minCount} ve %{maxCount} öğeleri arasında olmalı.', - rangeCountExact: '%{fieldLabel}, %{count} öğe olmalıdır.', - rangeMin: '%{fieldLabel}, en az %{minCount} öğe olmalıdır.', - rangeMax: '%{fieldLabel}, %{maxCount} veya daha az öğe olmalıdır.', - invalidPath: `'%{path}' geçerli bir yol değil`, - pathExists: `'%{path}' yolu zaten var`, - }, - i18n: { - writingInLocale: '%{locale} için yazılıyor', - copyFromLocale: 'Başka bir dilden doldurun', - copyFromLocaleConfirm: - 'Verileri %{locale} dilinden mi doldurmak istiyorsun?\nVarolan bütün verilerin üzerine yazılacak.', - }, - }, - editor: { - onLeavePage: 'Bu sayfadan ayrılmak istediğinize emin misiniz?', - onUpdatingWithUnsavedChanges: - 'Kaydedilmemiş değişiklikleriniz var, lütfen içeriği güncellemeden önce kaydedin.', - onPublishingNotReady: 'Lütfen yayınlamadan önce içeriği "Hazır" olarak güncelleyin.', - onPublishingWithUnsavedChanges: - 'Kaydedilmemiş değişiklikleriniz var, lütfen yayınlamadan önce kaydedin.', - onPublishing: 'Bu girdiyi yayınlamak istediğinize emin misiniz?', - onUnpublishing: 'Bu girdiyi yayından kaldırmak istediğinizden emin misiniz?', - onDeleteWithUnsavedChanges: - 'Bu oturumda kaydedilmiş değişikliklerin yanı sıra geçerli oturumdaki kaydedilmemiş değişikliklerinizi silmek istediğinize emin misiniz?', - onDeletePublishedEntry: 'Bu yayınlanmış girdiyi silmek istediğinize emin misiniz?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Bu girdide yayınlanmamış tüm değişiklikleri ve geçerli oturumdaki kaydedilmemiş değişikliklerinizi siler. Hala silmek istiyor musun?', - onDeleteUnpublishedChanges: - 'Bu girdide yayınlanmamış tüm değişiklikler silinecek. Hala silmek istiyor musun?', - loadingEntry: 'Girdiler yükleniyor...', - confirmLoadBackup: 'Bu girdi için yerel bir yedekleme kurtarıldı, kullanmak ister misiniz?', - }, - editorInterface: { - toggleI18n: 'i18n değiştir', - togglePreview: 'Önizlemeyi değiştir', - toggleScrollSync: 'Kaydırmayı senkronize et', - }, - editorToolbar: { - publishing: 'Yayınlanıyor...', - publish: 'Yayınla', - published: 'Yayınlanan', - unpublish: 'Yayından Kaldır', - duplicate: 'Kopyala', - unpublishing: 'Yayından kaldırılıyor...', - publishAndCreateNew: 'Yayınla ve yeni oluştur', - publishAndDuplicate: 'Yayınla ve kopya oluştur', - deleteUnpublishedChanges: 'Yayımlanmamış değişiklikleri sil', - deleteUnpublishedEntry: 'Yayımlanmamış girdiyi sil', - deletePublishedEntry: 'Yayınlanan girdiyi sil', - deleteEntry: 'Girdiyi sil', - saving: 'Kaydediliyor...', - save: 'Kaydet', - statusInfoTooltipDraft: - 'Giriş durumu taslak olarak ayarlandı. Girişi bitirmek ve incelemeye göndermek için giriş durumunu ‘İncelemede’ olarak ayarlayın', - statusInfoTooltipInReview: - 'Giriş gözden geçiriliyor, başka bir işlem yapılmasına gerek yok. Ancak, incelenirken yine de ek değişiklikler yapabilirsiniz.', - deleting: 'Siliniyor...', - updating: 'Güncelleniyor...', - status: 'Durumu: %{status}', - backCollection: ' %{collectionLabel} koleksiyonunda yazılı', - unsavedChanges: 'Kaydedilmemiş Değişiklikler', - changesSaved: 'Değişiklikler kaydedildi', - draft: 'Taslak', - inReview: 'İncelemede', - ready: 'Hazır', - publishNow: 'Şimdi yayımla', - deployPreviewPendingButtonLabel: 'Önizlemeyi Denetle', - deployPreviewButtonLabel: 'Önizlemeyi Görüntüle', - deployButtonLabel: 'Canlı Görüntüle', - }, - editorWidgets: { - markdown: { - bold: 'Kalın', - italic: 'İtalik', - code: 'Kod', - link: 'Bağlantı', - linkPrompt: "Bağlantının URL'sini girin", - headings: 'Başlıklar', - quote: 'Alıntı', - bulletedList: 'Maddeli Liste', - numberedList: 'Numaralı Liste', - addComponent: 'Bileşen Ekle', - richText: 'Zengin Metin', - markdown: 'Markdown', - }, - image: { - choose: 'Bir resim seçin', - chooseUrl: "URL'den ekle", - replaceUrl: 'URL ile değiştir', - promptUrl: "Resmin URL'sini girin", - chooseDifferent: 'Farklı bir resim seçin', - remove: 'Resmi kaldır', - }, - file: { - choose: 'Bir dosya seçin', - chooseUrl: "URL'den ekle", - replaceUrl: 'URL ile değiştir', - promptUrl: "Dosyanın URL'sini girin", - chooseDifferent: 'Farklı bir dosya seçin', - remove: 'Dosyayı kaldır', - }, - unknownControl: { - noControl: "'%{widget}' bileşeni için kontrol yok.", - }, - unknownPreview: { - noPreview: "'%{widget}' bileşeni için önizleme yok.", - }, - headingOptions: { - headingOne: 'Başlık 1', - headingTwo: 'Başlık 2', - headingThree: 'Başlık 3', - headingFour: 'Başlık 4', - headingFive: 'Başlık 5', - headingSix: 'Başlık 6', - }, - datetime: { - now: 'Şimdi', - }, - list: { - add: '%{item} Ekle', - addType: '%{item} Ekle', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Taslak', - copy: 'Kopyala', - copyUrl: 'URLyi Kopyala', - copyPath: 'Dosya Yolunu Kopyala', - copyName: 'Adını Kopyala', - copied: 'Kopyalandı', - }, - mediaLibrary: { - onDelete: 'Seçilen medyayı silmek istediğinize emin misiniz?', - fileTooLarge: - 'Dosya çok büyük.\n%{size} kilobaytdan daha büyük dosyaların yüklenmemesi için ayarlanmış.', - }, - mediaLibraryModal: { - loading: 'Yükleniyor...', - noResults: 'Sonuç yok.', - noAssetsFound: 'Hiçbir dosya bulunamadı.', - noImagesFound: 'Resim bulunamadı.', - private: 'Özel ', - images: 'Görseller', - mediaAssets: 'Medya dosyaları', - search: 'Ara...', - uploading: 'Yükleniyor...', - upload: 'Yükle', - download: 'İndir', - deleting: 'Siliniyor...', - deleteSelected: 'Seçileni sil', - chooseSelected: 'Seçileni kullan', - }, - }, - ui: { - default: { - goBackToSite: 'Siteye geri git', - }, - errorBoundary: { - title: 'Hata', - details: 'Bir hata oluştu - lütfen ', - reportIt: 'GitHub üzerinde hata raporu aç.', - detailsHeading: 'Ayrıntılar', - privacyWarning: - 'Bir hata raporu oluşturmak için gereken form otomatik olarak hata mesajı ve hata ayıklama verileriyle doldurulur.\nLütfen bilgilerin doğru olduğunu doğrulayın ve varsa hassas verileri kaldırın.', - recoveredEntry: { - heading: 'Kurtarılan belge', - warning: 'Lütfen gitmeden önce bunu bir yere kopyalayın / yapıştırın!', - copyButtonLabel: 'Panoya kopyala', - }, - }, - settingsDropdown: { - logOut: 'Çıkış Yap', - }, - toast: { - onFailToLoadEntries: 'Girdi yüklenemedi: %{details}', - onFailToLoadDeployPreview: 'Önizleme yüklenemedi: %{details}', - onFailToPersist: 'Girdi devam ettirilemedi: %{details}', - onFailToDelete: 'Girdi silinemedi: %{details}', - onFailToUpdateStatus: 'Durum güncellenemedi: %{details}', - missingRequiredField: 'Gerekli bir alan eksik. Lütfen kaydetmeden önce tamamlayın.', - entrySaved: 'Girdi kaydedildi', - entryPublished: 'Girdi yayınlandı', - entryUnpublished: 'Girdi yayınlanmamış', - onFailToPublishEntry: 'Yayınlanamadı: %{details}', - onFailToUnpublishEntry: 'Girdi yayından kaldırılamadı: %{details}', - entryUpdated: 'Girdi durumu güncellendi', - onDeleteUnpublishedChanges: 'Yayımlanmamış değişiklikler silindi', - onFailToAuth: '%{details}', - onLoggedOut: 'Çıkış yaptınız, lütfen tüm verileri yedekleyin ve tekrar giriş yapın', - onBackendDown: - 'Arka uç hizmetinde bir kesinti yaşanıyor. Daha fazla bilgi için %{details} gör', - }, - }, - workflow: { - workflow: { - loading: 'İş Akışı Girdileri Yükleniyor', - workflowHeading: 'Editoryal İş Akışı', - newPost: 'Yeni Mesaj', - description: - '%{smart_count} girdi incelemeyi bekliyor, %{readyCount} yayına hazır. |||| %{smart_count} girdi incelemeyi bekliyor, %{readyCount} yayınlanmaya hazır. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} tarafından %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '%{author} tarafından', - deleteChanges: 'Değişiklikleri sil', - deleteNewEntry: 'Yeni girdiyi sil', - publishChanges: 'Değişiklikleri yayınla', - publishNewEntry: 'Yeni girdi yayınla', - }, - workflowList: { - onDeleteEntry: 'Bu girdiyi silmek istediğinize emin misiniz?', - onPublishingNotReadyEntry: - 'Yalnızca "Hazır" durumu olan öğeler yayınlanabilir. Lütfen yayınlamayı etkinleştirmek için kartı "Hazır" sütununa sürükleyin.', - onPublishEntry: 'Bu girdiyi yayınlamak istediğinize emin misiniz?', - draftHeader: 'Taslaklar', - inReviewHeader: 'İncelemede', - readyHeader: 'Hazır', - currentEntries: '%{smart_count} girdi |||| %{smart_count} girdiler', - }, - }, -}; - -export default tr; diff --git a/packages/netlify-cms-locales/src/uk/index.js b/packages/netlify-cms-locales/src/uk/index.js deleted file mode 100644 index 3a2cd58b..00000000 --- a/packages/netlify-cms-locales/src/uk/index.js +++ /dev/null @@ -1,205 +0,0 @@ -const uk = { - app: { - header: { - content: 'Зміст', - workflow: 'Робочий процес', - media: 'Медіа', - quickAdd: 'Додати', - }, - app: { - errorHeader: 'Помилка завантаження конфігурації', - configErrors: 'Помилка конфігурації', - checkConfigYml: 'Перевірте config.yml файл.', - loadingConfig: 'Завантаження конфігурації...', - waitingBackend: 'Очікування серверу...', - }, - notFoundPage: { - header: 'Сторінку не знайдено ', - }, - }, - collection: { - sidebar: { - collections: 'Колекції', - searchAll: 'Пошук', - }, - collectionTop: { - viewAs: 'Змінити вигляд', - newButton: 'Створити %{collectionLabel}', - }, - entries: { - loadingEntries: 'Завантаження записів', - cachingEntries: 'Кешування записів', - longerLoading: 'Це може зайняти декілька хвилинок', - }, - }, - editor: { - editorControl: { - field: { - optional: 'необов’язково', - }, - }, - editorControlPane: { - widget: { - required: "%{fieldLabel} є обов'язковим.", - regexPattern: '%{fieldLabel} не задовільняє умові: %{pattern}.', - processing: 'обробляється %{fieldLabel}.', - range: 'значення %{fieldLabel} повинне бути від %{minValue} до %{maxValue}.', - min: 'значення %{fieldLabel} має бути від %{minValue}.', - max: 'значення %{fieldLabel} має бути %{maxValue} та менше.', - }, - }, - editor: { - onLeavePage: 'Ви дійсно бажаєте залишити сторінку?', - onUpdatingWithUnsavedChanges: - 'Присутні незбережені зміни, будь ласка збережіть перед зміною статусу.', - onPublishingNotReady: 'Будь ласка, встановіть статус "Готово" перед публікацією.', - onPublishingWithUnsavedChanges: - 'Присутні незбережені зміни, будь ласка збережіть їх перед публікацією.', - onPublishing: 'Ви дійсно бажаєте опублікувати запис?', - onDeleteWithUnsavedChanges: - 'Ви дійсно бажаєте видалити опублікований запис, як і всі незбережені зміни під час поточної сесії?', - onDeletePublishedEntry: 'Ви дійсно бажаєте видалити опублікований запис?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Видаляться всі неопубліковані зміни до цього запису, а також всі незбережені зміни під час поточної сесії. Бажаєте продовжити?', - onDeleteUnpublishedChanges: - 'Всі незбережені зміни до цього запису буде видалено. Бажаєте продовжити?', - loadingEntry: 'Завантаження...', - confirmLoadBackup: 'Відновлено резервну копію, бажаєте її використати?', - }, - editorToolbar: { - publishing: 'Публікація...', - publish: 'Опублікувати', - published: 'Опубліковано', - publishAndCreateNew: 'Опублікувати і створити нову', - deleteUnpublishedChanges: 'Видалити неопубліковані зміни', - deleteUnpublishedEntry: 'Видалити неопубліковану сторінку', - deletePublishedEntry: 'Видалити опубліковану сторінку', - deleteEntry: 'Видалити', - saving: 'Збереження...', - save: 'Зберегти', - deleting: 'Видалення...', - updating: 'Оновлення...', - status: 'Cтан: %{status}', - backCollection: ' Робота над %{collectionLabel} колекцією', - unsavedChanges: 'Незбережені зміни', - changesSaved: 'Зміни збережено', - draft: 'В роботі', - inReview: 'На розгляді', - ready: 'Готово', - publishNow: 'Опублікувати', - deployPreviewPendingButtonLabel: 'Перевірити оновлення', - deployPreviewButtonLabel: 'Попередній перегляд', - deployButtonLabel: 'Переглянути наживо', - }, - editorWidgets: { - image: { - choose: 'Виберіть зображення', - chooseDifferent: 'Виберіть інше зображення', - remove: 'Видалити зображення', - }, - file: { - choose: 'Виберіть файл', - chooseDifferent: 'Виберіть інший файл', - remove: 'Видалити файл', - }, - unknownControl: { - noControl: "Відсутній модуль для '%{widget}'.", - }, - unknownPreview: { - noPreview: "Відсутній перегляд для '%{widget}'.", - }, - headingOptions: { - headingOne: 'Heading 1', - headingTwo: 'Heading 2', - headingThree: 'Heading 3', - headingFour: 'Heading 4', - headingFive: 'Heading 5', - headingSix: 'Heading 6', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'В роботі', - }, - mediaLibrary: { - onDelete: 'Ви дійсно бажаєте видалити обрані матеріали?', - }, - mediaLibraryModal: { - loading: 'Завантаження...', - noResults: 'Результати відсутні.', - noAssetsFound: 'Матеріали відсутні.', - noImagesFound: 'Зображення відсутні.', - private: 'Private ', - images: 'Зображення', - mediaAssets: 'Медіа матеріали', - search: 'Пошук...', - uploading: 'Завантаження...', - upload: 'Завантажити', - deleting: 'Видалення...', - deleteSelected: 'Видалити обране', - chooseSelected: 'Додати обране', - }, - }, - ui: { - errorBoundary: { - title: 'Помилка', - details: 'Відбулась помилка - будь ласка ', - reportIt: 'надішліть нам деталі.', - detailsHeading: 'Деталі', - recoveredEntry: { - heading: 'Відновлено документ', - warning: 'Будь ласка, збережіть це десь перед тим як піти!', - copyButtonLabel: 'Скопіювати в буфер', - }, - }, - settingsDropdown: { - logOut: 'Вихід', - }, - toast: { - onFailToLoadEntries: 'Помилка завантаження: %{details}', - onFailToLoadDeployPreview: 'Помилка завантаження перегляду: %{details}', - onFailToPersist: 'Помилка перезапису: %{details}', - onFailToDelete: 'Помилка видалення: %{details}', - onFailToUpdateStatus: 'Помилка оновлення статусу: %{details}', - missingRequiredField: - "Йой, здається пропущено обов'язкове поле. Будь ласка, заповніть перед збереженням.", - entrySaved: 'Збережено', - entryPublished: 'Опубліковано', - onFailToPublishEntry: 'Помилка публікації: %{details}', - entryUpdated: 'Статус оновлено', - onDeleteUnpublishedChanges: 'Видалено неопубліковані зміни', - onFailToAuth: '%{details}', - }, - }, - workflow: { - workflow: { - loading: 'Завантаження редакційних матеріалів', - workflowHeading: 'Редакція', - newPost: 'Новий запис', - description: '%{smart_count} записів очікують розгляду, %{readyCount} готові до публікації. ', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} від %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'від %{author}', - deleteChanges: 'Видалити зміни', - deleteNewEntry: 'Видалити новий запис', - publishChanges: 'Опублікувати всі зміни', - publishNewEntry: 'Опублікувати новий запис', - }, - workflowList: { - onDeleteEntry: 'Ви дійсно бажаєте видалити запис?', - onPublishingNotReadyEntry: - 'Тільки елементи з статусом "Готово" можуть бути опубліковані. Будь ласка перемістіть картку в колонку "Готово" для публікації.', - onPublishEntry: 'Дійсно бажаєте опублікувати запис?', - draftHeader: 'В роботі', - inReviewHeader: 'На розгляді', - readyHeader: 'Готово', - currentEntries: '%{smart_count} запис |||| %{smart_count} записів', - }, - }, -}; - -export default uk; diff --git a/packages/netlify-cms-locales/src/vi/index.js b/packages/netlify-cms-locales/src/vi/index.js deleted file mode 100644 index 2925ab1f..00000000 --- a/packages/netlify-cms-locales/src/vi/index.js +++ /dev/null @@ -1,265 +0,0 @@ -const vi = { - auth: { - login: 'Đăng nhập', - loggingIn: 'Đang đăng nhập...', - loginWithNetlifyIdentity: 'Đăng nhập bằng Netlify Identity', - loginWithBitbucket: 'Đăng nhập bằng Bitbucket', - loginWithGitHub: 'Đăng nhập bằng GitHub', - loginWithGitLab: 'Đăng nhập bằng GitLab', - errors: { - email: 'Hãy nhập email của bạn.', - password: 'Hãy nhập mật khẩu của bạn.', - identitySettings: - 'Không thể truy cập thiêt lập danh tính. Hãy chắc chắn rằng bạn đã bật dịch vụ Identity và Git Gateway khi sử dụng git-gateway.', - }, - }, - app: { - header: { - content: 'Nội dung', - workflow: 'Biên tập', - media: 'Tập tin', - quickAdd: 'Tạo nhanh', - }, - app: { - errorHeader: 'Xảy ra lỗi khi tải cấu hình CMS', - configErrors: 'Lỗi cấu hình', - checkConfigYml: 'Kiểm tra lại file config.yml của bạn.', - loadingConfig: 'Đang tải cấu hình...', - waitingBackend: 'Đang chờ backend...', - }, - notFoundPage: { - header: 'Không tìm thấy', - }, - }, - collection: { - sidebar: { - collections: 'Bộ sưu tập', - allCollections: 'Tất cả bộ sưu tập', - searchAll: 'Tìm kiếm tất cả', - searchIn: 'Tìm kiếm trong', - }, - collectionTop: { - sortBy: 'Sắp xếp theo', - viewAs: 'View as', - newButton: '%{collectionLabel} mới', - ascending: 'Tăng dần', - descending: 'Giảm dần', - searchResults: 'Kết quả tìm kiếm cho "%{searchTerm}"', - searchResultsInCollection: 'Kết quả tìm kiếm cho "%{searchTerm}" trong %{collection}', - filterBy: 'Lọc theo', - }, - entries: { - loadingEntries: 'Đang tải...', - cachingEntries: 'Đang lưu...', - longerLoading: 'Sẽ mất vài phút', - noEntries: 'Không có mục nào', - }, - defaultFields: { - author: { - label: 'Tác giả', - }, - updatedOn: { - label: 'Ngày cập nhật', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: 'không bắt buộc', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} bắt buộc nhập.', - regexPattern: '%{fieldLabel} không khớp với mẫu: %{pattern}.', - processing: '%{fieldLabel} đang xử lý.', - range: '%{fieldLabel} phải nằm trong khoảng từ %{minValue} đến %{maxValue}.', - min: '%{fieldLabel} phải ít nhất %{minValue}.', - max: '%{fieldLabel} tối đa %{maxValue} hoặc ít hơn.', - rangeCount: '%{fieldLabel} phải nằm trong khoảng từ %{minCount} đến %{maxCount} mục.', - rangeCountExact: '%{fieldLabel} phải có %{count} mục.', - rangeMin: '%{fieldLabel} phải có ít nhất %{minCount} mục.', - rangeMax: '%{fieldLabel} phải có tối đa %{maxCount} mục hoặc ít hơn.', - invalidPath: `Đường dẫn '%{path}' không hợp lệ`, - pathExists: `Đường dẫn '%{path}' đã tồn tại`, - }, - }, - editor: { - onLeavePage: 'Bạn có chắc rằng bạn muốn rời khỏi trang này?', - onUpdatingWithUnsavedChanges: - 'Bạn chưa lưu những thay đổi, hãy lưu trước khi thay đổi trạng thái.', - onPublishingNotReady: 'Hãy thay đổi trạng thái thành "Sẵn sàng" trước khi công bố.', - onPublishingWithUnsavedChanges: 'Bạn có thay đổi chưa lưu, hãy lưu trước khi công bố.', - onPublishing: 'Bạn có chắc rằng bạn muốn công bố mục này?', - onUnpublishing: 'Bạn có chắc rằng bạn muốn ngừng công bố mục này?', - onDeleteWithUnsavedChanges: - 'Bạn có chắc rằng bạn muốn xoá mục đã được công bố này, cũng như là những thay đổi chưa lưu của bạn trong phiên làm việc này?', - onDeletePublishedEntry: 'Bạn có chắc rằng bạn muốn xoá mục đã được công bố này?', - onDeleteUnpublishedChangesWithUnsavedChanges: - 'Điều này sẽ xoá tất cả những thay đổi chưa được lưu trong mục này, cũng như là những thay đổi chưa được lưu của bạn trong phiên làm việc này. Bạn vẫn muốn xoá chứ?', - onDeleteUnpublishedChanges: - 'Tất cả những thay đổi chưa được lưu trong mục này sẽ bị xoá. Bạn vẫn muốn xoá chứ?', - loadingEntry: 'Đang tải...', - confirmLoadBackup: - 'Một bản sao lưu trên máy đã được phục hồi cho mục này, bạn có muốn tải lên không?', - }, - editorToolbar: { - publishing: 'Đang công bố...', - publish: 'Công bố', - published: 'Đã công bố', - unpublish: 'Ngừng công bố', - duplicate: 'Sao chép', - unpublishing: 'Đang ngừng công bố...', - publishAndCreateNew: 'Công bố và tạo mới', - publishAndDuplicate: 'Công bố và sao chép', - deleteUnpublishedChanges: 'Xoá thay đổi chưa công bố này', - deleteUnpublishedEntry: 'Xoá mục chưa được công bố này', - deletePublishedEntry: 'Xoá mục đã được công bố này', - deleteEntry: 'Xoá mục này', - saving: 'Đang lưu...', - save: 'Lưu', - deleting: 'Đang xoá...', - updating: 'Đang cập nhật...', - status: 'Trạng: %{status}', - backCollection: ' Đang viết trong bộ sưu tập %{collectionLabel}', - unsavedChanges: 'Thay đổi chưa được lưu', - changesSaved: 'Thay đổi đã được lưu', - draft: 'Bản nháp', - inReview: 'Đang xét duyệt', - ready: 'Sẵn sàng', - publishNow: 'Công bố ngay', - deployPreviewPendingButtonLabel: 'Kiểm tra Xem trước', - deployPreviewButtonLabel: 'Xem trước', - deployButtonLabel: 'Xem bản hoàn chỉnh', - }, - editorWidgets: { - markdown: { - richText: 'Văn bản định dạng', - markdown: 'Markdown', - }, - image: { - choose: 'Chọn một hình', - chooseDifferent: 'Chọn hình khác', - remove: 'Gỡ bỏ hình', - }, - file: { - choose: 'Chọn một tập tin', - chooseDifferent: 'Chọn tập tin khác', - remove: 'Gỡ bỏ tập tin', - }, - unknownControl: { - noControl: "Không tìm thấy control cho widget '%{widget}'.", - }, - unknownPreview: { - noPreview: "Không tìm thấy preview cho widget '%{widget}'.", - }, - headingOptions: { - headingOne: 'Tiêu đề cấp 1', - headingTwo: 'Tiêu đề cấp 2', - headingThree: 'Tiêu đề cấp 3', - headingFour: 'Tiêu đề cấp 4', - headingFive: 'Tiêu đề cấp 5', - headingSix: 'Tiêu đề cấp 6', - }, - datetime: { - now: 'Ngay lúc này', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: 'Bản nháp', - }, - mediaLibrary: { - onDelete: 'Bạn có chắc rằng bạn muốn xoá tập tin này?', - fileTooLarge: 'Tập tin quá lớn.\nCấu hình không cho phép những tập tin lớn hơn %{size} kB.', - }, - mediaLibraryModal: { - loading: 'Đang tải...', - noResults: 'Không có kết quả.', - noAssetsFound: 'Không tìm thấy tập tin nào.', - noImagesFound: 'Không tìm thấy hình nào.', - private: 'Riêng tư ', - images: 'Hình ảnh', - mediaAssets: 'Tập tin', - search: 'Tìm kiếm...', - uploading: 'Đang tải lên...', - upload: 'Tải lên', - download: 'Tải về', - deleting: 'Đang xoá...', - deleteSelected: 'Xoá những cái đã chọn', - chooseSelected: 'Lấy những cái đã chọn', - }, - }, - ui: { - default: { - goBackToSite: 'Quay về trang web', - }, - errorBoundary: { - title: 'Lỗi', - details: 'Đã xảy ra lỗi - xin hãy ', - reportIt: 'tạo một issue trên GitHub.', - detailsHeading: 'Chi tiết', - privacyWarning: - 'Tạo một issue với nội dung lỗi và dữ liệu debug được nhập sẵn.\nHãy xác nhận những thông tin này là đúng và gỡ bỏ dữ liệu nhạy cảm nếu cần thiết.', - recoveredEntry: { - heading: 'Tài liệu đã được phục hồi', - warning: 'Hãy sao chép/dán nội dung này ở đâu đó trước khi chuyển sang trang khác!', - copyButtonLabel: 'Sao chép vào vùng nhớ', - }, - }, - settingsDropdown: { - logOut: 'Đăng xuất', - }, - toast: { - onFailToLoadEntries: 'Không thể tải mục: %{details}', - onFailToLoadDeployPreview: 'Không thể tải xem trước: %{details}', - onFailToPersist: 'Không thể giữ lại mục: %{details}', - onFailToDelete: 'Không thể xoá mục: %{details}', - onFailToUpdateStatus: 'Không thể cập nhật trạng thái: %{details}', - missingRequiredField: 'Bạn còn thiếu vài thông tin bắt buộc. Hãy hoàn thành trước khi lưu.', - entrySaved: 'Mục đã được lưu', - entryPublished: 'Mục đã được công bố', - entryUnpublished: 'Mục đã ngừng công bố', - onFailToPublishEntry: 'Không thể công bố: %{details}', - onFailToUnpublishEntry: 'Không thể ngừng công bố mục: %{details}', - entryUpdated: 'Trạng thái của mục đã được cập nhật', - onDeleteUnpublishedChanges: 'Những thay đổi chưa được công bố đã được xoá', - onFailToAuth: '%{details}', - onLoggedOut: 'Bạn đã đăng xuất, hãy sao lưu dữ liệu và đăng nhập lại', - onBackendDown: 'Dịch vụ backend đang gặp trục trặc. Hãy xem {details} để biết thêm thông tin', - }, - }, - workflow: { - workflow: { - loading: 'Đang tải bài viết', - workflowHeading: 'Quy trình biên tập', - newPost: 'Bài mới', - description: - '%{smart_count} bài đang chờ duyệt, %{readyCount} bài đã sẵn sàng để công bố. |||| %{smart_count} bài đang chờ duyệt, %{readyCount} bài đã sẵn sàng để công bố. ', - dateFormat: 'D MMMM', - }, - workflowCard: { - lastChange: '%{date} bởi %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'bởi %{author}', - deleteChanges: 'Xoá thay đổi', - deleteNewEntry: 'Xoá bài mới', - publishChanges: 'Công bố thay đổi', - publishNewEntry: 'Công bố bài mới', - }, - workflowList: { - onDeleteEntry: 'Bạn có chắc rằng bạn muốn xoá bài này?', - onPublishingNotReadyEntry: - 'Chỉ những bài với trạng thái "Sẵn sàng" mới có thể được công bố. Hãy kéo thẻ vào cột "Sẵn sàng" để cho phép công bố.', - onPublishEntry: 'Bạn có chắc rằng bạn muốn công khai bài này?', - draftHeader: 'Bản nháp', - inReviewHeader: 'Đang xét duyệt', - readyHeader: 'Sẵn sàng', - currentEntries: '%{smart_count} bài |||| %{smart_count} bài', - }, - }, -}; - -export default vi; diff --git a/packages/netlify-cms-locales/src/zh_Hans/index.js b/packages/netlify-cms-locales/src/zh_Hans/index.js deleted file mode 100644 index c54a8b65..00000000 --- a/packages/netlify-cms-locales/src/zh_Hans/index.js +++ /dev/null @@ -1,296 +0,0 @@ -const zh_Hans = { - auth: { - login: '登录', - loggingIn: '正在登录...', - loginWithNetlifyIdentity: '使用 Netlify Identity 登录', - loginWithAzure: '使用 Azure 登录', - loginWithBitbucket: '使用 Bitbucket 登录', - loginWithGitHub: '使用 GitHub 登录', - loginWithGitLab: '使用 GitLab 登录', - errors: { - email: '请输入电子邮箱', - password: '请输入密码', - identitySettings: - '无法连接账户认证系统(如果正在使用 git-gateway 作为 backend,请确保已经开启 Netlify Identity 服务以及 Git Gateway)', - }, - }, - app: { - header: { - content: '内容', - workflow: '工作流', - media: '媒体', - quickAdd: '快速新建', - }, - app: { - errorHeader: '加载 CMS 配置时发生错误', - configErrors: '配置错误', - checkConfigYml: '请检查 config.yml 文件是否配置正确', - loadingConfig: '正在加载配置...', - waitingBackend: '等待 backend 数据...', - }, - notFoundPage: { - header: '页面不存在', - }, - }, - collection: { - sidebar: { - collections: '集合', - allCollections: '所有集合', - searchAll: '查找所有...', - searchIn: '查找', - }, - collectionTop: { - sortBy: '排序', - viewAs: '查看', - newButton: '新建%{collectionLabel}', - ascending: '升序', - descending: '降序', - searchResults: '有关“%{searchTerm}”的搜索结果', - searchResultsInCollection: '在%{collection}中有关“%{searchTerm}”的搜索结果', - filterBy: '筛选', - groupBy: '分组', - }, - entries: { - loadingEntries: '正在加载内容...', - cachingEntries: '正在缓存内容...', - longerLoading: '这可能需要花费几分钟时间', - noEntries: '暂无内容', - }, - groups: { - other: '其他', - negateLabel: '非%{label}', - }, - defaultFields: { - author: { - label: '作者', - }, - updatedOn: { - label: '更新于', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: '可选', - }, - }, - editorControlPane: { - widget: { - required: '“%{fieldLabel}”是必填项', - regexPattern: '“%{fieldLabel}”不满足模式%{pattern}', - processing: '“%{fieldLabel}”正在处理中', - range: '“%{fieldLabel}”必须位于 %{minValue} 和 %{maxValue} 之间', - min: '“%{fieldLabel}”必须至少为 %{minValue}', - max: '“%{fieldLabel}”必须小于等于 %{maxValue}', - rangeCount: '“%{fieldLabel}”必须包含 %{minCount} 到 %{maxCount} 个项目', - rangeCountExact: '“%{fieldLabel}”必须且只能包含 %{count} 个项目', - minCount: '“%{fieldLabel}”必须为至少 %{minCount} 个项目', - maxCount: '“%{fieldLabel}”必须为小于等于 %{maxCount} 个项目', - invalidPath: `“%{path}”为无效路径`, - pathExists: `路径“%{path}”已经存在`, - }, - i18n: { - writingInLocale: '正在使用%{locale}撰写', - }, - }, - editor: { - onLeavePage: '你确定要离开此页面吗?', - onUpdatingWithUnsavedChanges: '你有尚未保存的修改,请在更新状态前进行保存', - onPublishingNotReady: '请在发布之前将状态更新为“就绪”', - onPublishingWithUnsavedChanges: '你有尚未保存的修改,请在发布前进行保存', - onPublishing: '你确定要发布此内容吗?', - onUnpublishing: '你确定要撤销发布此内容吗?', - onDeleteWithUnsavedChanges: '你确定要删除这个已经发布的内容,以及当前尚未保存的修改吗?', - onDeletePublishedEntry: '你确定要删除这个已经发布的内容吗?', - onDeleteUnpublishedChangesWithUnsavedChanges: - '此内容所有未被发布的修改,以及当前尚未保存的修改都将被删除,你确定吗?', - onDeleteUnpublishedChanges: '此内容所有未被发布的修改都将被删除,你确定吗?', - loadingEntry: '正在加载内容...', - confirmLoadBackup: '发现了一个对应此内容的本地备份,你要加载它吗?', - }, - editorInterface: { - toggleI18n: '打开/关闭国际化', - togglePreview: '打开/关闭预览', - toggleScrollSync: '同步滚动', - }, - editorToolbar: { - publishing: '正在发布...', - publish: '发布', - published: '已发布', - unpublish: '撤销发布', - duplicate: '复制', - unpublishing: '正在撤销发布...', - publishAndCreateNew: '发布,然后新建内容', - publishAndDuplicate: '发布,然后复制内容', - deleteUnpublishedChanges: '删除未发布的修改', - deleteUnpublishedEntry: '删除未发布的内容', - deletePublishedEntry: '删除已发布的内容', - deleteEntry: '删除内容', - saving: '正在保存...', - save: '保存', - deleting: '正在删除...', - updating: '正在更新...', - status: '状态: %{status}', - backCollection: '正在集合“%{collectionLabel}”中编写', - unsavedChanges: '含未保存的修改', - changesSaved: '修改已保存', - draft: '草稿', - inReview: '审核中', - ready: '就绪', - publishNow: '立即发布', - deployPreviewPendingButtonLabel: '点击以预览', - deployPreviewButtonLabel: '查看预览', - deployButtonLabel: '查看发布', - }, - editorWidgets: { - markdown: { - bold: '粗体', - italic: '斜体', - code: '代码', - link: '链接', - linkPrompt: '输入链接的 URL', - headings: '标题', - quote: '引用', - bulletedList: '无序列表', - numberedList: '有序列表', - addComponent: '添加组件', - richText: '富文本', - markdown: 'Markdown', - }, - image: { - choose: '选择图片', - chooseUrl: '从 URL 插入', - replaceUrl: '用 URL 替代', - promptUrl: '输入图片的 URL', - chooseDifferent: '选择其他图片', - remove: '移除图片', - }, - file: { - choose: '选择文件', - chooseUrl: '从 URL 插入', - replaceUrl: '用 URL 替代', - promptUrl: '输入文件的 URL', - chooseDifferent: '选择其他文件', - remove: '移除文件', - }, - unknownControl: { - noControl: "'%{widget}'的控件不存在", - }, - unknownPreview: { - noPreview: "'%{widget}'无法预览", - }, - headingOptions: { - headingOne: '标题 1', - headingTwo: '标题 2', - headingThree: '标题 3', - headingFour: '标题 4', - headingFive: '标题 5', - headingSix: '标题 6', - }, - datetime: { - now: '现在', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: '草稿', - copy: '复制', - copyUrl: '复制 URL', - copyPath: '复制路径', - copyName: '复制名称', - copied: '已复制', - }, - mediaLibrary: { - onDelete: '你确定要删除此媒体项目吗?', - fileTooLarge: '文件体积过大\n目前的配置中不允许文件体积超过 %{size} kB', - }, - mediaLibraryModal: { - loading: '正在加载...', - noResults: '暂无结果', - noAssetsFound: '未找到资源', - noImagesFound: '未找到图片', - private: '私有', - images: '图片', - mediaAssets: '媒体资源', - search: '搜索...', - uploading: '正在上传...', - upload: '上传', - download: '下载', - deleting: '正在下载...', - deleteSelected: '删除已选中项目', - chooseSelected: '选用已选中项目', - }, - }, - ui: { - default: { - goBackToSite: '返回主页', - }, - errorBoundary: { - title: '错误', - details: '程序发生了一个错误,请', - reportIt: '在 Github 上发布一个 Issue', - detailsHeading: '详情', - privacyWarning: - '发布一个 Issue 会将错误信息和调试数据预置其中\n请确保这些信息是正确的,同时移除那些敏感数据', - recoveredEntry: { - heading: '已恢复的文档', - warning: '请在切换至其他页面之前,将它复制并粘贴到某个地方', - copyButtonLabel: '复制到剪贴板', - }, - }, - settingsDropdown: { - logOut: '注销', - }, - toast: { - onFailToLoadEntries: '加载内容失败: %{details}', - onFailToLoadDeployPreview: '加载预览失败: %{details}', - onFailToPersist: '保存内容失败: %{details}', - onFailToDelete: '删除内容失败: %{details}', - onFailToUpdateStatus: '更新状态失败: %{details}', - missingRequiredField: '你漏掉了一个必填项,请在保存之前将它填写好', - entrySaved: '内容已保存', - entryPublished: '内容已发布', - entryUnpublished: '内容已撤销发布', - onFailToPublishEntry: '发布失败: %{details}', - onFailToUnpublishEntry: '撤销发布失败: %{details}', - entryUpdated: '内容状态已更新', - onDeleteUnpublishedChanges: '未发布的修改已删除', - onFailToAuth: '%{details}', - onLoggedOut: '你已注销,请先保存好数据然后再次登录', - onBackendDown: 'Backend 服务已中断,欲知详情请查看:%{details}', - }, - }, - workflow: { - workflow: { - loading: '正在加载编辑工作流项目', - workflowHeading: '编辑工作流', - newPost: '新建帖子', - description: - '%{smart_count} 个待审查的内容、%{readyCount} 个已就绪的内容 |||| %{smart_count} 个待检查的内容、%{readyCount} 个已就绪的内容', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} 由 %{author} 修改', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: '由 %{author} 修改', - deleteChanges: '删除修改', - deleteNewEntry: '删除新内容', - publishChanges: '发布修改', - publishNewEntry: '发布新内容', - }, - workflowList: { - onDeleteEntry: '你确定要删除此内容吗?', - onPublishingNotReadyEntry: - '只有状态为“就绪”的项目才能被发布。需要先将卡片拖动到“就绪”一列才能发布', - onPublishEntry: '你确定要发布此内容吗?', - draftHeader: '草稿', - inReviewHeader: '审查中', - readyHeader: '就绪', - currentEntries: '%{smart_count} 个内容 |||| %{smart_count} 个内容', - }, - }, -}; - -export default zh_Hans; diff --git a/packages/netlify-cms-locales/src/zh_Hant/index.js b/packages/netlify-cms-locales/src/zh_Hant/index.js deleted file mode 100644 index 531faefa..00000000 --- a/packages/netlify-cms-locales/src/zh_Hant/index.js +++ /dev/null @@ -1,274 +0,0 @@ -const zh_Hant = { - auth: { - login: '登入', - loggingIn: '正在登入...', - loginWithNetlifyIdentity: '使用你的 Netlify 帳號來進行登入', - loginWithBitbucket: '使用你的 Bitbucket 帳號來進行登入', - loginWithGitHub: '使用你的 GitHub 帳號來進行登入', - loginWithGitLab: '使用你的 GitLab 帳號來進行登入', - errors: { - email: '請確認你已經輸入你的電子郵件。', - password: '請輸入你的密碼。', - identitySettings: - '無法連接認證系統!當使用 git-gateway 作為後端資料庫時,請確認您已開啟認證服務及 Git Gateway。', - }, - }, - app: { - header: { - content: '內容', - workflow: '作業流程', - media: '媒體', - quickAdd: '快速新增', - }, - app: { - errorHeader: '載入 CMS 設定時發生錯誤', - configErrors: '設定錯誤', - checkConfigYml: '請確認你的 config.yml 設定檔的內容是否正確', - loadingConfig: '正在載入設定...', - waitingBackend: '正在等待後端資料連接...', - }, - notFoundPage: { - header: '找不到頁面', - }, - }, - collection: { - sidebar: { - collections: '集合', - allCollections: '所有集合', - searchAll: '尋找所有集合', - searchIn: '搜尋範圍', - }, - collectionTop: { - sortBy: '排序方式', - viewAs: '瀏覽方式', - newButton: '新增 %{collectionLabel}', - ascending: '由小到大', - descending: '由大到小', - searchResults: '搜尋 "%{searchTerm}" 的結果', - searchResultsInCollection: '在 %{collection} 中搜尋 %{searchTerm}" 的結果', - filterBy: '篩選方式', - }, - entries: { - loadingEntries: '載入內容', - cachingEntries: '快取內容', - longerLoading: '這可能需要幾分鐘的時間', - noEntries: '沒有內容', - }, - defaultFields: { - author: { - label: '作者', - }, - updatedOn: { - label: '更新於', - }, - }, - }, - editor: { - editorControl: { - field: { - optional: '選填', - }, - }, - editorControlPane: { - widget: { - required: '%{fieldLabel} 是必須的。', - regexPattern: '%{fieldLabel} 並不符合 %{pattern} 的型態', - processing: '%{fieldLabel} 正在處理', - range: '%{fieldLabel} 必須介於 %{minValue} 和 %{maxValue} 之間', - min: '%{fieldLabel} 必須至少為 %{minValue}', - max: '%{fieldLabel} 必須小於或等於 %{maxValue}', - rangeCount: '%{fieldLabel} 必須有 %{minCount} 到 %{maxCount} 個項目。', - rangeCountExact: '%{fieldLabel} 必須正好有 %{count} 個項目。', - rangeMin: '%{fieldLabel} 必須至少有 %{minCount} 個項目。', - rangeMax: '%{fieldLabel} 最多只能有 %{maxCount} 個項目。', - invalidPath: `'%{path}' 不是有效的路徑`, - pathExists: `路徑 '%{path}' 已經存在`, - }, - i18n: { - writingInLocale: '以 %{locale} 書寫', - }, - }, - editor: { - onLeavePage: '您確定要離開這頁嗎?', - onUpdatingWithUnsavedChanges: '您有未儲存的變更,在更新狀態前請先進行儲存。', - onPublishingNotReady: '在發布前,請先將狀態設定為:預備發布。', - onPublishingWithUnsavedChanges: '您有未儲存的變更,在發布前請先進行儲存。', - onPublishing: '你確定要發表此內容嗎?', - onUnpublishing: '你確定要取消發表此內容嗎?', - onDeleteWithUnsavedChanges: '你確定要刪除這篇已發布的內容以及你尚未儲存的變更?', - onDeletePublishedEntry: '你確定要刪除這篇已發布的內容?', - onDeleteUnpublishedChangesWithUnsavedChanges: - '這將會刪除此內容所有未發布的變更,以及未儲存的變更。你確定還是要刪除?', - onDeleteUnpublishedChanges: '此內容所有未發布的變更都將會被刪除。你確定還是要刪除?', - loadingEntry: '載入內容中...', - confirmLoadBackup: '此內容的本地備份已經還原,你想要使用嗎?', - }, - editorToolbar: { - publishing: '發布中...', - publish: '發布', - published: '已發布', - unpublish: '取消發布', - duplicate: '建立新內容', - unpublishing: '取消發布中...', - publishAndCreateNew: '發布並建立內容', - publishAndDuplicate: '發布並複製內容', - deleteUnpublishedChanges: '刪除未發布的變更', - deleteUnpublishedEntry: '刪除未發布的內容', - deletePublishedEntry: '刪除已發布的內容', - deleteEntry: '刪除內容', - saving: '儲存中...', - save: '儲存', - deleting: '刪除中...', - updating: '更新中...', - status: '狀態: %{status}', - backCollection: '在集合 %{collectionLabel} 新增內容', - unsavedChanges: '未儲存變更', - changesSaved: '已儲存變更', - draft: '草稿', - inReview: '正在審核', - ready: '預備發布', - publishNow: '立即發布', - deployPreviewPendingButtonLabel: '點擊來進行預覽', - deployPreviewButtonLabel: '進行預覽', - deployButtonLabel: '觀看已發布的內容', - }, - editorWidgets: { - markdown: { - bold: '粗體', - italic: '斜體', - code: '程式碼', - link: '連結', - linkPrompt: '輸入連結網址', - headings: '標題', - quote: '引言', - bulletedList: '項目符號清單', - numberedList: '編號清單', - addComponent: '加入元件', - richText: 'Rich Text', - markdown: 'Markdown', - }, - image: { - choose: '選擇一張圖片', - chooseDifferent: '選擇其他圖片', - remove: '刪除圖片', - }, - file: { - choose: '選擇一個檔案', - chooseDifferent: '選擇其他檔案', - remove: '刪除檔案', - }, - unknownControl: { - noControl: "無法控制元件: '%{widget}'.", - }, - unknownPreview: { - noPreview: "無法預覽元件: '%{widget}'.", - }, - headingOptions: { - headingOne: '標題 1', - headingTwo: '標題 2', - headingThree: '標題 3', - headingFour: '標題 4', - headingFive: '標題 5', - headingSix: '標題 6', - }, - datetime: { - now: '現在', - }, - }, - }, - mediaLibrary: { - mediaLibraryCard: { - draft: '草稿', - }, - mediaLibrary: { - onDelete: '你確定要刪除已選擇的媒體嗎?', - fileTooLarge: '檔案太大。\n已設定不允許大於 %{size} kB 的檔案。', - }, - mediaLibraryModal: { - loading: '載入中...', - noResults: '沒有結果', - noAssetsFound: '沒有發現媒體資產。', - noImagesFound: '沒有發現影像。', - private: '私人', - images: '影像', - mediaAssets: '媒體資產', - search: '搜尋中...', - uploading: '上傳中...', - upload: '上傳新內容', - download: '下載', - deleting: '刪除中...', - deleteSelected: '刪除已選擇的項目', - chooseSelected: '選擇已選擇的項目', - }, - }, - ui: { - default: { - goBackToSite: '回到網站', - }, - errorBoundary: { - title: '錯誤', - details: '發生錯誤!請 ', - reportIt: '回報錯誤', - detailsHeading: '細節', - privacyWarning: - '建立 issue,並加上錯誤訊息及除錯資訊。\n請確認資訊正確,敏感資料也已經去除。', - recoveredEntry: { - heading: '已恢復的內容', - warning: '在你離開本頁前,請將此處的內容複製貼上到其他地方來進行備份!', - copyButtonLabel: '複製到剪貼簿', - }, - }, - settingsDropdown: { - logOut: '登出', - }, - toast: { - onFailToLoadEntries: '無法載入內容: %{details}', - onFailToLoadDeployPreview: '無法預覽內容: %{details}', - onFailToPersist: '無法暫存內容: %{details}', - onFailToDelete: '無法刪除內容: %{details}', - onFailToUpdateStatus: '無法更新狀態: %{details}', - missingRequiredField: '糟了!你漏填了一個必須填入的欄位,在儲存前請先填完所有內容', - entrySaved: '已儲存內容', - entryPublished: '已發布內容', - entryUnpublished: '已取消發布內容', - onFailToPublishEntry: '無法發布: %{details}', - onFailToUnpublishEntry: '無法取消發布: %{details}', - entryUpdated: '內容狀態已更新', - onDeleteUnpublishedChanges: '已刪除未發布的變更', - onFailToAuth: '%{details}', - onLoggedOut: '你已經登出,請備份任何資料然後重新登入', - onBackendDown: '後端服務發生中斷。看 %{details} 取得更多資訊', - }, - }, - workflow: { - workflow: { - loading: '正在載入編輯流程的內容', - workflowHeading: '編輯作業流程', - newPost: '建立新的內容', - description: - '%{smart_count} 篇內容正在等待審核, %{readyCount} 篇已經準備進行發布。 |||| %{smart_count} 篇內容正在等待審核, %{readyCount} 篇已經準備進行發布。', - dateFormat: 'MMMM D', - }, - workflowCard: { - lastChange: '%{date} by %{author}', - lastChangeNoAuthor: '%{date}', - lastChangeNoDate: 'by %{author}', - deleteChanges: '刪除變更', - deleteNewEntry: '刪除新內容', - publishChanges: '發布變更', - publishNewEntry: '發布新內容', - }, - workflowList: { - onDeleteEntry: '你確定要刪除這個項目嗎?', - onPublishingNotReadyEntry: - '只有狀態為 預備發布 的內容可以被發布,請將本內容的狀態設定為 預備發布 來進行發布前的準備', - onPublishEntry: '你確定要發表這篇內容嗎?', - draftHeader: '草稿', - inReviewHeader: '正在預覽', - readyHeader: '準備完成', - currentEntries: '%{smart_count} 篇內容 |||| %{smart_count} 篇內容', - }, - }, -}; - -export default zh_Hant; diff --git a/packages/netlify-cms-locales/webpack.config.js b/packages/netlify-cms-locales/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-locales/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-media-library-cloudinary/CHANGELOG.md b/packages/netlify-cms-media-library-cloudinary/CHANGELOG.md deleted file mode 100644 index 50ed0041..00000000 --- a/packages/netlify-cms-media-library-cloudinary/CHANGELOG.md +++ /dev/null @@ -1,195 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.3.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.9...netlify-cms-media-library-cloudinary@1.3.10) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.8...netlify-cms-media-library-cloudinary@1.3.9) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.7...netlify-cms-media-library-cloudinary@1.3.8) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## 1.3.7 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.3.6 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.3.5 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [1.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.3...netlify-cms-media-library-cloudinary@1.3.4) (2019-09-26) - - -### Bug Fixes - -* **media-library-cloudinary:** when 'multiple' is true, always return an array ([#2656](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2656)) ([4c32ee4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/4c32ee4)) - - - - - -## [1.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.2...netlify-cms-media-library-cloudinary@1.3.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.2-beta.0...netlify-cms-media-library-cloudinary@1.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.1...netlify-cms-media-library-cloudinary@1.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.1-beta.1...netlify-cms-media-library-cloudinary@1.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -## [1.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.1-beta.0...netlify-cms-media-library-cloudinary@1.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/6ffd13b)) - - - - - -## [1.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.3.0...netlify-cms-media-library-cloudinary@1.3.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.2.0...netlify-cms-media-library-cloudinary@1.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/d142b32)) - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.2.0-beta.0...netlify-cms-media-library-cloudinary@1.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-media-library-cloudinary - - - - - -# [1.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.1.3-beta.0...netlify-cms-media-library-cloudinary@1.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/82cc794)) - - - - - -## [1.1.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.1.2...netlify-cms-media-library-cloudinary@1.1.3-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/ccef446)) - - - - - -## [1.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.1.1...netlify-cms-media-library-cloudinary@1.1.2) (2019-03-11) - - -### Bug Fixes - -* **cloudinary:** allow multiple asset selection per field ([#2157](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2157)) ([e297075](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/e297075)) -* **cloudinary:** update config object shape ([#2044](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/2044)) ([b42a9c6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/b42a9c6)) - - - - - -## [1.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/compare/netlify-cms-media-library-cloudinary@1.1.0...netlify-cms-media-library-cloudinary@1.1.1) (2018-12-11) - - -### Bug Fixes - -* **media-library-cloudinary:** fix options, add tests ([#1938](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/1938)) ([443f060](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/443f060)) -* **media-library-uploadcare:** fix bugs, add tests ([#1953](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/1953)) ([716ee62](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/716ee62)) - - - - - -# 1.1.0 (2018-12-04) - - -### Features - -* add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary/commit/1fc2f50)) diff --git a/packages/netlify-cms-media-library-cloudinary/README.md b/packages/netlify-cms-media-library-cloudinary/README.md deleted file mode 100644 index 0e619c7f..00000000 --- a/packages/netlify-cms-media-library-cloudinary/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-media-library-cloudinary/README.md)! diff --git a/packages/netlify-cms-media-library-cloudinary/package.json b/packages/netlify-cms-media-library-cloudinary/package.json deleted file mode 100644 index a8f6ebc3..00000000 --- a/packages/netlify-cms-media-library-cloudinary/package.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "netlify-cms-media-library-cloudinary", - "description": "Cloudinary integration for Netlify CMS", - "version": "1.3.10", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-cloudinary", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-media-library-cloudinary.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "cloudinary", - "image", - "images", - "media", - "assets", - "files", - "uploads" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "netlify-cms-lib-util": "^2.12.3" - } -} diff --git a/packages/netlify-cms-media-library-cloudinary/src/__tests__/index.spec.js b/packages/netlify-cms-media-library-cloudinary/src/__tests__/index.spec.js deleted file mode 100644 index b1d0f658..00000000 --- a/packages/netlify-cms-media-library-cloudinary/src/__tests__/index.spec.js +++ /dev/null @@ -1,287 +0,0 @@ -import cloudinary from '../index'; - -jest.mock('netlify-cms-lib-util'); - -describe('cloudinary exports', () => { - it('exports an object with expected properties', () => { - expect(cloudinary).toMatchInlineSnapshot(` - Object { - "init": [Function], - "name": "cloudinary", - } - `); - }); -}); - -describe('cloudinary media library', () => { - let mediaLibrary; - let cloudinaryConfig; - let cloudinaryInsertHandler; - - beforeEach(() => { - /** - * Mock of the Cloudinary library itself, which is otherwise created by - * their script (which isn't actually run during testing). - */ - window.cloudinary = { - createMediaLibrary: (config, { insertHandler }) => { - cloudinaryConfig = config; - cloudinaryInsertHandler = insertHandler; - return mediaLibrary; - }, - }; - - /** - * Mock of the object returned by the Cloudinary createMediaLibrary method. - */ - mediaLibrary = { - show: jest.fn(), - hide: jest.fn(), - }; - }); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - afterEach(() => { - const { loadScript } = require('netlify-cms-lib-util'); - expect(loadScript).toHaveBeenCalledTimes(1); - expect(loadScript).toHaveBeenCalledWith('https://media-library.cloudinary.com/global/all.js'); - }); - - describe('configuration', () => { - const defaultCloudinaryConfig = { - button_class: undefined, - inline_container: undefined, - insert_transformation: false, - z_index: '99999', - multiple: false, - }; - - it('has defaults', async () => { - await cloudinary.init(); - expect(cloudinaryConfig).toEqual(defaultCloudinaryConfig); - }); - - it('does not allow enforced values to be overridden', async () => { - const options = { - config: { - button_class: 'foo', - inline_container: 'foo', - insert_transformation: 'foo', - z_index: 0, - }, - }; - await cloudinary.init({ options }); - expect(cloudinaryConfig).toEqual(defaultCloudinaryConfig); - }); - - it('allows non-enforced defaults to be overridden', async () => { - const options = { - config: { - multiple: true, - }, - }; - await cloudinary.init({ options }); - expect(cloudinaryConfig).toEqual({ ...defaultCloudinaryConfig, ...options.config }); - }); - - it('allows unknown values', async () => { - const options = { - config: { - foo: 'bar', - }, - }; - await cloudinary.init({ options }); - expect(cloudinaryConfig).toEqual({ ...defaultCloudinaryConfig, ...options.config }); - }); - }); - - describe('insertHandler', () => { - let handleInsert; - const asset = { - url: 'http://foo.bar/image.jpg', - secure_url: 'https://foo.bar/image.jpg', - public_id: 'image', - format: 'jpg', - }; - const assetWithDerived = { - ...asset, - derived: [ - { - secure_url: 'https://derived.foo.bar/image.jpg', - url: 'http://derived.foo.bar/image.jpg', - }, - ], - }; - - beforeEach(() => { - handleInsert = jest.fn(); - }); - - it('calls insert function with single asset', async () => { - await cloudinary.init({ handleInsert }); - cloudinaryInsertHandler({ assets: [asset] }); - expect(handleInsert).toHaveBeenCalledWith(expect.any(String)); - }); - - it('calls insert function with multiple assets', async () => { - const options = { - config: { - multiple: true, - }, - }; - await cloudinary.init({ options, handleInsert }); - cloudinaryInsertHandler({ assets: [asset, asset] }); - expect(handleInsert).toHaveBeenCalledWith(expect.any(Array)); - }); - - it('calls insert function with array when only one asset is returned and config.multiple is true', async () => { - const options = { - config: { - multiple: true, - }, - }; - await cloudinary.init({ options, handleInsert }); - cloudinaryInsertHandler({ assets: [asset] }); - expect(handleInsert).toHaveBeenCalledWith(expect.any(Array)); - }); - - it('calls insert function with secure url', async () => { - await cloudinary.init({ handleInsert }); - cloudinaryInsertHandler({ assets: [asset] }); - expect(handleInsert).toHaveBeenCalledWith(asset.secure_url); - }); - - it('calls insert function with insecure url', async () => { - const options = { - use_secure_url: false, - }; - await cloudinary.init({ options, handleInsert }); - cloudinaryInsertHandler({ assets: [asset] }); - expect(handleInsert).toHaveBeenCalledWith(asset.url); - }); - - it('supports derived assets', async () => { - await cloudinary.init({ handleInsert }); - cloudinaryInsertHandler({ assets: [assetWithDerived] }); - expect(handleInsert).toHaveBeenCalledWith(assetWithDerived.derived[0].secure_url); - }); - - it('ignores derived assets when use_transformations is false', async () => { - const options = { - use_transformations: false, - }; - await cloudinary.init({ options, handleInsert }); - cloudinaryInsertHandler({ assets: [assetWithDerived] }); - expect(handleInsert).toHaveBeenCalledWith(assetWithDerived.secure_url); - }); - - it('supports outputting filename only', async () => { - const options = { - output_filename_only: true, - }; - await cloudinary.init({ options, handleInsert }); - cloudinaryInsertHandler({ assets: [asset] }); - expect(handleInsert.mock.calls[0][0]).toMatchInlineSnapshot(`"image.jpg"`); - }); - }); - - describe('show method', () => { - const defaultOptions = { - config: { - multiple: false, - }, - }; - - it('calls cloudinary instance show method with default options', async () => { - const integration = await cloudinary.init(); - integration.show(); - expect(mediaLibrary.show).toHaveBeenCalledWith(defaultOptions.config); - }); - - it('accepts unknown configuration keys', async () => { - const showOptions = { - config: { - ...defaultOptions.config, - foo: 'bar', - }, - }; - const integration = await cloudinary.init(); - integration.show(showOptions); - expect(mediaLibrary.show).toHaveBeenCalledWith(showOptions.config); - }); - - it('receives global configuration for behavior only', async () => { - const behaviorOptions = { - default_transformations: [{ foo: 'bar' }], - max_files: 2, - multiple: true, - }; - const nonBehaviorOptions = { - api_key: 123, - }; - const options = { - config: { - ...behaviorOptions, - ...nonBehaviorOptions, - }, - }; - const expectedOptions = { - config: behaviorOptions, - }; - const integration = await cloudinary.init({ options }); - integration.show(); - expect(mediaLibrary.show).toHaveBeenCalledWith(expectedOptions.config); - }); - - it('allows global/default configuration to be overridden', async () => { - const showOptions = { - config: { - multiple: true, - }, - }; - const integration = await cloudinary.init(); - integration.show(showOptions); - expect(mediaLibrary.show).toHaveBeenCalledWith(showOptions.config); - }); - - it('enforces multiple: false if allowMultiple is false', async () => { - const options = { - config: { - multiple: true, - }, - }; - const showOptions = { - config: { - multiple: true, - }, - allowMultiple: false, - }; - const expectedOptions = { - config: { - multiple: false, - }, - }; - const integration = await cloudinary.init(options); - integration.show(showOptions); - expect(mediaLibrary.show).toHaveBeenCalledWith(expectedOptions.config); - }); - }); - - describe('hide method', () => { - it('calls cloudinary instance hide method', async () => { - const integration = await cloudinary.init(); - integration.hide(); - expect(mediaLibrary.hide).toHaveBeenCalled(); - }); - }); - - describe('enableStandalone method', () => { - it('returns true', async () => { - const integration = await cloudinary.init(); - expect(integration.enableStandalone()).toEqual(true); - }); - }); -}); diff --git a/packages/netlify-cms-media-library-cloudinary/webpack.config.js b/packages/netlify-cms-media-library-cloudinary/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-media-library-cloudinary/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-media-library-uploadcare/CHANGELOG.md b/packages/netlify-cms-media-library-uploadcare/CHANGELOG.md deleted file mode 100644 index 1eaf78c1..00000000 --- a/packages/netlify-cms-media-library-uploadcare/CHANGELOG.md +++ /dev/null @@ -1,237 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [0.5.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.9...netlify-cms-media-library-uploadcare@0.5.10) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.8...netlify-cms-media-library-uploadcare@0.5.9) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## 0.5.8 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 0.5.7 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 0.5.6 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [0.5.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.4...netlify-cms-media-library-uploadcare@0.5.5) (2019-11-07) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.3...netlify-cms-media-library-uploadcare@0.5.4) (2019-09-26) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.2...netlify-cms-media-library-uploadcare@0.5.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.2-beta.0...netlify-cms-media-library-uploadcare@0.5.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.1...netlify-cms-media-library-uploadcare@0.5.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.1-beta.1...netlify-cms-media-library-uploadcare@0.5.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.5.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.1-beta.0...netlify-cms-media-library-uploadcare@0.5.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/6ffd13b)) - - - - - -## [0.5.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.5.0...netlify-cms-media-library-uploadcare@0.5.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -# [0.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.4.0...netlify-cms-media-library-uploadcare@0.5.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/d142b32)) - - - - - -# [0.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.4.0-beta.0...netlify-cms-media-library-uploadcare@0.4.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -# [0.4.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.5-beta.0...netlify-cms-media-library-uploadcare@0.4.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/82cc794)) - - - - - -## [0.3.5-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.4...netlify-cms-media-library-uploadcare@0.3.5-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/ccef446)) - - - - - -## [0.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.3...netlify-cms-media-library-uploadcare@0.3.4) (2019-02-26) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.2...netlify-cms-media-library-uploadcare@0.3.3) (2019-02-09) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.1...netlify-cms-media-library-uploadcare@0.3.2) (2019-02-08) - -**Note:** Version bump only for package netlify-cms-media-library-uploadcare - - - - - -## [0.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.3.0...netlify-cms-media-library-uploadcare@0.3.1) (2018-12-11) - - -### Bug Fixes - -* **media-library-uploadcare:** fix bugs, add tests ([#1953](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/1953)) ([716ee62](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/716ee62)) - - - - - -# [0.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.2.1...netlify-cms-media-library-uploadcare@0.3.0) (2018-12-04) - - -### Features - -* add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/1fc2f50)) - - - - - -## [0.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/compare/netlify-cms-media-library-uploadcare@0.2.0...netlify-cms-media-library-uploadcare@0.2.1) (2018-11-12) - - -### Bug Fixes - -* **uploadcare:** allow to be Uploadcare to be used in list widget ([#1774](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/1774)) ([deaac3d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/deaac3d)) - - - - - - -# 0.2.0 (2018-09-06) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/0596904)) - - - - - -# 0.2.0 (2018-09-06) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare/commit/0596904)) diff --git a/packages/netlify-cms-media-library-uploadcare/README.md b/packages/netlify-cms-media-library-uploadcare/README.md deleted file mode 100644 index d78b29c0..00000000 --- a/packages/netlify-cms-media-library-uploadcare/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-media-library-uploadcare/README.md)! diff --git a/packages/netlify-cms-media-library-uploadcare/package.json b/packages/netlify-cms-media-library-uploadcare/package.json deleted file mode 100644 index b84a7bfd..00000000 --- a/packages/netlify-cms-media-library-uploadcare/package.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "netlify-cms-media-library-uploadcare", - "description": "Uploadcare integration for Netlify CMS", - "version": "0.5.10", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-media-library-uploadcare", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-media-library-uploadcare.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "uploadcare", - "media", - "assets", - "files", - "uploads" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "uploadcare-widget": "^3.7.0", - "uploadcare-widget-tab-effects": "^1.4.0" - } -} diff --git a/packages/netlify-cms-media-library-uploadcare/src/__tests__/index.spec.js b/packages/netlify-cms-media-library-uploadcare/src/__tests__/index.spec.js deleted file mode 100644 index 14a8d26e..00000000 --- a/packages/netlify-cms-media-library-uploadcare/src/__tests__/index.spec.js +++ /dev/null @@ -1,290 +0,0 @@ -import uuid from 'uuid/v4'; -import uploadcare from 'uploadcare-widget'; -import uploadcareTabEffects from 'uploadcare-widget-tab-effects'; - -import uploadcareMediaLibrary from '../index'; - -function generateMockUrl({ count = 1, cdnUrl } = {}) { - const baseUrl = 'https://ucarecdn.com'; - const url = `${baseUrl}/${uuid()}~${count}/`; - const result = - count === 1 ? `${url}nth/0/` : Array.from({ length: count }, (val, idx) => `${url}nth/${idx}/`); - if (cdnUrl) { - return { result, cdnUrl: url }; - } - return result; -} - -let openDialogCallback; - -/** - * Mock of the uploadcare widget object itself. - */ -jest.mock('uploadcare-widget', () => ({ - registerTab: jest.fn(), - openDialog: jest.fn(() => ({ - done: jest.fn(cb => { - openDialogCallback = cb; - }), - })), - fileFrom: jest.fn((type, url) => - Promise.resolve({ - testFileUrl: url, - }), - ), - loadFileGroup: () => ({ - done: cb => cb(), - }), -})); - -describe('uploadcare media library', () => { - let handleInsert; - let simulateCloseDialog; - const TEST_PUBLIC_KEY = 123; - const defaultConfig = { - imagesOnly: false, - multiple: false, - previewStep: true, - integration: 'NetlifyCMS-Uploadcare-MediaLibrary', - }; - - beforeEach(() => { - /** - * Mock to manually call the close dialog registered callback. - */ - simulateCloseDialog = (result, files) => - openDialogCallback({ - promise: () => Promise.resolve(result), - ...(files ? { files: () => files.map(file => Promise.resolve(file)) } : {}), - }); - - /** - * Spy to serve as the Netlify CMS insertion handler. - */ - handleInsert = jest.fn(); - }); - - it('exports an object with expected properties', () => { - expect(uploadcareMediaLibrary).toMatchInlineSnapshot(` -Object { - "init": [Function], - "name": "uploadcare", -} -`); - }); - - describe('initialization', () => { - it('sets global required configuration', async () => { - const options = { - config: { - publicKey: TEST_PUBLIC_KEY, - }, - }; - await uploadcareMediaLibrary.init({ options }); - expect(window.UPLOADCARE_LIVE).toEqual(false); - expect(window.UPLOADCARE_MANUAL_START).toEqual(true); - expect(window.UPLOADCARE_PUBLIC_KEY).toEqual(TEST_PUBLIC_KEY); - }); - - it('registers the effects tab', async () => { - await uploadcareMediaLibrary.init(); - expect(uploadcare.registerTab).toHaveBeenCalledWith('preview', uploadcareTabEffects); - }); - }); - - describe('widget configuration', () => { - const options = { - config: { - foo: 'bar', - }, - }; - - it('has defaults', async () => { - const integration = await uploadcareMediaLibrary.init(); - await integration.show(); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, defaultConfig); - }); - - it('can be defined globally', async () => { - const expectedConfig = { - ...defaultConfig, - ...options.config, - }; - const integration = await uploadcareMediaLibrary.init({ options }); - await integration.show(); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, expectedConfig); - }); - - it('can be defined per field', async () => { - const expectedConfig = { - ...defaultConfig, - ...options.config, - }; - const integration = await uploadcareMediaLibrary.init(); - await integration.show({ config: options.config }); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, expectedConfig); - }); - }); - - describe('show method', () => { - const options = { - config: { - foo: 'bar', - }, - }; - - it('accepts imagesOnly as standalone property', async () => { - const expectedConfig = { - ...defaultConfig, - ...options.config, - imagesOnly: true, - }; - const integration = await uploadcareMediaLibrary.init(); - await integration.show({ config: options.config, imagesOnly: true }); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, expectedConfig); - }); - - it('allows multiple selection if allowMultiple is not false', async () => { - options.config.multiple = true; - const expectedConfig = { - ...defaultConfig, - ...options.config, - multiple: true, - }; - const integration = await uploadcareMediaLibrary.init({ options }); - await integration.show({ config: options.config }); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, expectedConfig); - }); - - it('disallows multiple selection if allowMultiple is false', async () => { - options.config.multiple = true; - const expectedConfig = { - ...defaultConfig, - ...options.config, - multiple: false, - }; - const integration = await uploadcareMediaLibrary.init({ options }); - await integration.show({ config: options.config, allowMultiple: false }); - expect(uploadcare.openDialog).toHaveBeenCalledWith(null, expectedConfig); - }); - - it('passes selected image url to handleInsert', async () => { - const url = generateMockUrl(); - const mockResult = { cdnUrl: url }; - const integration = await uploadcareMediaLibrary.init({ handleInsert }); - await integration.show(); - await simulateCloseDialog(mockResult); - expect(handleInsert).toHaveBeenCalledWith(url); - }); - - it('passes multiple selected image urls to handleInsert', async () => { - options.config.multiple = true; - const { result, cdnUrl } = generateMockUrl({ count: 3, cdnUrl: true }); - const mockDialogCloseResult = { cdnUrl, count: 3 }; - const mockDialogCloseFiles = result.map((cdnUrl, idx) => ({ - cdnUrl, - isImage: true, - name: `test${idx}.png`, - })); - const integration = await uploadcareMediaLibrary.init({ options, handleInsert }); - await integration.show(); - await simulateCloseDialog(mockDialogCloseResult, mockDialogCloseFiles); - expect(handleInsert).toHaveBeenCalledWith(result); - }); - }); - - describe('settings', () => { - describe('defaultOperations', () => { - it('should append specified string to the url', async () => { - const options = { - config: { - publicKey: TEST_PUBLIC_KEY, - }, - settings: { - defaultOperations: '/preview/', - }, - }; - const url = generateMockUrl(); - const mockResult = { cdnUrl: url, isImage: true }; - const integration = await uploadcareMediaLibrary.init({ - options, - handleInsert, - }); - await integration.show(); - await simulateCloseDialog(mockResult); - expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/'); - }); - - it('should work along with `autoFilename` setting enabled', async () => { - const options = { - config: { - publicKey: TEST_PUBLIC_KEY, - }, - settings: { - autoFilename: true, - defaultOperations: '/preview/', - }, - }; - const url = generateMockUrl(); - const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' }; - const integration = await uploadcareMediaLibrary.init({ - options, - handleInsert, - }); - await integration.show(); - await simulateCloseDialog(mockResult); - expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/test.png'); - }); - - it('should overwrite filename with `autoFilename` setting enabled', async () => { - const options = { - config: { - publicKey: TEST_PUBLIC_KEY, - }, - settings: { - autoFilename: true, - defaultOperations: '/preview/another_name.png', - }, - }; - const url = generateMockUrl(); - const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' }; - const integration = await uploadcareMediaLibrary.init({ - options, - handleInsert, - }); - await integration.show(); - await simulateCloseDialog(mockResult); - expect(handleInsert).toHaveBeenCalledWith(url + '-/preview/another_name.png'); - }); - }); - - describe('autoFilename', () => { - it('should append filename to the url', async () => { - const options = { - config: { - publicKey: TEST_PUBLIC_KEY, - }, - settings: { - autoFilename: true, - }, - }; - const url = generateMockUrl(); - const mockResult = { cdnUrl: url, isImage: true, name: 'test.png' }; - const integration = await uploadcareMediaLibrary.init({ - options, - handleInsert, - }); - await integration.show(); - await simulateCloseDialog(mockResult); - expect(handleInsert).toHaveBeenCalledWith(url + 'test.png'); - }); - }); - }); - - describe('enableStandalone method', () => { - it('returns false', async () => { - const integration = await uploadcareMediaLibrary.init(); - expect(integration.enableStandalone()).toEqual(false); - }); - }); -}); diff --git a/packages/netlify-cms-media-library-uploadcare/webpack.config.js b/packages/netlify-cms-media-library-uploadcare/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-media-library-uploadcare/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-proxy-server/.env.example b/packages/netlify-cms-proxy-server/.env.example deleted file mode 100644 index 029285dc..00000000 --- a/packages/netlify-cms-proxy-server/.env.example +++ /dev/null @@ -1,6 +0,0 @@ -# optional, defaults to current directory -GIT_REPO_DIRECTORY=FULL_PATH_TO_LOCAL_GIT_REPO -# optional, defaults to 8081 -PORT=CUSTOM_PORT -# optional, defaults to false -LOG_LEVEL=info \ No newline at end of file diff --git a/packages/netlify-cms-proxy-server/CHANGELOG.md b/packages/netlify-cms-proxy-server/CHANGELOG.md deleted file mode 100644 index aaa52e27..00000000 --- a/packages/netlify-cms-proxy-server/CHANGELOG.md +++ /dev/null @@ -1,452 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.3.26](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.25...netlify-cms-proxy-server@1.3.26) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.25](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.24...netlify-cms-proxy-server@1.3.25) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.24](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.23...netlify-cms-proxy-server@1.3.24) (2022-04-13) - - -### Bug Fixes - -* **deps:** update dependency simple-git to v3 [security] ([#6305](https://github.com/netlify/netlify-cms/issues/6305)) ([e997101](https://github.com/netlify/netlify-cms/commit/e99710116d015ca47b5cbe114710fdf93fabfe61)) - - - - - -## [1.3.23](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.22...netlify-cms-proxy-server@1.3.23) (2021-12-28) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.22](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.21...netlify-cms-proxy-server@1.3.22) (2021-11-01) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.21](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.20...netlify-cms-proxy-server@1.3.21) (2021-10-18) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.20](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.19...netlify-cms-proxy-server@1.3.20) (2021-08-17) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.19](https://github.com/netlify/netlify-cms/compare/netlify-cms-proxy-server@1.3.18...netlify-cms-proxy-server@1.3.19) (2021-07-14) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.18](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.17...netlify-cms-proxy-server@1.3.18) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.17](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.16...netlify-cms-proxy-server@1.3.17) (2021-05-31) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.15...netlify-cms-proxy-server@1.3.16) (2021-05-24) - - -### Bug Fixes - -* **deps:** update dependency dotenv to v10 ([#5433](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/5433)) ([1d44a5c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/1d44a5c0b94ab8512278ffc877f2daeeb8159593)) - - - - - -## [1.3.15](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.14...netlify-cms-proxy-server@1.3.15) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.14](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.13...netlify-cms-proxy-server@1.3.14) (2021-05-10) - - -### Bug Fixes - -* **deps:** update dependency dotenv to v9 ([#5361](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/5361)) ([3e65080](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/3e6508046f15672ca97cfe223ac9ea76b43121c9)) - - - - - -## [1.3.13](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.12...netlify-cms-proxy-server@1.3.13) (2021-04-29) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.12](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.11...netlify-cms-proxy-server@1.3.12) (2021-04-04) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.11](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.10...netlify-cms-proxy-server@1.3.11) (2021-02-15) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.9...netlify-cms-proxy-server@1.3.10) (2021-02-10) - - -### Bug Fixes - -* **deps:** update dependency async-mutex to ^0.3.0 ([#4932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/4932)) ([f608a81](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/f608a81f19681a4265ea8875ad50c585926c9113)) - - - - - -## [1.3.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.8...netlify-cms-proxy-server@1.3.9) (2021-02-01) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.7...netlify-cms-proxy-server@1.3.8) (2020-12-13) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.6...netlify-cms-proxy-server@1.3.7) (2020-11-26) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.5...netlify-cms-proxy-server@1.3.6) (2020-09-28) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.4...netlify-cms-proxy-server@1.3.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.3.3...netlify-cms-proxy-server@1.3.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## 1.3.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.3.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.3.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.9...netlify-cms-proxy-server@1.3.0) (2020-07-14) - - -### Bug Fixes - -* **proxy-server:** change request logging level to debug ([#3993](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3993)) ([784c1fe](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/784c1fe4801c89f1908d1b5e96cd7e847ec10fa0)) - - -### Features - -* **proxy-server:** allow setting proxy log level ([#3989](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3989)) ([3e0d088](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/3e0d0886d930a17c7b77d995cc0fa628ef3ecdc2)) - - - - - -## [1.2.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.8...netlify-cms-proxy-server@1.2.9) (2020-06-18) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.7...netlify-cms-proxy-server@1.2.8) (2020-06-01) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.6...netlify-cms-proxy-server@1.2.7) (2020-05-19) - - -### Bug Fixes - -* **deps:** update dependency simple-git to v2 ([#3730](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3730)) ([1c7ef1c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/1c7ef1c457612242257d96af53a57c1460e45b31)) - - - - - -## [1.2.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.5...netlify-cms-proxy-server@1.2.6) (2020-04-21) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.4...netlify-cms-proxy-server@1.2.5) (2020-04-14) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.3...netlify-cms-proxy-server@1.2.4) (2020-04-01) - - -### Bug Fixes - -* move common api functions to a separate file ([#3511](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3511)) ([49098de](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/49098de27f053e51aa3d936d09adae3a7186c6ae)) - - - - - -## [1.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.2...netlify-cms-proxy-server@1.2.3) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.1...netlify-cms-proxy-server@1.2.2) (2020-03-19) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.2.0...netlify-cms-proxy-server@1.2.1) (2020-03-12) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.5...netlify-cms-proxy-server@1.2.0) (2020-03-03) - - -### Features - -* **proxy-server:** export proxy middlewares ([#3361](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3361)) ([4e1e5a9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/4e1e5a9bd54f9fcfcfd7e971729c8d2d796f9a1b)) - - - - - -## [1.1.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.4...netlify-cms-proxy-server@1.1.5) (2020-02-25) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.1.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.3...netlify-cms-proxy-server@1.1.4) (2020-02-17) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.1.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.2...netlify-cms-proxy-server@1.1.3) (2020-02-14) - - -### Bug Fixes - -* **proxy-server:** add missing labels to file collections ([#3250](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3250)) ([8d67de0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/8d67de0e681e02ddbf811eecc5e4744b324b7e61)) - - - - - -## [1.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.1...netlify-cms-proxy-server@1.1.2) (2020-02-12) - - -### Bug Fixes - -* **proxy-server:** better handle files based collections ([#3237](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3237)) ([3678053](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/3678053f0c419718000a21768790618749df762c)) - - - - - -## [1.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.1.0...netlify-cms-proxy-server@1.1.1) (2020-02-11) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -# [1.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.7...netlify-cms-proxy-server@1.1.0) (2020-02-10) - - -### Bug Fixes - -* fs proxy info action ([#3225](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3225)) ([4522739](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/45227392315f4b8b7566ffe65756ca13dc55b9f8)) - - -### Features - -* **proxy-server:** add local fs middleware and make it the default ([#3217](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3217)) ([31dbd72](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/31dbd72273b723bb6bbb551641a6e4bcc1f0314b)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [1.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.6...netlify-cms-proxy-server@1.0.7) (2020-02-06) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.5...netlify-cms-proxy-server@1.0.6) (2020-01-30) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.4...netlify-cms-proxy-server@1.0.5) (2020-01-29) - - -### Bug Fixes - -* **proxy-server:** fix entriesByFiles implementation ([#3161](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/issues/3161)) ([22df7f7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/commit/22df7f7ae1c63d5275156c13202ee2cba8edfe30)) - - - - - -## [1.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.3...netlify-cms-proxy-server@1.0.4) (2020-01-26) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## [1.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server/compare/netlify-cms-proxy-server@1.0.2...netlify-cms-proxy-server@1.0.3) (2020-01-24) - -**Note:** Version bump only for package netlify-cms-proxy-server - - - - - -## 1.0.2 (2020-01-22) - -**Note:** Version bump only for package netlify-cms-proxy-server diff --git a/packages/netlify-cms-proxy-server/README.md b/packages/netlify-cms-proxy-server/README.md deleted file mode 100644 index bdcfc812..00000000 --- a/packages/netlify-cms-proxy-server/README.md +++ /dev/null @@ -1,30 +0,0 @@ -# Netlify CMS Proxy Server - -Netlify CMS Proxy Server is an express server created to facilitate local development. - -## How It Works - -1. Navigate to a local Git repository configured with the CMS. -2. Run `npx netlify-cms-proxy-server` from the root directory of the above repository. -3. Update your `config.yml` to connect to the server: - -```yaml -backend: - name: proxy - proxy_url: http://localhost:8081/api/v1 - branch: master # optional, defaults to master -``` - -4. Start you local development server (e.g. run `gatsby develop`). - -## Custom Configuration - -1. Create a `.env` file in the root directory of your local Git repository. -2. Update the file as follows: - -```bash -# optional, defaults to current directory -GIT_REPO_DIRECTORY=FULL_PATH_TO_LOCAL_GIT_REPO -# optional, defaults to 8081 -PORT=CUSTOM_PORT -``` diff --git a/packages/netlify-cms-proxy-server/jest.config.js b/packages/netlify-cms-proxy-server/jest.config.js deleted file mode 100644 index b8782949..00000000 --- a/packages/netlify-cms-proxy-server/jest.config.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - preset: 'ts-jest', - testEnvironment: 'node', - moduleNameMapper: { - 'netlify-cms-lib-util': '/../netlify-cms-lib-util/dist/esm', - }, -}; diff --git a/packages/netlify-cms-proxy-server/package.json b/packages/netlify-cms-proxy-server/package.json deleted file mode 100644 index 1993c787..00000000 --- a/packages/netlify-cms-proxy-server/package.json +++ /dev/null @@ -1,59 +0,0 @@ -{ - "name": "netlify-cms-proxy-server", - "description": "Proxy server to be used with Netlify CMS proxy backend", - "version": "1.3.26", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-proxy-server", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "main": "dist/index", - "keywords": [ - "netlify", - "netlify-cms", - "backend" - ], - "sideEffects": false, - "scripts": { - "build": "webpack", - "prestart": "yarn build", - "start": "node dist/index.js", - "develop": "nodemon --watch 'src/**/*.ts' --ignore 'src/**/*.spec.ts' --exec 'ts-node' --files src/index.ts", - "test": "jest", - "test:watch": "yarn test --watch", - "test:coverage": "yarn test --coverage" - }, - "dependencies": { - "@hapi/joi": "^17.0.2", - "async-mutex": "^0.3.0", - "cors": "^2.8.5", - "dotenv": "^10.0.0", - "express": "^4.17.1", - "morgan": "^1.9.1", - "simple-git": "^3.0.0", - "what-the-diff": "^0.6.0", - "winston": "^3.3.3" - }, - "devDependencies": { - "@types/cors": "^2.8.6", - "@types/express": "^4.17.8", - "@types/hapi__joi": "17.1.8", - "@types/jest": "^27.0.0", - "@types/morgan": "^1.7.37", - "@types/node": "^16.0.0", - "@types/vfile-message": "^2.0.0", - "jest": "^27.0.0", - "netlify-cms-lib-util": "^2.15.3", - "nodemon": "^2.0.2", - "ts-jest": "^27.0.0", - "ts-loader": "^8.0.0", - "ts-node": "^10.0.0", - "tsconfig-paths-webpack-plugin": "^3.2.0", - "webpack": "^4.41.5", - "webpack-node-externals": "^3.0.0" - }, - "engines": { - "node": ">=v10.22.1" - }, - "bin": { - "netlify-cms-proxy-server": "./dist/index.js" - } -} diff --git a/packages/netlify-cms-proxy-server/src/global.d.ts b/packages/netlify-cms-proxy-server/src/global.d.ts deleted file mode 100644 index 23843f26..00000000 --- a/packages/netlify-cms-proxy-server/src/global.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -type LocalForage = { - getItem: (key: string) => Promise; - setItem: (key: string, value: T) => Promise; -}; diff --git a/packages/netlify-cms-proxy-server/src/index.ts b/packages/netlify-cms-proxy-server/src/index.ts deleted file mode 100644 index 136075de..00000000 --- a/packages/netlify-cms-proxy-server/src/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -// eslint-disable-next-line @typescript-eslint/no-var-requires -require('dotenv').config(); -import express from 'express'; - -import { registerCommonMiddlewares } from './middlewares/common'; -import { registerMiddleware as registerLocalGit } from './middlewares/localGit'; -import { registerMiddleware as registerLocalFs } from './middlewares/localFs'; -import { createLogger } from './logger'; - -const app = express(); -const port = process.env.PORT || 8081; -const level = process.env.LOG_LEVEL || 'info'; - -(async () => { - const logger = createLogger({ level }); - const options = { - logger, - }; - - registerCommonMiddlewares(app, options); - - try { - const mode = process.env.MODE || 'fs'; - if (mode === 'fs') { - registerLocalFs(app, options); - } else if (mode === 'git') { - registerLocalGit(app, options); - } else { - throw new Error(`Unknown proxy mode '${mode}'`); - } - } catch (e) { - logger.error(e.message); - process.exit(1); - } - - return app.listen(port, () => { - logger.info(`Netlify CMS Proxy Server listening on port ${port}`); - }); -})(); diff --git a/packages/netlify-cms-proxy-server/src/logger.ts b/packages/netlify-cms-proxy-server/src/logger.ts deleted file mode 100644 index b92fc710..00000000 --- a/packages/netlify-cms-proxy-server/src/logger.ts +++ /dev/null @@ -1,15 +0,0 @@ -import winston from 'winston'; - -const { combine, colorize, simple } = winston.format; - -type LogOptions = { - level: string; -}; - -export function createLogger({ level }: LogOptions) { - return winston.createLogger({ - level, - format: combine(colorize(), simple()), - transports: [new winston.transports.Console()], - }); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares.ts b/packages/netlify-cms-proxy-server/src/middlewares.ts deleted file mode 100644 index bae15c9a..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { registerCommonMiddlewares } from './middlewares/common'; -import { registerMiddleware as localGit } from './middlewares/localGit'; -import { registerMiddleware as localFs } from './middlewares/localFs'; -import { createLogger } from './logger'; - -import type express from 'express'; - -type Options = { - logLevel?: string; -}; - -function createOptions(options: Options) { - return { - logger: createLogger({ level: options.logLevel || 'info' }), - }; -} - -export async function registerLocalGit(app: express.Express, options: Options = {}) { - const opts = createOptions(options); - registerCommonMiddlewares(app, opts); - await localGit(app, opts); -} - -export async function registerLocalFs(app: express.Express, options: Options = {}) { - const opts = createOptions(options); - registerCommonMiddlewares(app, opts); - await localFs(app, opts); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/common/index.ts b/packages/netlify-cms-proxy-server/src/middlewares/common/index.ts deleted file mode 100644 index 18ec4c46..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/common/index.ts +++ /dev/null @@ -1,21 +0,0 @@ -import express from 'express'; -import morgan from 'morgan'; -import cors from 'cors'; - -import type winston from 'winston'; - -export type Options = { - logger: winston.Logger; -}; - -export function registerCommonMiddlewares(app: express.Express, options: Options) { - const { logger } = options; - const stream = { - write: (message: string) => { - logger.debug(String(message).trim()); - }, - }; - app.use(morgan('combined', { stream })); - app.use(cors()); - app.use(express.json({ limit: '50mb' })); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/joi/customValidators.ts b/packages/netlify-cms-proxy-server/src/middlewares/joi/customValidators.ts deleted file mode 100644 index bd12253c..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/joi/customValidators.ts +++ /dev/null @@ -1,18 +0,0 @@ -import Joi from '@hapi/joi'; -import path from 'path'; - -export function pathTraversal(repoPath: string) { - return Joi.extend({ - type: 'path', - base: Joi.string().required(), - messages: { - 'path.invalid': '{{#label}} must resolve to a path under the configured repository', - }, - validate(value, helpers) { - const resolvedPath = path.join(repoPath, value); - if (!resolvedPath.startsWith(repoPath)) { - return { value, errors: helpers.error('path.invalid') }; - } - }, - }).path(); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/joi/index.spec.ts b/packages/netlify-cms-proxy-server/src/middlewares/joi/index.spec.ts deleted file mode 100644 index 174789dc..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/joi/index.spec.ts +++ /dev/null @@ -1,617 +0,0 @@ -import { defaultSchema, joi } from '.'; - -import type express from 'express'; -import type Joi from '@hapi/joi'; - -function assetFailure(result: Joi.ValidationResult, expectedMessage: string) { - const { error } = result; - expect(error).not.toBeNull(); - expect(error!.details).toHaveLength(1); - const message = error!.details.map(({ message }) => message)[0]; - expect(message).toBe(expectedMessage); -} - -const defaultParams = { - branch: 'master', -}; - -describe('defaultSchema', () => { - it('should fail on unsupported body', () => { - const schema = defaultSchema(); - - assetFailure(schema.validate({}), '"action" is required'); - }); - - it('should fail on unsupported action', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'unknown', params: {} }), - '"action" must be one of [info, entriesByFolder, entriesByFiles, getEntry, unpublishedEntries, unpublishedEntry, unpublishedEntryDataFile, unpublishedEntryMediaFile, deleteUnpublishedEntry, persistEntry, updateUnpublishedEntryStatus, publishUnpublishedEntry, getMedia, getMediaFile, persistMedia, deleteFile, deleteFiles, getDeployPreview]', - ); - }); - - describe('info', () => { - it('should pass with no params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'info', - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('entriesByFolder', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'entriesByFolder', params: { ...defaultParams } }), - '"params.folder" is required', - ); - assetFailure( - schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: 'folder' }, - }), - '"params.extension" is required', - ); - assetFailure( - schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: 'folder', extension: 'md' }, - }), - '"params.depth" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: 'folder', extension: 'md', depth: 1 }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('entriesByFiles', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'entriesByFiles', params: { ...defaultParams } }), - '"params.files" is required', - ); - assetFailure( - schema.validate({ action: 'entriesByFiles', params: { ...defaultParams, files: {} } }), - '"params.files" must be an array', - ); - assetFailure( - schema.validate({ - action: 'entriesByFiles', - params: { ...defaultParams, files: [{ id: 'id' }] }, - }), - '"params.files[0].path" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'entriesByFiles', - params: { ...defaultParams, files: [{ path: 'path' }] }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('getEntry', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'getEntry', params: { ...defaultParams } }), - '"params.path" is required', - ); - assetFailure( - schema.validate({ action: 'getEntry', params: { ...defaultParams, path: 1 } }), - '"params.path" must be a string', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'getEntry', - params: { ...defaultParams, path: 'path' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('unpublishedEntries', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'unpublishedEntries', params: {} }), - '"params.branch" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'unpublishedEntries', - params: { ...defaultParams, branch: 'master' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('unpublishedEntry', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - assetFailure( - schema.validate({ action: 'unpublishedEntry', params: {} }), - '"params.branch" is required', - ); - }); - - it('should pass on valid collection and slug', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'unpublishedEntry', - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }); - - expect(error).toBeUndefined(); - }); - - it('should pass on valid id', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'unpublishedEntry', - params: { ...defaultParams, id: 'id' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - ['unpublishedEntryDataFile', 'unpublishedEntryMediaFile'].forEach(action => { - describe(action, () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action, params: { ...defaultParams } }), - '"params.collection" is required', - ); - assetFailure( - schema.validate({ - action, - params: { ...defaultParams, collection: 'collection' }, - }), - '"params.slug" is required', - ); - assetFailure( - schema.validate({ - action, - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }), - '"params.id" is required', - ); - assetFailure( - schema.validate({ - action, - params: { ...defaultParams, collection: 'collection', slug: 'slug', id: 'id' }, - }), - '"params.path" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action, - params: { - ...defaultParams, - collection: 'collection', - slug: 'slug', - id: 'id', - path: 'path', - }, - }); - - expect(error).toBeUndefined(); - }); - }); - }); - - describe('deleteUnpublishedEntry', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'deleteUnpublishedEntry', params: { ...defaultParams } }), - '"params.collection" is required', - ); - assetFailure( - schema.validate({ - action: 'deleteUnpublishedEntry', - params: { ...defaultParams, collection: 'collection' }, - }), - '"params.slug" is required', - ); - assetFailure( - schema.validate({ - action: 'deleteUnpublishedEntry', - params: { ...defaultParams, collection: 'collection', slug: 1 }, - }), - '"params.slug" must be a string', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'deleteUnpublishedEntry', - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('persistEntry', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ - action: 'persistEntry', - params: { - ...defaultParams, - assets: [], - options: { - commitMessage: 'commitMessage', - useWorkflow: true, - status: 'draft', - }, - }, - }), - '"params" must contain at least one of [entry, dataFiles]', - ); - assetFailure( - schema.validate({ - action: 'persistEntry', - params: { ...defaultParams, entry: { slug: 'slug', path: 'path', raw: 'content' } }, - }), - '"params.assets" is required', - ); - assetFailure( - schema.validate({ - action: 'persistEntry', - params: { - ...defaultParams, - entry: { slug: 'slug', path: 'path', raw: 'content' }, - assets: [], - }, - }), - '"params.options" is required', - ); - assetFailure( - schema.validate({ - action: 'persistEntry', - params: { - ...defaultParams, - entry: { slug: 'slug', path: 'path', raw: 'content' }, - assets: [], - options: {}, - }, - }), - '"params.options.commitMessage" is required', - ); - }); - - it('should pass on valid params (entry argument)', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'persistEntry', - params: { - ...defaultParams, - entry: { slug: 'slug', path: 'path', raw: 'content' }, - assets: [{ path: 'path', content: 'content', encoding: 'base64' }], - options: { - commitMessage: 'commitMessage', - useWorkflow: true, - status: 'draft', - }, - }, - }); - - expect(error).toBeUndefined(); - }); - - it('should pass on valid params (dataFiles argument)', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'persistEntry', - params: { - ...defaultParams, - dataFiles: [{ slug: 'slug', path: 'path', raw: 'content' }], - assets: [{ path: 'path', content: 'content', encoding: 'base64' }], - options: { - commitMessage: 'commitMessage', - useWorkflow: true, - status: 'draft', - }, - }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('updateUnpublishedEntryStatus', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'updateUnpublishedEntryStatus', params: { ...defaultParams } }), - '"params.collection" is required', - ); - assetFailure( - schema.validate({ - action: 'updateUnpublishedEntryStatus', - params: { ...defaultParams, collection: 'collection' }, - }), - '"params.slug" is required', - ); - assetFailure( - schema.validate({ - action: 'updateUnpublishedEntryStatus', - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }), - '"params.newStatus" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'updateUnpublishedEntryStatus', - params: { ...defaultParams, collection: 'collection', slug: 'slug', newStatus: 'draft' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('publishUnpublishedEntry', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'publishUnpublishedEntry', params: { ...defaultParams } }), - '"params.collection" is required', - ); - assetFailure( - schema.validate({ - action: 'publishUnpublishedEntry', - params: { ...defaultParams, collection: 'collection' }, - }), - '"params.slug" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'publishUnpublishedEntry', - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('getMedia', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'getMedia', params: { ...defaultParams } }), - '"params.mediaFolder" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'getMedia', - params: { ...defaultParams, mediaFolder: 'src/static/images' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('getMediaFile', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'getMediaFile', params: { ...defaultParams } }), - '"params.path" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'getMediaFile', - params: { ...defaultParams, path: 'src/static/images/image.png' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('persistMedia', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'persistMedia', params: { ...defaultParams } }), - '"params.asset" is required', - ); - assetFailure( - schema.validate({ - action: 'persistMedia', - params: { ...defaultParams, asset: { path: 'path' } }, - }), - '"params.asset.content" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'persistMedia', - params: { - ...defaultParams, - asset: { path: 'path', content: 'content', encoding: 'base64' }, - options: { commitMessage: 'commitMessage' }, - }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('deleteFile', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'deleteFile', params: { ...defaultParams } }), - '"params.path" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'deleteFile', - params: { - ...defaultParams, - path: 'src/static/images/image.png', - options: { commitMessage: 'commitMessage' }, - }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('deleteFiles', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'deleteFiles', params: { ...defaultParams } }), - '"params.paths" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'deleteFiles', - params: { - ...defaultParams, - paths: ['src/static/images/image.png'], - options: { commitMessage: 'commitMessage' }, - }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('getDeployPreview', () => { - it('should fail on invalid params', () => { - const schema = defaultSchema(); - - assetFailure( - schema.validate({ action: 'getDeployPreview', params: { ...defaultParams } }), - '"params.collection" is required', - ); - assetFailure( - schema.validate({ - action: 'getDeployPreview', - params: { ...defaultParams, collection: 'collection' }, - }), - '"params.slug" is required', - ); - }); - - it('should pass on valid params', () => { - const schema = defaultSchema(); - const { error } = schema.validate({ - action: 'getDeployPreview', - params: { ...defaultParams, collection: 'collection', slug: 'slug' }, - }); - - expect(error).toBeUndefined(); - }); - }); -}); - -describe('joi', () => { - it('should call next on valid schema', () => { - const next = jest.fn(); - - const req = { - body: { - action: 'entriesByFolder', - params: { branch: 'master', folder: 'folder', extension: 'md', depth: 1 }, - }, - } as express.Request; - const res: express.Response = {} as express.Response; - joi(defaultSchema())(req, res, next); - - expect(next).toHaveBeenCalledTimes(1); - }); - - it('should send error on invalid schema', () => { - const next = jest.fn(); - - const req = { - body: { - action: 'entriesByFolder', - }, - } as express.Request; - const json = jest.fn(); - const status = jest.fn(() => ({ json })); - const res: express.Response = { status } as unknown as express.Response; - - joi(defaultSchema())(req, res, next); - - expect(next).toHaveBeenCalledTimes(0); - - expect(status).toHaveBeenCalledTimes(1); - expect(json).toHaveBeenCalledTimes(1); - - expect(status).toHaveBeenCalledWith(422); - expect(json).toHaveBeenCalledWith({ error: '"params" is required' }); - }); -}); diff --git a/packages/netlify-cms-proxy-server/src/middlewares/joi/index.ts b/packages/netlify-cms-proxy-server/src/middlewares/joi/index.ts deleted file mode 100644 index 430816bc..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/joi/index.ts +++ /dev/null @@ -1,246 +0,0 @@ -import Joi from '@hapi/joi'; - -import type express from 'express'; - -const allowedActions = [ - 'info', - 'entriesByFolder', - 'entriesByFiles', - 'getEntry', - 'unpublishedEntries', - 'unpublishedEntry', - 'unpublishedEntryDataFile', - 'unpublishedEntryMediaFile', - 'deleteUnpublishedEntry', - 'persistEntry', - 'updateUnpublishedEntryStatus', - 'publishUnpublishedEntry', - 'getMedia', - 'getMediaFile', - 'persistMedia', - 'deleteFile', - 'deleteFiles', - 'getDeployPreview', -]; - -const requiredString = Joi.string().required(); -const requiredNumber = Joi.number().required(); -const requiredBool = Joi.bool().required(); - -const collection = requiredString; -const slug = requiredString; - -export function defaultSchema({ path = requiredString } = {}) { - const defaultParams = Joi.object({ - branch: requiredString, - }); - - const asset = Joi.object({ - path, - content: requiredString, - encoding: requiredString.valid('base64'), - }); - - const dataFile = Joi.object({ - slug: requiredString, - path, - raw: requiredString, - newPath: path.optional(), - }); - - const params = Joi.when('action', { - switch: [ - { - is: 'info', - then: Joi.allow(), - }, - { - is: 'entriesByFolder', - then: defaultParams - .keys({ - folder: path, - extension: requiredString, - depth: requiredNumber, - }) - .required(), - }, - { - is: 'entriesByFiles', - then: defaultParams.keys({ - files: Joi.array() - .items(Joi.object({ path, label: Joi.string() })) - .required(), - }), - }, - { - is: 'getEntry', - then: defaultParams - .keys({ - path, - }) - .required(), - }, - { - is: 'unpublishedEntries', - then: defaultParams.keys({ branch: requiredString }).required(), - }, - { - is: 'unpublishedEntry', - then: defaultParams - .keys({ - id: Joi.string().optional(), - collection: Joi.string().optional(), - slug: Joi.string().optional(), - cmsLabelPrefix: Joi.string().optional(), - }) - .required(), - }, - { - is: 'unpublishedEntryDataFile', - then: defaultParams - .keys({ - collection, - slug, - id: requiredString, - path: requiredString, - }) - .required(), - }, - { - is: 'unpublishedEntryMediaFile', - then: defaultParams - .keys({ - collection, - slug, - id: requiredString, - path: requiredString, - }) - .required(), - }, - { - is: 'deleteUnpublishedEntry', - then: defaultParams - .keys({ - collection, - slug, - }) - .required(), - }, - { - is: 'persistEntry', - then: defaultParams - .keys({ - cmsLabelPrefix: Joi.string().optional(), - entry: dataFile, // entry is kept for backwards compatibility - dataFiles: Joi.array().items(dataFile), - assets: Joi.array().items(asset).required(), - options: Joi.object({ - collectionName: Joi.string(), - commitMessage: requiredString, - useWorkflow: requiredBool, - status: requiredString, - }).required(), - }) - .xor('entry', 'dataFiles') - .required(), - }, - { - is: 'updateUnpublishedEntryStatus', - then: defaultParams - .keys({ - collection, - slug, - newStatus: requiredString, - cmsLabelPrefix: Joi.string().optional(), - }) - .required(), - }, - { - is: 'publishUnpublishedEntry', - then: defaultParams - .keys({ - collection, - slug, - }) - .required(), - }, - { - is: 'getMedia', - then: defaultParams - .keys({ - mediaFolder: path, - }) - .required(), - }, - { - is: 'getMediaFile', - then: defaultParams - .keys({ - path, - }) - .required(), - }, - { - is: 'persistMedia', - then: defaultParams - .keys({ - asset: asset.required(), - options: Joi.object({ - commitMessage: requiredString, - }).required(), - }) - .required(), - }, - { - is: 'deleteFile', - then: defaultParams - .keys({ - path, - options: Joi.object({ - commitMessage: requiredString, - }).required(), - }) - .required(), - }, - { - is: 'deleteFiles', - then: defaultParams - .keys({ - paths: Joi.array().items(path).min(1).required(), - options: Joi.object({ - commitMessage: requiredString, - }).required(), - }) - .required(), - }, - { - is: 'getDeployPreview', - then: defaultParams - .keys({ - collection, - slug, - }) - .required(), - }, - ], - otherwise: Joi.forbidden(), - }); - - return Joi.object({ - action: Joi.valid(...allowedActions).required(), - params, - }); -} - -export function joi(schema: Joi.Schema) { - return (req: express.Request, res: express.Response, next: express.NextFunction) => { - const { error } = schema.validate(req.body, { allowUnknown: true }); - if (error) { - const { details } = error; - const message = details.map(i => i.message).join(','); - res.status(422).json({ error: message }); - } else { - next(); - } - }; -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.spec.ts b/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.spec.ts deleted file mode 100644 index e04a9e51..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.spec.ts +++ /dev/null @@ -1,92 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -import { getSchema } from '.'; - -import type Joi from '@hapi/joi'; - -function assetFailure(result: Joi.ValidationResult, expectedMessage: string) { - const { error } = result; - expect(error).not.toBeNull(); - expect(error!.details).toHaveLength(1); - const message = error!.details.map(({ message }) => message)[0]; - expect(message).toBe(expectedMessage); -} - -const defaultParams = { - branch: 'master', -}; - -describe('localFsMiddleware', () => { - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('getSchema', () => { - it('should throw on path traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'getEntry', - params: { ...defaultParams, path: '../' }, - }), - '"params.path" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid path', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - const { error } = schema.validate({ - action: 'getEntry', - params: { ...defaultParams, path: 'src/content/posts/title.md' }, - }); - - expect(error).toBeUndefined(); - }); - - it('should throw on folder traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: '../', extension: 'md', depth: 1 }, - }), - '"params.folder" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid folder', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - const { error } = schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: 'src/posts', extension: 'md', depth: 1 }, - }); - - expect(error).toBeUndefined(); - }); - - it('should throw on media folder traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'getMedia', - params: { ...defaultParams, mediaFolder: '../' }, - }), - '"params.mediaFolder" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid folder', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - const { error } = schema.validate({ - action: 'getMedia', - params: { ...defaultParams, mediaFolder: 'static/images' }, - }); - - expect(error).toBeUndefined(); - }); - }); -}); diff --git a/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.ts b/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.ts deleted file mode 100644 index 1a608483..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/localFs/index.ts +++ /dev/null @@ -1,159 +0,0 @@ -import path from 'path'; - -import { defaultSchema, joi } from '../joi'; -import { pathTraversal } from '../joi/customValidators'; -import { listRepoFiles, deleteFile, writeFile, move } from '../utils/fs'; -import { entriesFromFiles, readMediaFile } from '../utils/entries'; - -import type { - EntriesByFolderParams, - EntriesByFilesParams, - GetEntryParams, - PersistEntryParams, - GetMediaParams, - GetMediaFileParams, - PersistMediaParams, - DeleteFileParams, - DeleteFilesParams, - DataFile, -} from '../types'; -import type express from 'express'; -import type winston from 'winston'; - -type FsOptions = { - repoPath: string; - logger: winston.Logger; -}; - -export function localFsMiddleware({ repoPath, logger }: FsOptions) { - return async function (req: express.Request, res: express.Response) { - try { - const { body } = req; - - switch (body.action) { - case 'info': { - res.json({ - repo: path.basename(repoPath), - publish_modes: ['simple'], - type: 'local_fs', - }); - break; - } - case 'entriesByFolder': { - const payload = body.params as EntriesByFolderParams; - const { folder, extension, depth } = payload; - const entries = await listRepoFiles(repoPath, folder, extension, depth).then(files => - entriesFromFiles( - repoPath, - files.map(file => ({ path: file })), - ), - ); - res.json(entries); - break; - } - case 'entriesByFiles': { - const payload = body.params as EntriesByFilesParams; - const entries = await entriesFromFiles(repoPath, payload.files); - res.json(entries); - break; - } - case 'getEntry': { - const payload = body.params as GetEntryParams; - const [entry] = await entriesFromFiles(repoPath, [{ path: payload.path }]); - res.json(entry); - break; - } - case 'persistEntry': { - const { - entry, - dataFiles = [entry as DataFile], - assets, - } = body.params as PersistEntryParams; - await Promise.all( - dataFiles.map(dataFile => writeFile(path.join(repoPath, dataFile.path), dataFile.raw)), - ); - // save assets - await Promise.all( - assets.map(a => - writeFile(path.join(repoPath, a.path), Buffer.from(a.content, a.encoding)), - ), - ); - if (dataFiles.every(dataFile => dataFile.newPath)) { - dataFiles.forEach(async dataFile => { - await move( - path.join(repoPath, dataFile.path), - path.join(repoPath, dataFile.newPath!), - ); - }); - } - res.json({ message: 'entry persisted' }); - break; - } - case 'getMedia': { - const { mediaFolder } = body.params as GetMediaParams; - const files = await listRepoFiles(repoPath, mediaFolder, '', 1); - const mediaFiles = await Promise.all(files.map(file => readMediaFile(repoPath, file))); - res.json(mediaFiles); - break; - } - case 'getMediaFile': { - const { path } = body.params as GetMediaFileParams; - const mediaFile = await readMediaFile(repoPath, path); - res.json(mediaFile); - break; - } - case 'persistMedia': { - const { asset } = body.params as PersistMediaParams; - await writeFile( - path.join(repoPath, asset.path), - Buffer.from(asset.content, asset.encoding), - ); - const file = await readMediaFile(repoPath, asset.path); - res.json(file); - break; - } - case 'deleteFile': { - const { path: filePath } = body.params as DeleteFileParams; - await deleteFile(repoPath, filePath); - res.json({ message: `deleted file ${filePath}` }); - break; - } - case 'deleteFiles': { - const { paths } = body.params as DeleteFilesParams; - await Promise.all(paths.map(filePath => deleteFile(repoPath, filePath))); - res.json({ message: `deleted files ${paths.join(', ')}` }); - break; - } - case 'getDeployPreview': { - res.json(null); - break; - } - default: { - const message = `Unknown action ${body.action}`; - res.status(422).json({ error: message }); - break; - } - } - } catch (e) { - logger.error(`Error handling ${JSON.stringify(req.body)}: ${e.message}`); - res.status(500).json({ error: 'Unknown error' }); - } - }; -} - -export function getSchema({ repoPath }: { repoPath: string }) { - const schema = defaultSchema({ path: pathTraversal(repoPath) }); - return schema; -} - -type Options = { - logger: winston.Logger; -}; - -export async function registerMiddleware(app: express.Express, options: Options) { - const { logger } = options; - const repoPath = path.resolve(process.env.GIT_REPO_DIRECTORY || process.cwd()); - app.post('/api/v1', joi(getSchema({ repoPath }))); - app.post('/api/v1', localFsMiddleware({ repoPath, logger })); - logger.info(`Netlify CMS File System Proxy Server configured with ${repoPath}`); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.spec.ts b/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.spec.ts deleted file mode 100644 index c1345761..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.spec.ts +++ /dev/null @@ -1,154 +0,0 @@ -/* eslint-disable @typescript-eslint/no-var-requires */ -import winston from 'winston'; - -import { validateRepo, getSchema, localGitMiddleware } from '.'; - -import type Joi from '@hapi/joi'; -import type express from 'express'; - -jest.mock('netlify-cms-lib-util', () => jest.fn()); -jest.mock('simple-git'); - -function assetFailure(result: Joi.ValidationResult, expectedMessage: string) { - const { error } = result; - expect(error).not.toBeNull(); - expect(error!.details).toHaveLength(1); - const message = error!.details.map(({ message }) => message)[0]; - expect(message).toBe(expectedMessage); -} - -const defaultParams = { - branch: 'master', -}; - -describe('localGitMiddleware', () => { - const simpleGit = require('simple-git'); - - const git = { - checkIsRepo: jest.fn(), - silent: jest.fn(), - branchLocal: jest.fn(), - checkout: jest.fn(), - }; - git.silent.mockReturnValue(git); - - simpleGit.mockReturnValue(git); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - describe('validateRepo', () => { - it('should throw on non valid git repo', async () => { - git.checkIsRepo.mockResolvedValue(false); - await expect(validateRepo({ repoPath: '/Users/user/code/repo' })).rejects.toEqual( - new Error('/Users/user/code/repo is not a valid git repository'), - ); - }); - - it('should not throw on valid git repo', async () => { - git.checkIsRepo.mockResolvedValue(true); - await expect(validateRepo({ repoPath: '/Users/user/code/repo' })).resolves.toBeUndefined(); - }); - }); - - describe('getSchema', () => { - it('should throw on path traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'getEntry', - params: { ...defaultParams, path: '../' }, - }), - '"params.path" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid path', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - const { error } = schema.validate({ - action: 'getEntry', - params: { ...defaultParams, path: 'src/content/posts/title.md' }, - }); - - expect(error).toBeUndefined(); - }); - - it('should throw on folder traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: '../', extension: 'md', depth: 1 }, - }), - '"params.folder" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid folder', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - const { error } = schema.validate({ - action: 'entriesByFolder', - params: { ...defaultParams, folder: 'src/posts', extension: 'md', depth: 1 }, - }); - - expect(error).toBeUndefined(); - }); - - it('should throw on media folder traversal', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - - assetFailure( - schema.validate({ - action: 'getMedia', - params: { ...defaultParams, mediaFolder: '../' }, - }), - '"params.mediaFolder" must resolve to a path under the configured repository', - ); - }); - - it('should not throw on valid folder', () => { - const schema = getSchema({ repoPath: '/Users/user/documents/code/repo' }); - const { error } = schema.validate({ - action: 'getMedia', - params: { ...defaultParams, mediaFolder: 'static/images' }, - }); - - expect(error).toBeUndefined(); - }); - }); - - describe('localGitMiddleware', () => { - const json = jest.fn(); - const status = jest.fn(() => ({ json })); - const res: express.Response = { status } as unknown as express.Response; - - const repoPath = '.'; - - it("should return error when default branch doesn't exist", async () => { - git.branchLocal.mockResolvedValue({ all: ['master'] }); - - const req = { - body: { - action: 'getMedia', - params: { - mediaFolder: 'mediaFolder', - branch: 'develop', - }, - }, - } as express.Request; - - await localGitMiddleware({ repoPath, logger: winston.createLogger() })(req, res); - - expect(status).toHaveBeenCalledTimes(1); - expect(status).toHaveBeenCalledWith(422); - - expect(json).toHaveBeenCalledTimes(1); - expect(json).toHaveBeenCalledWith({ error: "Default branch 'develop' doesn't exist" }); - }); - }); -}); diff --git a/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.ts b/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.ts deleted file mode 100644 index a6c7a1b3..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/localGit/index.ts +++ /dev/null @@ -1,458 +0,0 @@ -import path from 'path'; -import { promises as fs } from 'fs'; -import { - branchFromContentKey, - generateContentKey, - contentKeyFromBranch, - CMS_BRANCH_PREFIX, - statusToLabel, - labelToStatus, - parseContentKey, -} from 'netlify-cms-lib-util/src/APIUtils'; -import { parse } from 'what-the-diff'; -import simpleGit from 'simple-git'; -import { Mutex, withTimeout } from 'async-mutex'; - -import { defaultSchema, joi } from '../joi'; -import { pathTraversal } from '../joi/customValidators'; -import { listRepoFiles, writeFile, move, deleteFile, getUpdateDate } from '../utils/fs'; -import { entriesFromFiles, readMediaFile } from '../utils/entries'; - -import type { - EntriesByFolderParams, - EntriesByFilesParams, - GetEntryParams, - DefaultParams, - UnpublishedEntryParams, - PersistEntryParams, - GetMediaParams, - Asset, - PublishUnpublishedEntryParams, - PersistMediaParams, - DeleteFileParams, - UpdateUnpublishedEntryStatusParams, - DataFile, - GetMediaFileParams, - DeleteEntryParams, - DeleteFilesParams, - UnpublishedEntryDataFileParams, - UnpublishedEntryMediaFileParams, -} from '../types'; -import type express from 'express'; -import type winston from 'winston'; -import type { SimpleGit } from 'simple-git'; - -async function commit(git: SimpleGit, commitMessage: string) { - await git.add('.'); - await git.commit(commitMessage, undefined, { - // setting the value to a string passes name=value - // any other value passes just the key - '--no-verify': null, - '--no-gpg-sign': null, - }); -} - -async function getCurrentBranch(git: SimpleGit) { - const currentBranch = await git.branchLocal().then(summary => summary.current); - return currentBranch; -} - -async function runOnBranch(git: SimpleGit, branch: string, func: () => Promise) { - const currentBranch = await getCurrentBranch(git); - try { - if (currentBranch !== branch) { - await git.checkout(branch); - } - const result = await func(); - return result; - } finally { - await git.checkout(currentBranch); - } -} - -function branchDescription(branch: string) { - return `branch.${branch}.description`; -} - -type GitOptions = { - repoPath: string; - logger: winston.Logger; -}; - -async function commitEntry( - git: SimpleGit, - repoPath: string, - dataFiles: DataFile[], - assets: Asset[], - commitMessage: string, -) { - // save entry content - await Promise.all( - dataFiles.map(dataFile => writeFile(path.join(repoPath, dataFile.path), dataFile.raw)), - ); - // save assets - await Promise.all( - assets.map(a => writeFile(path.join(repoPath, a.path), Buffer.from(a.content, a.encoding))), - ); - if (dataFiles.every(dataFile => dataFile.newPath)) { - dataFiles.forEach(async dataFile => { - await move(path.join(repoPath, dataFile.path), path.join(repoPath, dataFile.newPath!)); - }); - } - - // commits files - await commit(git, commitMessage); -} - -async function rebase(git: SimpleGit, branch: string) { - const gpgSign = await git.raw(['config', 'commit.gpgsign']); - try { - if (gpgSign === 'true') { - await git.addConfig('commit.gpgsign', 'false'); - } - await git.rebase([branch, '--no-verify']); - } finally { - if (gpgSign === 'true') { - await git.addConfig('commit.gpgsign', gpgSign); - } - } -} - -async function merge(git: SimpleGit, from: string, to: string) { - const gpgSign = await git.raw(['config', 'commit.gpgsign']); - try { - if (gpgSign === 'true') { - await git.addConfig('commit.gpgsign', 'false'); - } - await git.mergeFromTo(from, to); - } finally { - if (gpgSign === 'true') { - await git.addConfig('commit.gpgsign', gpgSign); - } - } -} - -async function isBranchExists(git: SimpleGit, branch: string) { - const branchExists = await git.branchLocal().then(({ all }) => all.includes(branch)); - return branchExists; -} - -async function getDiffs(git: SimpleGit, source: string, dest: string) { - const rawDiff = await git.diff([source, dest]); - const diffs = parse(rawDiff).map(d => { - const oldPath = d.oldPath?.replace(/b\//, '') || ''; - const newPath = d.newPath?.replace(/b\//, '') || ''; - const path = newPath || (oldPath as string); - return { - oldPath, - newPath, - status: d.status, - newFile: d.status === 'added', - path, - id: path, - binary: d.binary || /.svg$/.test(path), - }; - }); - return diffs; -} - -export async function validateRepo({ repoPath }: { repoPath: string }) { - const git = simpleGit(repoPath); - const isRepo = await git.checkIsRepo(); - if (!isRepo) { - throw Error(`${repoPath} is not a valid git repository`); - } -} - -export function getSchema({ repoPath }: { repoPath: string }) { - const schema = defaultSchema({ path: pathTraversal(repoPath) }); - return schema; -} - -export function localGitMiddleware({ repoPath, logger }: GitOptions) { - const git = simpleGit(repoPath); - - // we can only perform a single git operation at any given time - const mutex = withTimeout(new Mutex(), 3000, new Error('Request timed out')); - - return async function (req: express.Request, res: express.Response) { - let release; - try { - release = await mutex.acquire(); - const { body } = req; - if (body.action === 'info') { - res.json({ - repo: path.basename(repoPath), - publish_modes: ['simple', 'editorial_workflow'], - type: 'local_git', - }); - return; - } - const { branch } = body.params as DefaultParams; - - const branchExists = await isBranchExists(git, branch); - if (!branchExists) { - const message = `Default branch '${branch}' doesn't exist`; - res.status(422).json({ error: message }); - return; - } - - switch (body.action) { - case 'entriesByFolder': { - const payload = body.params as EntriesByFolderParams; - const { folder, extension, depth } = payload; - const entries = await runOnBranch(git, branch, () => - listRepoFiles(repoPath, folder, extension, depth).then(files => - entriesFromFiles( - repoPath, - files.map(file => ({ path: file })), - ), - ), - ); - res.json(entries); - break; - } - case 'entriesByFiles': { - const payload = body.params as EntriesByFilesParams; - const entries = await runOnBranch(git, branch, () => - entriesFromFiles(repoPath, payload.files), - ); - res.json(entries); - break; - } - case 'getEntry': { - const payload = body.params as GetEntryParams; - const [entry] = await runOnBranch(git, branch, () => - entriesFromFiles(repoPath, [{ path: payload.path }]), - ); - res.json(entry); - break; - } - case 'unpublishedEntries': { - const cmsBranches = await git - .branchLocal() - .then(result => result.all.filter(b => b.startsWith(`${CMS_BRANCH_PREFIX}/`))); - res.json(cmsBranches.map(contentKeyFromBranch)); - break; - } - case 'unpublishedEntry': { - let { id, collection, slug, cmsLabelPrefix } = body.params as UnpublishedEntryParams; - if (id) { - ({ collection, slug } = parseContentKey(id)); - } - const contentKey = generateContentKey(collection as string, slug as string); - const cmsBranch = branchFromContentKey(contentKey); - const branchExists = await isBranchExists(git, cmsBranch); - if (branchExists) { - const diffs = await getDiffs(git, branch, cmsBranch); - const label = await git.raw(['config', branchDescription(cmsBranch)]); - const status = label && labelToStatus(label.trim(), cmsLabelPrefix || ''); - const updatedAt = - diffs.length >= 0 - ? await runOnBranch(git, cmsBranch, async () => { - const dates = await Promise.all( - diffs.map(({ newPath }) => getUpdateDate(repoPath, newPath)), - ); - return dates.reduce((a, b) => { - return a > b ? a : b; - }); - }) - : new Date(); - const unpublishedEntry = { - collection, - slug, - status, - diffs, - updatedAt, - }; - res.json(unpublishedEntry); - } else { - return res.status(404).json({ message: 'Not Found' }); - } - break; - } - case 'unpublishedEntryDataFile': { - const { path, collection, slug } = body.params as UnpublishedEntryDataFileParams; - const contentKey = generateContentKey(collection as string, slug as string); - const cmsBranch = branchFromContentKey(contentKey); - const [entry] = await runOnBranch(git, cmsBranch, () => - entriesFromFiles(repoPath, [{ path }]), - ); - res.json({ data: entry.data }); - break; - } - case 'unpublishedEntryMediaFile': { - const { path, collection, slug } = body.params as UnpublishedEntryMediaFileParams; - const contentKey = generateContentKey(collection as string, slug as string); - const cmsBranch = branchFromContentKey(contentKey); - const file = await runOnBranch(git, cmsBranch, () => readMediaFile(repoPath, path)); - res.json(file); - break; - } - case 'deleteUnpublishedEntry': { - const { collection, slug } = body.params as DeleteEntryParams; - const contentKey = generateContentKey(collection, slug); - const cmsBranch = branchFromContentKey(contentKey); - const currentBranch = await getCurrentBranch(git); - if (currentBranch === cmsBranch) { - await git.checkoutLocalBranch(branch); - } - await git.branch(['-D', cmsBranch]); - res.json({ message: `deleted branch: ${cmsBranch}` }); - break; - } - case 'persistEntry': { - const { - cmsLabelPrefix, - entry, - dataFiles = [entry as DataFile], - assets, - options, - } = body.params as PersistEntryParams; - - if (!options.useWorkflow) { - await runOnBranch(git, branch, async () => { - await commitEntry(git, repoPath, dataFiles, assets, options.commitMessage); - }); - } else { - const slug = dataFiles[0].slug; - const collection = options.collectionName as string; - const contentKey = generateContentKey(collection, slug); - const cmsBranch = branchFromContentKey(contentKey); - await runOnBranch(git, branch, async () => { - const branchExists = await isBranchExists(git, cmsBranch); - if (branchExists) { - await git.checkout(cmsBranch); - } else { - await git.checkoutLocalBranch(cmsBranch); - } - await rebase(git, branch); - const diffs = await getDiffs(git, branch, cmsBranch); - // delete media files that have been removed from the entry - const toDelete = diffs.filter( - d => d.binary && !assets.map(a => a.path).includes(d.path), - ); - await Promise.all(toDelete.map(f => fs.unlink(path.join(repoPath, f.path)))); - await commitEntry(git, repoPath, dataFiles, assets, options.commitMessage); - - // add status for new entries - if (!branchExists) { - const description = statusToLabel(options.status, cmsLabelPrefix || ''); - await git.addConfig(branchDescription(cmsBranch), description); - } - }); - } - res.json({ message: 'entry persisted' }); - break; - } - case 'updateUnpublishedEntryStatus': { - const { collection, slug, newStatus, cmsLabelPrefix } = - body.params as UpdateUnpublishedEntryStatusParams; - const contentKey = generateContentKey(collection, slug); - const cmsBranch = branchFromContentKey(contentKey); - const description = statusToLabel(newStatus, cmsLabelPrefix || ''); - await git.addConfig(branchDescription(cmsBranch), description); - res.json({ message: `${branch} description was updated to ${description}` }); - break; - } - case 'publishUnpublishedEntry': { - const { collection, slug } = body.params as PublishUnpublishedEntryParams; - const contentKey = generateContentKey(collection, slug); - const cmsBranch = branchFromContentKey(contentKey); - await merge(git, cmsBranch, branch); - await git.deleteLocalBranch(cmsBranch); - res.json({ message: `branch ${cmsBranch} merged to ${branch}` }); - break; - } - case 'getMedia': { - const { mediaFolder } = body.params as GetMediaParams; - const mediaFiles = await runOnBranch(git, branch, async () => { - const files = await listRepoFiles(repoPath, mediaFolder, '', 1); - const serializedFiles = await Promise.all( - files.map(file => readMediaFile(repoPath, file)), - ); - return serializedFiles; - }); - res.json(mediaFiles); - break; - } - case 'getMediaFile': { - const { path } = body.params as GetMediaFileParams; - const mediaFile = await runOnBranch(git, branch, () => { - return readMediaFile(repoPath, path); - }); - res.json(mediaFile); - break; - } - case 'persistMedia': { - const { - asset, - options: { commitMessage }, - } = body.params as PersistMediaParams; - - const file = await runOnBranch(git, branch, async () => { - await writeFile( - path.join(repoPath, asset.path), - Buffer.from(asset.content, asset.encoding), - ); - await commit(git, commitMessage); - return readMediaFile(repoPath, asset.path); - }); - res.json(file); - break; - } - case 'deleteFile': { - const { - path: filePath, - options: { commitMessage }, - } = body.params as DeleteFileParams; - await runOnBranch(git, branch, async () => { - await deleteFile(repoPath, filePath); - await commit(git, commitMessage); - }); - res.json({ message: `deleted file ${filePath}` }); - break; - } - case 'deleteFiles': { - const { - paths, - options: { commitMessage }, - } = body.params as DeleteFilesParams; - await runOnBranch(git, branch, async () => { - await Promise.all(paths.map(filePath => deleteFile(repoPath, filePath))); - await commit(git, commitMessage); - }); - res.json({ message: `deleted files ${paths.join(', ')}` }); - break; - } - case 'getDeployPreview': { - res.json(null); - break; - } - default: { - const message = `Unknown action ${body.action}`; - res.status(422).json({ error: message }); - break; - } - } - } catch (e) { - logger.error(`Error handling ${JSON.stringify(req.body)}: ${e.message}`); - res.status(500).json({ error: 'Unknown error' }); - } finally { - release && release(); - } - }; -} - -type Options = { - logger: winston.Logger; -}; - -export async function registerMiddleware(app: express.Express, options: Options) { - const { logger } = options; - const repoPath = path.resolve(process.env.GIT_REPO_DIRECTORY || process.cwd()); - await validateRepo({ repoPath }); - app.post('/api/v1', joi(getSchema({ repoPath }))); - app.post('/api/v1', localGitMiddleware({ repoPath, logger })); - logger.info(`Netlify CMS Git Proxy Server configured with ${repoPath}`); -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/types.ts b/packages/netlify-cms-proxy-server/src/middlewares/types.ts deleted file mode 100644 index be69316d..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/types.ts +++ /dev/null @@ -1,101 +0,0 @@ -export type DefaultParams = { - branch: string; -}; - -export type EntriesByFolderParams = { - folder: string; - extension: string; - depth: 1; -}; - -export type EntriesByFilesParams = { - files: { path: string }[]; -}; - -export type GetEntryParams = { - path: string; -}; - -export type UnpublishedEntryParams = { - id?: string; - collection?: string; - slug?: string; - cmsLabelPrefix?: string; -}; - -export type UnpublishedEntryDataFileParams = { - collection: string; - slug: string; - id: string; - path: string; -}; - -export type UnpublishedEntryMediaFileParams = { - collection: string; - slug: string; - id: string; - path: string; -}; - -export type DeleteEntryParams = { - collection: string; - slug: string; -}; - -export type UpdateUnpublishedEntryStatusParams = { - collection: string; - slug: string; - newStatus: string; - cmsLabelPrefix?: string; -}; - -export type PublishUnpublishedEntryParams = { - collection: string; - slug: string; -}; - -export type DataFile = { slug: string; path: string; raw: string; newPath?: string }; - -export type Asset = { path: string; content: string; encoding: 'base64' }; - -export type PersistEntryParams = { - cmsLabelPrefix?: string; - entry?: DataFile; - dataFiles?: DataFile[]; - assets: Asset[]; - options: { - collectionName?: string; - commitMessage: string; - useWorkflow: boolean; - status: string; - }; -}; - -export type GetMediaParams = { - mediaFolder: string; -}; - -export type GetMediaFileParams = { - path: string; -}; - -export type PersistMediaParams = { - asset: Asset; - options: { - commitMessage: string; - }; -}; - -export type DeleteFileParams = { - path: string; - options: { - commitMessage: string; - }; -}; - -export type DeleteFilesParams = { - paths: string[]; - options: { - commitMessage: string; - }; -}; diff --git a/packages/netlify-cms-proxy-server/src/middlewares/utils/entries.ts b/packages/netlify-cms-proxy-server/src/middlewares/utils/entries.ts deleted file mode 100644 index be31ebc0..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/utils/entries.ts +++ /dev/null @@ -1,48 +0,0 @@ -import crypto from 'crypto'; -import path from 'path'; -import { promises as fs } from 'fs'; - -function sha256(buffer: Buffer) { - return crypto.createHash('sha256').update(buffer).digest('hex'); -} - -// normalize windows os path format -function normalizePath(path: string) { - return path.replace(/\\/g, '/'); -} - -export async function entriesFromFiles( - repoPath: string, - files: { path: string; label?: string }[], -) { - return Promise.all( - files.map(async file => { - try { - const content = await fs.readFile(path.join(repoPath, file.path)); - return { - data: content.toString(), - file: { path: normalizePath(file.path), label: file.label, id: sha256(content) }, - }; - } catch (e) { - return { - data: null, - file: { path: normalizePath(file.path), label: file.label, id: null }, - }; - } - }), - ); -} - -export async function readMediaFile(repoPath: string, file: string) { - const encoding = 'base64'; - const buffer = await fs.readFile(path.join(repoPath, file)); - const id = sha256(buffer); - - return { - id, - content: buffer.toString(encoding), - encoding, - path: normalizePath(file), - name: path.basename(file), - }; -} diff --git a/packages/netlify-cms-proxy-server/src/middlewares/utils/fs.ts b/packages/netlify-cms-proxy-server/src/middlewares/utils/fs.ts deleted file mode 100644 index a15c1e09..00000000 --- a/packages/netlify-cms-proxy-server/src/middlewares/utils/fs.ts +++ /dev/null @@ -1,65 +0,0 @@ -import path from 'path'; -import { promises as fs } from 'fs'; - -async function listFiles(dir: string, extension: string, depth: number): Promise { - if (depth <= 0) { - return []; - } - - try { - const dirents = await fs.readdir(dir, { withFileTypes: true }); - const files = await Promise.all( - dirents.map(dirent => { - const res = path.join(dir, dirent.name); - return dirent.isDirectory() - ? listFiles(res, extension, depth - 1) - : [res].filter(f => f.endsWith(extension)); - }), - ); - return ([] as string[]).concat(...files); - } catch (e) { - return []; - } -} - -export async function listRepoFiles( - repoPath: string, - folder: string, - extension: string, - depth: number, -) { - const files = await listFiles(path.join(repoPath, folder), extension, depth); - return files.map(f => f.slice(repoPath.length + 1)); -} - -export async function writeFile(filePath: string, content: Buffer | string) { - await fs.mkdir(path.dirname(filePath), { recursive: true }); - await fs.writeFile(filePath, content); -} - -export async function deleteFile(repoPath: string, filePath: string) { - await fs.unlink(path.join(repoPath, filePath)).catch(() => undefined); -} - -async function moveFile(from: string, to: string) { - await fs.mkdir(path.dirname(to), { recursive: true }); - await fs.rename(from, to); -} - -export async function move(from: string, to: string) { - // move file - await moveFile(from, to); - - // move children - const sourceDir = path.dirname(from); - const destDir = path.dirname(to); - const allFiles = await listFiles(sourceDir, '', 100); - await Promise.all(allFiles.map(file => moveFile(file, file.replace(sourceDir, destDir)))); -} - -export async function getUpdateDate(repoPath: string, filePath: string) { - return fs - .stat(path.join(repoPath, filePath)) - .then(stat => stat.mtime) - .catch(() => new Date()); -} diff --git a/packages/netlify-cms-proxy-server/src/what-the-diff.d.ts b/packages/netlify-cms-proxy-server/src/what-the-diff.d.ts deleted file mode 100644 index 1f3bdeab..00000000 --- a/packages/netlify-cms-proxy-server/src/what-the-diff.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -declare module 'what-the-diff' { - export const parse: ( - rawDiff: string, - ) => { oldPath?: string; newPath?: string; binary: boolean; status: string }[]; -} diff --git a/packages/netlify-cms-proxy-server/tsconfig.json b/packages/netlify-cms-proxy-server/tsconfig.json deleted file mode 100644 index a847f832..00000000 --- a/packages/netlify-cms-proxy-server/tsconfig.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "compilerOptions": { - "module": "commonjs", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "target": "ES2018", - "moduleResolution": "node", - "outDir": "dist", - "baseUrl": ".", - "allowJs": true, - "strict": true, - "noImplicitAny": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "sourceMap": true - }, - "include": ["src/**/*"], - "exclude": ["src/**/*spec.ts"] -} diff --git a/packages/netlify-cms-proxy-server/webpack.config.js b/packages/netlify-cms-proxy-server/webpack.config.js deleted file mode 100644 index 28914a49..00000000 --- a/packages/netlify-cms-proxy-server/webpack.config.js +++ /dev/null @@ -1,39 +0,0 @@ -const path = require('path'); -const webpack = require('webpack'); -const nodeExternals = require('webpack-node-externals'); -const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin'); -const { NODE_ENV = 'production' } = process.env; - -const allowlist = [/^netlify-cms-lib-util/]; - -module.exports = { - entry: { index: path.join('src', 'index.ts'), middlewares: path.join('src', 'middlewares.ts') }, - mode: NODE_ENV, - target: 'node', - devtool: 'source-map', - output: { - path: path.resolve(__dirname, 'dist'), - filename: '[name].js', - libraryTarget: 'commonjs2', - }, - resolve: { - plugins: [new TsconfigPathsPlugin()], - extensions: ['.ts', '.js'], - }, - module: { - rules: [ - { - test: /\.ts$/, - use: ['ts-loader'], - }, - ], - }, - externals: [ - nodeExternals({ allowlist }), - nodeExternals({ - allowlist, - modulesDir: path.resolve(__dirname, path.join('..', '..', 'node_modules')), - }), - ], - plugins: [new webpack.BannerPlugin({ banner: '#!/usr/bin/env node', raw: true })], -}; diff --git a/packages/netlify-cms-ui-default/CHANGELOG.md b/packages/netlify-cms-ui-default/CHANGELOG.md deleted file mode 100644 index 0722b735..00000000 --- a/packages/netlify-cms-ui-default/CHANGELOG.md +++ /dev/null @@ -1,751 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.15.21](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.20...netlify-cms-ui-default@2.15.21) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.20](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.19...netlify-cms-ui-default@2.15.20) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.19](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.18...netlify-cms-ui-default@2.15.19) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.18](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.17...netlify-cms-ui-default@2.15.18) (2022-09-20) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.17](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.16...netlify-cms-ui-default@2.15.17) (2022-09-20) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.16](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.15...netlify-cms-ui-default@2.15.16) (2022-09-20) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.15](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.14...netlify-cms-ui-default@2.15.15) (2022-09-20) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.14](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.5...netlify-cms-ui-default@2.15.14) (2022-09-08) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.11](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.5...netlify-cms-ui-default@2.15.11) (2022-09-07) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.9](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.5...netlify-cms-ui-default@2.15.9) (2022-09-07) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.4...netlify-cms-ui-default@2.15.5) (2022-03-08) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.15.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.3...netlify-cms-ui-default@2.15.4) (2021-12-21) - - -### Bug Fixes - -* **netlify-cms-ui-default:** use grayDark for button ([#6069](https://github.com/netlify/netlify-cms/issues/6069)) ([ad85514](https://github.com/netlify/netlify-cms/commit/ad85514cba607f066ab7071bee5932b2192466ee)), closes [/github.com/netlify/netlify-cms/issues/1333#issuecomment-998115794](https://github.com//github.com/netlify/netlify-cms/issues/1333/issues/issuecomment-998115794) - - - - - -## [2.15.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.2...netlify-cms-ui-default@2.15.3) (2021-10-15) - - -### Bug Fixes - -* remove "Don't fork the repo"-Button - fixes [#5723](https://github.com/netlify/netlify-cms/issues/5723) ([#5872](https://github.com/netlify/netlify-cms/issues/5872)) ([05d8923](https://github.com/netlify/netlify-cms/commit/05d89230dca315ddcc734b1dc6223df1d8dc1ede)) - - - - - -## [2.15.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.1...netlify-cms-ui-default@2.15.2) (2021-08-17) - - -### Bug Fixes - -* make 'now' button consistent ([#5716](https://github.com/netlify/netlify-cms/issues/5716)) ([97de9da](https://github.com/netlify/netlify-cms/commit/97de9da948fff3b132d4d31c5f9069780abf3cc6)) - - - - - -## [2.15.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.15.0...netlify-cms-ui-default@2.15.1) (2021-08-04) - - -### Bug Fixes - -* **widget-list:** add missing translations in widget list top bar ([#5471](https://github.com/netlify/netlify-cms/issues/5471)) ([#5679](https://github.com/netlify/netlify-cms/issues/5679)) ([db560cc](https://github.com/netlify/netlify-cms/commit/db560cc082fcc0a9842919e28f715e44a6e4625a)) - - - - - -# [2.15.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.14.0...netlify-cms-ui-default@2.15.0) (2021-08-03) - - -### Features - -* disable 'Save' button when there are no changes ([#5595](https://github.com/netlify/netlify-cms/issues/5595)) ([4b566a7](https://github.com/netlify/netlify-cms/commit/4b566a78f4282a6f04caf3deafaaac4d74acfd63)) - - - - - -# [2.14.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-ui-default@2.13.4...netlify-cms-ui-default@2.14.0) (2021-07-06) - - -### Features - -* **open-authoring:** add hover tooltip ([#5567](https://github.com/netlify/netlify-cms/issues/5567)) ([1822815](https://github.com/netlify/netlify-cms/commit/1822815118b9d35fce8e65a8424f2cb748253ac3)) - - - - - -## [2.13.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.13.3...netlify-cms-ui-default@2.13.4) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.13.2...netlify-cms-ui-default@2.13.3) (2021-05-19) - - -### Bug Fixes - -* **deps:** update dependency react-aria-menubutton to v7 ([#5382](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5382)) ([8ec9ba0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/8ec9ba0747dcae8561d5f530b76897724574d941)) - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.13.1...netlify-cms-ui-default@2.13.2) (2021-05-19) - - -### Bug Fixes - -* **deps:** update dependency react-aria-menubutton to v7 ([#5378](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5378)) ([2dd8944](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/2dd89446aab5dcf81a8546b8da45082953bdb364)) -* **deps:** update dependency react-transition-group to v4 ([#5385](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5385)) ([f0725a8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/f0725a83799f54cc442566ad036d493ad3a7ce6f)) - - -### Reverts - -* Revert "fix(deps): update dependency react-aria-menubutton to v7 (#5378)" (#5380) ([5b0ba81](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/5b0ba8124e5d0112dfc315fde83590aa88f58144)), closes [#5378](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5378) [#5380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5380) - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.13.0...netlify-cms-ui-default@2.13.1) (2021-05-09) - - -### Bug Fixes - -* buttons use inherited font stack ([#5344](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5344)) ([2143cd3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/2143cd30fd410098f629902c8ca1ce75535f5a54)) - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.12.2...netlify-cms-ui-default@2.13.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.12.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.12.1...netlify-cms-ui-default@2.12.2) (2021-04-01) - - -### Bug Fixes - -* **widget-markdown:** improve UX in Markdown editor - link editing and selected heading underline ([#5104](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/5104)) ([dde1a9d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/dde1a9db5483912f626f13239d7a3d06d6c4e05c)) - - - - - -## [2.12.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.12.0...netlify-cms-ui-default@2.12.1) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.11.6...netlify-cms-ui-default@2.12.0) (2020-11-26) - - -### Features - -* add azure devops backend ([#4427](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/4427)) ([4e6dc88](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/4e6dc88efb1dae4cf6137730c3b4fb6d0f75a8cc)) - - - - - -## [2.11.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.11.5...netlify-cms-ui-default@2.11.6) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.11.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.11.4...netlify-cms-ui-default@2.11.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## 2.11.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.11.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.11.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.11.0...netlify-cms-ui-default@2.11.1) (2020-06-18) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.10.1...netlify-cms-ui-default@2.11.0) (2020-06-01) - - -### Features - -* add filter to collection view ([#3741](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3741)) ([c28cc0c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/c28cc0c9e7c7bc4bed07c02dfb869b2dedab9aab)) - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.10.0...netlify-cms-ui-default@2.10.1) (2020-05-04) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.5...netlify-cms-ui-default@2.10.0) (2020-04-14) - - -### Bug Fixes - -* increase DropdownList z-index ([#3579](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3579)) ([7fcdaef](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/7fcdaef1c92c65d981ac2ebc1077d8da0c3ca285)) - - -### Features - -* **widget-datetime:** add now to datepicker ([#3484](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3484)) ([79b8469](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/79b8469337dade3bd7472b3f42b826efc7e0987d)) - - - - - -## [2.9.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.4...netlify-cms-ui-default@2.9.5) (2020-04-01) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.9.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.3...netlify-cms-ui-default@2.9.4) (2020-03-30) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.2...netlify-cms-ui-default@2.9.3) (2020-03-12) - - -### Bug Fixes - -* ja locale labels ([#3367](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3367)) ([50837b0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/50837b0068ac8972ce16cbf5f238aa5a2c5bd6e9)) - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.1...netlify-cms-ui-default@2.9.2) (2020-03-03) - - -### Bug Fixes - -* **locale:** Remove hard coded string literals ([#3333](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3333)) ([7c45a3c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/7c45a3cda983be427864a56e58791565eb9232e2)) - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.9.0...netlify-cms-ui-default@2.9.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.8.0...netlify-cms-ui-default@2.9.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.8.0-beta.0...netlify-cms-ui-default@2.8.0) (2020-01-07) - - -### Bug Fixes - -* avoid nested select widget z-index conflicts ([#2990](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2990)) ([fe09720](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/fe097202f0220b2eab426848b928258524ba6e72)) - - - - - -# [2.8.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0...netlify-cms-ui-default@2.8.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.5...netlify-cms-ui-default@2.7.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.7.0-beta.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.4...netlify-cms-ui-default@2.7.0-beta.5) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -# [2.7.0-beta.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.3...netlify-cms-ui-default@2.7.0-beta.4) (2019-12-11) - - -### Features - -* duplicate entry ([#2956](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2956)) ([d180bff](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/d180bffb44432a82f2b4e5a08df5693b30268fee)) - - - - - -# [2.7.0-beta.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.2...netlify-cms-ui-default@2.7.0-beta.3) (2019-11-18) - - -### Features - -* **widget-markdown:** add headings dropdown ([#2879](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2879)) ([78face3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/78face334f2dc7c99f5805551c052587e54d5753)) - - - - - -# [2.7.0-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.1...netlify-cms-ui-default@2.7.0-beta.2) (2019-11-18) - - -### Bug Fixes - -* media assets modal ([#2880](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2880)) ([0df2159](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/0df21598ab2b3ed42c74f922ed4aadd88a64de3b)) - - -### Features - -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -# [2.7.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.7.0-beta.0...netlify-cms-ui-default@2.7.0-beta.1) (2019-11-07) - - -### Bug Fixes - -* swap out svg plugin causing node 12 failures ([#2710](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2710)) ([5dc7ee2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/5dc7ee2a9c0e4ad68569fbc8215c3ac589231bc9)) - - -### Features - -* add go back to site button ([#2538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2538)) ([f206e7e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/f206e7e5a13fb48ec6b27dce0dbb3a59b61de8f9)) - - - - - -# [2.7.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.4...netlify-cms-ui-default@2.7.0-beta.0) (2019-07-24) - - -### Features - -* **backend-github:** Open Authoring ([#2430](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2430)) ([edf0a3a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/edf0a3a)) - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.3...netlify-cms-ui-default@2.6.4) (2019-07-24) - - -### Bug Fixes - -* **ui:** typos in color vars ([#2444](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2444)) ([d260161](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/d260161)) - - - - - -## [2.6.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.3-beta.0...netlify-cms-ui-default@2.6.3) (2019-06-14) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.6.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.2...netlify-cms-ui-default@2.6.3-beta.0) (2019-05-15) - - -### Bug Fixes - -* **widget-markdown:** keep markdown widget dropdowns on top ([#2326](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2326)) ([5f807d7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/5f807d7)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.2-beta.0...netlify-cms-ui-default@2.6.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.6.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.1...netlify-cms-ui-default@2.6.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.1-beta.1...netlify-cms-ui-default@2.6.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -## [2.6.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.1-beta.0...netlify-cms-ui-default@2.6.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/6ffd13b)) - - - - - -## [2.6.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.6.0...netlify-cms-ui-default@2.6.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.5.0...netlify-cms-ui-default@2.6.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/d142b32)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.5.0-beta.0...netlify-cms-ui-default@2.5.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.4.1-beta.0...netlify-cms-ui-default@2.5.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/82cc794)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.4.1-alpha.0...netlify-cms-ui-default@2.4.1-beta.0) (2019-03-15) - - -### Bug Fixes - -* **deps:** update dependency react-aria-menubutton to v6 ([#2195](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2195)) ([e8d3db1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/e8d3db1)) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/ccef446)) - - - - - -## [2.4.1-alpha.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.4.0...netlify-cms-ui-default@2.4.1-alpha.0) (2019-03-14) - -**Note:** Version bump only for package netlify-cms-ui-default - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.3.0...netlify-cms-ui-default@2.4.0) (2019-02-26) - - -### Features - -* **netlify-cms-widget-relation:** use react-select and add support for multiple entries ([#1936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1936)) ([518f6fb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/518f6fb)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.2.0...netlify-cms-ui-default@2.3.0) (2019-02-08) - - -### Features - -* **workflow:** add deploy preview links ([#2028](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/2028)) ([15d221d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/15d221d)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.1.1...netlify-cms-ui-default@2.2.0) (2018-12-27) - - -### Features - -* **netlify-cms-widget-list:** add variable type definitions to list widget ([#1857](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1857)) ([8ddc168](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/8ddc168)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.1.0...netlify-cms-ui-default@2.1.1) (2018-11-29) - - -### Bug Fixes - -* **a11y:** correct label "for" references to fields ([#1904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1904)) ([955f94f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/955f94f)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.6...netlify-cms-ui-default@2.1.0) (2018-11-12) - - -### Features - -* allow custom logo on auth page ([#1818](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1818)) ([c6ae1e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/c6ae1e8)) - - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.5...netlify-cms-ui-default@2.0.6) (2018-08-27) - - -### Bug Fixes - -* **list-widget:** use the sortable handle ([#1655](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1655)) ([e215f68](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/e215f68)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.4...netlify-cms-ui-default@2.0.5) (2018-08-24) - - -### Bug Fixes - -* **list-widget:** fix single field usage in list widget ([#1395](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/issues/1395)) ([06d3650](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/commit/06d3650)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.3...netlify-cms-ui-default@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-ui-default - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.2...netlify-cms-ui-default@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-ui-default - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default/compare/netlify-cms-ui-default@2.0.1...netlify-cms-ui-default@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-ui-default - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - -### Bug Fixes - -* **bitbucket:** fix rebasing mistakes in bitbucket backend and deps ([#1522](https://github.com/netlify/netlify-cms/issues/1522)) ([bdfd944](https://github.com/netlify/netlify-cms/commit/bdfd944)) -* **UI:** fix loader styling ([#1521](https://github.com/netlify/netlify-cms/issues/1521)) ([0bd0273](https://github.com/netlify/netlify-cms/commit/0bd0273)) diff --git a/packages/netlify-cms-ui-default/README.md b/packages/netlify-cms-ui-default/README.md deleted file mode 100644 index 8563f790..00000000 --- a/packages/netlify-cms-ui-default/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-ui-default/README.md)! diff --git a/packages/netlify-cms-ui-default/package.json b/packages/netlify-cms-ui-default/package.json deleted file mode 100644 index 68721acc..00000000 --- a/packages/netlify-cms-ui-default/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "netlify-cms-ui-default", - "description": "Default UI components for Netlify CMS.", - "version": "2.15.21", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-ui-default", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "license": "MIT", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-ui-default.js", - "keywords": [ - "netlify-cms" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-aria-menubutton": "^7.0.0", - "react-toggled": "^1.1.2", - "react-transition-group": "^4.0.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "lodash": "^4.17.11", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-ui-default/webpack.config.js b/packages/netlify-cms-ui-default/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-ui-default/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-boolean/CHANGELOG.md b/packages/netlify-cms-widget-boolean/CHANGELOG.md deleted file mode 100644 index 4f6a3288..00000000 --- a/packages/netlify-cms-widget-boolean/CHANGELOG.md +++ /dev/null @@ -1,258 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.4.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-boolean@2.4.2...netlify-cms-widget-boolean@2.4.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-boolean@2.4.1...netlify-cms-widget-boolean@2.4.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.4.0...netlify-cms-widget-boolean@2.4.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.3.6...netlify-cms-widget-boolean@2.4.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.3.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.3.5...netlify-cms-widget-boolean@2.3.6) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.3.4...netlify-cms-widget-boolean@2.3.5) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.3.3...netlify-cms-widget-boolean@2.3.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## 2.3.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.3.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.3.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.3...netlify-cms-widget-boolean@2.3.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.2...netlify-cms-widget-boolean@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.2-beta.0...netlify-cms-widget-boolean@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.1...netlify-cms-widget-boolean@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.1-beta.2...netlify-cms-widget-boolean@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.1-beta.1...netlify-cms-widget-boolean@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.1-beta.0...netlify-cms-widget-boolean@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.2.0...netlify-cms-widget-boolean@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.1.0...netlify-cms-widget-boolean@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.1.0-beta.0...netlify-cms-widget-boolean@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-boolean - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.6-beta.0...netlify-cms-widget-boolean@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/82cc794)) - - - - - -## [2.0.6-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.5...netlify-cms-widget-boolean@2.0.6-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/ccef446)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.4...netlify-cms-widget-boolean@2.0.5) (2018-11-12) - - -### Bug Fixes - -* **widgets:** fix list object field default values ([#1826](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/issues/1826)) ([c765793](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/commit/c765793)) - - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.3...netlify-cms-widget-boolean@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-boolean - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.2...netlify-cms-widget-boolean@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-boolean - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean/compare/netlify-cms-widget-boolean@2.0.1...netlify-cms-widget-boolean@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-boolean - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-boolean diff --git a/packages/netlify-cms-widget-boolean/README.md b/packages/netlify-cms-widget-boolean/README.md deleted file mode 100644 index 3e634ea8..00000000 --- a/packages/netlify-cms-widget-boolean/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-boolean/README.md)! diff --git a/packages/netlify-cms-widget-boolean/package.json b/packages/netlify-cms-widget-boolean/package.json deleted file mode 100644 index 2142e5cc..00000000 --- a/packages/netlify-cms-widget-boolean/package.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "netlify-cms-widget-boolean", - "description": "Widget for editing boolean values in Netlify CMS.", - "version": "2.4.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#boolean", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-boolean", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-boolean.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "boolean" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "lodash": "^4.17.11", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - } -} diff --git a/packages/netlify-cms-widget-boolean/webpack.config.js b/packages/netlify-cms-widget-boolean/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-boolean/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-code/CHANGELOG.md b/packages/netlify-cms-widget-code/CHANGELOG.md deleted file mode 100644 index f6e34fe4..00000000 --- a/packages/netlify-cms-widget-code/CHANGELOG.md +++ /dev/null @@ -1,219 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.3.6](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-code@1.3.5...netlify-cms-widget-code@1.3.6) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.3.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-code@1.3.4...netlify-cms-widget-code@1.3.5) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.3.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-code@1.3.3...netlify-cms-widget-code@1.3.4) (2022-03-08) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.3.2...netlify-cms-widget-code@1.3.3) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.3.1...netlify-cms-widget-code@1.3.2) (2021-05-23) - - -### Bug Fixes - -* **deps:** update dependency react-select to v4 ([#5417](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/5417)) ([03362ef](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/03362ef5ab87c6fe5c964da5c5a18099b73a3fc6)) - - - - - -## [1.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.3.0...netlify-cms-widget-code@1.3.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update react-select to v3 ([#5394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/5394)) ([03be13c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/03be13c1e87b318fd10ae6f6ab54cd2634fb9662)) - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.8...netlify-cms-widget-code@1.3.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [1.2.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.7...netlify-cms-widget-code@1.2.8) (2021-03-30) - - -### Bug Fixes - -* add !important to codeMirror height ([#5127](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/5127)) ([50ab350](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/50ab3504e533353bfefc65480edf8a53bb497acf)) - - - - - -## [1.2.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.6...netlify-cms-widget-code@1.2.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.2.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.5...netlify-cms-widget-code@1.2.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.2.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.4...netlify-cms-widget-code@1.2.5) (2021-01-05) - - -### Bug Fixes - -* **deps:** update dependency js-yaml to v4 ([#4797](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/4797)) ([bda604b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/bda604b389071ab2dd31a7107841aa7fcafdc04f)) - - - - - -## [1.2.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.2.3...netlify-cms-widget-code@1.2.4) (2020-09-15) - - -### Bug Fixes - -* **deps:** update dependency re-resizable to v6 ([#4308](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/4308)) ([de068cb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/de068cba1d44ec76e47e28d724427a9f4a53e0fd)) -* **deps:** update dependency react-codemirror2 to v7 ([#4310](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/4310)) ([180cd5f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/180cd5f652ba23a186ade9173161ac13605a8ce8)) - - - - - -## 1.2.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.2.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.2.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.5...netlify-cms-widget-code@1.2.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [1.1.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.4...netlify-cms-widget-code@1.1.5) (2020-05-19) - - -### Bug Fixes - -* **widget-code:** change dynamic import to require ([#3745](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/3745)) ([3d7d5d2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/3d7d5d2e677fa0bb2bd6e2a65df302053ba4d159)) - - - - - -## [1.1.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.3...netlify-cms-widget-code@1.1.4) (2020-03-30) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.1.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.2...netlify-cms-widget-code@1.1.3) (2020-01-29) - - -### Bug Fixes - -* **widget-code:** use snake case for default language option ([#3155](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/3155)) ([32854de](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/32854de41c1d0ef81836ffdad8851a583086d6a6)) - - - - - -## [1.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.2-beta.0...netlify-cms-widget-code@1.1.2) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-widget-code - - - - - -## [1.1.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/compare/netlify-cms-widget-code@1.1.0...netlify-cms-widget-code@1.1.2-beta.0) (2019-12-19) - - -### Bug Fixes - -* allow widget overflow ([#2982](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/2982)) ([5ea2b6f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/5ea2b6fe2f3ccb5e465f65fca359baf7210e5fdb)) - - - - - -# 1.1.0 (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) diff --git a/packages/netlify-cms-widget-code/README.md b/packages/netlify-cms-widget-code/README.md deleted file mode 100644 index 91370813..00000000 --- a/packages/netlify-cms-widget-code/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://gitter.im/netlify/netlifycms/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-code/README.md)! diff --git a/packages/netlify-cms-widget-code/package.json b/packages/netlify-cms-widget-code/package.json deleted file mode 100644 index aed42036..00000000 --- a/packages/netlify-cms-widget-code/package.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "name": "netlify-cms-widget-code", - "description": "Widget for editing code in Netlify CMS", - "version": "1.3.6", - "homepage": "https://www.netlifycms.org/docs/widgets/#code", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-code", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-code.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "code", - "codemirror", - "editor", - "code editor" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward", - "process:languages": "node ./scripts/process-languages" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "codemirror": "^5.46.0", - "lodash": "^4.17.11", - "netlify-cms-ui-default": "^2.12.1", - "react": "^16.8.4 || ^17.0.0" - }, - "dependencies": { - "react-codemirror2": "^7.0.0", - "react-select": "^4.0.0" - } -} diff --git a/packages/netlify-cms-widget-code/webpack.config.js b/packages/netlify-cms-widget-code/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-code/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-colorstring/CHANGELOG.md b/packages/netlify-cms-widget-colorstring/CHANGELOG.md deleted file mode 100644 index 3f875bfa..00000000 --- a/packages/netlify-cms-widget-colorstring/CHANGELOG.md +++ /dev/null @@ -1,70 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.1.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-colorstring@1.1.3...netlify-cms-widget-colorstring@1.1.4) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -## [1.1.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-colorstring@1.1.2...netlify-cms-widget-colorstring@1.1.3) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -## [1.1.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-colorstring@1.1.1...netlify-cms-widget-colorstring@1.1.2) (2022-03-08) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -## [1.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/compare/netlify-cms-widget-colorstring@1.1.0...netlify-cms-widget-colorstring@1.1.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -# [1.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/compare/netlify-cms-widget-colorstring@1.0.3...netlify-cms-widget-colorstring@1.1.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [1.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/compare/netlify-cms-widget-colorstring@1.0.2...netlify-cms-widget-colorstring@1.0.3) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -## [1.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/compare/netlify-cms-widget-colorstring@1.0.1...netlify-cms-widget-colorstring@1.0.2) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-colorstring - - - - - -## 1.0.1 (2020-10-25) - - -### Bug Fixes - -* **widget-color:** rename to colorstring ([#4496](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/issues/4496)) ([fbc8963](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring/commit/fbc89637267f65ede25cd15ff6ed832ab3eb44dc)) diff --git a/packages/netlify-cms-widget-colorstring/README.md b/packages/netlify-cms-widget-colorstring/README.md deleted file mode 100644 index 674eada6..00000000 --- a/packages/netlify-cms-widget-colorstring/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-colorstring/README.md)! diff --git a/packages/netlify-cms-widget-colorstring/package.json b/packages/netlify-cms-widget-colorstring/package.json deleted file mode 100644 index 1e668328..00000000 --- a/packages/netlify-cms-widget-colorstring/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "netlify-cms-widget-colorstring", - "description": "Widget for editing color strings in Netlify CMS.", - "version": "1.1.4", - "homepage": "https://www.netlifycms.org/docs/widgets/#color", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-colorstring", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-colorstring.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "color" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-color": "^2.18.1", - "validate-color": "^2.1.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-colorstring/webpack.config.js b/packages/netlify-cms-widget-colorstring/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-colorstring/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-date/CHANGELOG.md b/packages/netlify-cms-widget-date/CHANGELOG.md deleted file mode 100644 index fc685376..00000000 --- a/packages/netlify-cms-widget-date/CHANGELOG.md +++ /dev/null @@ -1,345 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.6.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-date@2.6.4...netlify-cms-widget-date@2.6.5) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-date@2.6.3...netlify-cms-widget-date@2.6.4) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.6.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-date@2.6.2...netlify-cms-widget-date@2.6.3) (2021-09-13) - - -### Bug Fixes - -* **deps:** update react-datetime ([#5803](https://github.com/netlify/netlify-cms/issues/5803)) ([477efa5](https://github.com/netlify/netlify-cms/commit/477efa58f1a26e60c9ba5c0405e11132ecb7c68a)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.6.1...netlify-cms-widget-date@2.6.2) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.6.0...netlify-cms-widget-date@2.6.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update dependency react-datetime to v3 ([#5383](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/5383)) ([a2735b5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/a2735b5fd68470821841f608ce2123e8ce74c4e0)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.5.7...netlify-cms-widget-date@2.6.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.5.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.5.6...netlify-cms-widget-date@2.5.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.5.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.5.5...netlify-cms-widget-date@2.5.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.5.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.5.4...netlify-cms-widget-date@2.5.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## 2.5.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.5.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.5.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.5.0...netlify-cms-widget-date@2.5.1) (2020-05-19) - - -### Bug Fixes - -* **date:** allow default value to Date field ([#3740](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/3740)) ([8ab2a60](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/8ab2a6036be99c397c7d2fcb4ad3ebaeba549546)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.4.0...netlify-cms-widget-date@2.5.0) (2020-04-07) - - -### Features - -* **yaml:** support comments ([#3529](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/3529)) ([4afbbdd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/4afbbdd8a99241d239f28c5be544bb0ca77e345b)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.5...netlify-cms-widget-date@2.4.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.4...netlify-cms-widget-date@2.3.5) (2019-11-07) - - -### Bug Fixes - -* **widget-date:** allow empty value ([#2705](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2705)) ([d058697](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/d0586976443c4255ba122fba33bbe045069fc461)) - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.3...netlify-cms-widget-date@2.3.4) (2019-09-26) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.2...netlify-cms-widget-date@2.3.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.2-beta.0...netlify-cms-widget-date@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.1...netlify-cms-widget-date@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.1-beta.2...netlify-cms-widget-date@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.1-beta.1...netlify-cms-widget-date@2.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.1-beta.0...netlify-cms-widget-date@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.3.0...netlify-cms-widget-date@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.2.0...netlify-cms-widget-date@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.2.0-beta.0...netlify-cms-widget-date@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-date - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.1.1-beta.0...netlify-cms-widget-date@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/82cc794)) - - - - - -## [2.1.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.1.0...netlify-cms-widget-date@2.1.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/ccef446)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.6...netlify-cms-widget-date@2.1.0) (2018-11-29) - - -### Bug Fixes - -* **a11y:** correct label "for" references to fields ([#1904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/1904)) ([955f94f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/955f94f)) - - -### Features - -* **widget-date:** add input display formatting ([#1739](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/1739)) ([855efd8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/855efd8)) - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.5...netlify-cms-widget-date@2.0.6) (2018-11-12) - - -### Bug Fixes - -* **widget-date:** fix default value for nested date widget ([#1859](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/issues/1859)) ([d8f8887](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/commit/d8f8887)) - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.4...netlify-cms-widget-date@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-date - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.3...netlify-cms-widget-date@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-date - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.2...netlify-cms-widget-date@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-date - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date/compare/netlify-cms-widget-date@2.0.1...netlify-cms-widget-date@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-date - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-date diff --git a/packages/netlify-cms-widget-date/README.md b/packages/netlify-cms-widget-date/README.md deleted file mode 100644 index 914210b9..00000000 --- a/packages/netlify-cms-widget-date/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-date/README.md)! diff --git a/packages/netlify-cms-widget-date/package.json b/packages/netlify-cms-widget-date/package.json deleted file mode 100644 index 51f6ec23..00000000 --- a/packages/netlify-cms-widget-date/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "netlify-cms-widget-date", - "description": "Widget for editing dates in Netlify CMS.", - "version": "2.6.5", - "homepage": "https://www.netlifycms.org/docs/widgets/#date", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-date", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-date.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "date", - "dates" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-datetime": "^3.1.1" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "moment": "^2.24.0", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-date/src/DateControl.js b/packages/netlify-cms-widget-date/src/DateControl.js deleted file mode 100644 index b8b51e07..00000000 --- a/packages/netlify-cms-widget-date/src/DateControl.js +++ /dev/null @@ -1,142 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { css } from '@emotion/react'; -import reactDateTimeStyles from 'react-datetime/css/react-datetime.css'; -import DateTime from 'react-datetime'; -import moment from 'moment'; -import { once } from 'lodash'; -import { oneLine } from 'common-tags'; - -const warnDeprecated = once(() => - console.warn(oneLine` - Netlify CMS config: the date widget has been deprecated and will - be removed in the next major release. Please use the datetime widget instead. -`), -); - -/** - * `date` widget is deprecated in favor of the `datetime` widget - */ -export default class DateControl extends React.Component { - static propTypes = { - field: PropTypes.object.isRequired, - forID: PropTypes.string, - onChange: PropTypes.func.isRequired, - classNameWrapper: PropTypes.string.isRequired, - setActiveStyle: PropTypes.func.isRequired, - setInactiveStyle: PropTypes.func.isRequired, - value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), - includeTime: PropTypes.bool, - }; - - getFormats() { - const { field, includeTime } = this.props; - const format = field.get('format'); - - // dateFormat and timeFormat are strictly for modifying - // input field with the date/time pickers - const dateFormat = field.get('date_format'); - // show time-picker? false hides it, true shows it using default format - let timeFormat = field.get('time_format'); - if (typeof timeFormat === 'undefined') { - timeFormat = !!includeTime; - } - - return { - format, - dateFormat, - timeFormat, - }; - } - - getDefaultValue() { - const { field } = this.props; - const defaultValue = field.get('default'); - return defaultValue; - } - - formats = this.getFormats(); - defaultValue = this.getDefaultValue(); - - componentDidMount() { - warnDeprecated(); - const { value } = this.props; - - /** - * Set the current date as default value if no default value is provided. An - * empty string means the value is intentionally blank. - */ - if (value === undefined) { - setTimeout(() => { - this.handleChange(this.defaultValue === undefined ? new Date() : this.defaultValue); - }, 0); - } - } - - // Date is valid if datetime is a moment or Date object otherwise it's a string. - // Handle the empty case, if the user wants to empty the field. - isValidDate = datetime => - moment.isMoment(datetime) || datetime instanceof Date || datetime === ''; - - handleChange = datetime => { - /** - * Set the date only if it is valid. - */ - if (!this.isValidDate(datetime)) { - return; - } - - const { onChange } = this.props; - const { format } = this.formats; - - /** - * Produce a formatted string only if a format is set in the config. - * Otherwise produce a date object. - */ - if (format) { - const formattedValue = datetime ? moment(datetime).format(format) : ''; - onChange(formattedValue); - } else { - const value = moment.isMoment(datetime) ? datetime.toDate() : datetime; - onChange(value); - } - }; - - onClose = datetime => { - const { setInactiveStyle } = this.props; - - if (!this.isValidDate(datetime)) { - const parsedDate = moment(datetime); - - if (parsedDate.isValid()) { - this.handleChange(datetime); - } else { - window.alert('The date you entered is invalid.'); - } - } - - setInactiveStyle(); - }; - - render() { - const { forID, value, classNameWrapper, setActiveStyle } = this.props; - const { format, dateFormat, timeFormat } = this.formats; - return ( -
    - -
    - ); - } -} diff --git a/packages/netlify-cms-widget-date/src/DatePreview.js b/packages/netlify-cms-widget-date/src/DatePreview.js deleted file mode 100644 index 6c97679f..00000000 --- a/packages/netlify-cms-widget-date/src/DatePreview.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; - -function DatePreview({ value }) { - return {value ? value.toString() : null}; -} - -DatePreview.propTypes = { - value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), -}; - -export default DatePreview; diff --git a/packages/netlify-cms-widget-date/src/index.js b/packages/netlify-cms-widget-date/src/index.js deleted file mode 100644 index 4060a680..00000000 --- a/packages/netlify-cms-widget-date/src/index.js +++ /dev/null @@ -1,14 +0,0 @@ -import controlComponent from './DateControl'; -import previewComponent from './DatePreview'; - -function Widget(opts = {}) { - return { - name: 'date', - controlComponent, - previewComponent, - ...opts, - }; -} - -export const NetlifyCmsWidgetDate = { Widget, controlComponent, previewComponent }; -export default NetlifyCmsWidgetDate; diff --git a/packages/netlify-cms-widget-date/webpack.config.js b/packages/netlify-cms-widget-date/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-date/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-datetime/CHANGELOG.md b/packages/netlify-cms-widget-datetime/CHANGELOG.md deleted file mode 100644 index a2cc949b..00000000 --- a/packages/netlify-cms-widget-datetime/CHANGELOG.md +++ /dev/null @@ -1,383 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.7.6](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-datetime@2.7.5...netlify-cms-widget-datetime@2.7.6) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.7.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-datetime@2.7.4...netlify-cms-widget-datetime@2.7.5) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.7.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-datetime@2.7.3...netlify-cms-widget-datetime@2.7.4) (2021-09-13) - - -### Bug Fixes - -* **deps:** update react-datetime ([#5803](https://github.com/netlify/netlify-cms/issues/5803)) ([477efa5](https://github.com/netlify/netlify-cms/commit/477efa58f1a26e60c9ba5c0405e11132ecb7c68a)) - - - - - -## [2.7.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-datetime@2.7.2...netlify-cms-widget-datetime@2.7.3) (2021-08-17) - - -### Bug Fixes - -* make 'now' button consistent ([#5716](https://github.com/netlify/netlify-cms/issues/5716)) ([97de9da](https://github.com/netlify/netlify-cms/commit/97de9da948fff3b132d4d31c5f9069780abf3cc6)) - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.7.1...netlify-cms-widget-datetime@2.7.2) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.7.0...netlify-cms-widget-datetime@2.7.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update dependency react-datetime to v3 ([#5383](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/5383)) ([a2735b5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/a2735b5fd68470821841f608ce2123e8ce74c4e0)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.8...netlify-cms-widget-datetime@2.7.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.6.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.7...netlify-cms-widget-datetime@2.6.8) (2021-02-25) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.6.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.6...netlify-cms-widget-datetime@2.6.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.6.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.5...netlify-cms-widget-datetime@2.6.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.6.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.4...netlify-cms-widget-datetime@2.6.5) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.6.3...netlify-cms-widget-datetime@2.6.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## 2.6.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.6.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.6.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.5.0...netlify-cms-widget-datetime@2.6.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.4.0...netlify-cms-widget-datetime@2.5.0) (2020-05-19) - - -### Features - -* add pickerUtc option to datetime widget ([#3721](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/3721)) ([ef5ff03](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/ef5ff031dab99f73468c32835e2d94311967e09c)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.3.0...netlify-cms-widget-datetime@2.4.0) (2020-04-14) - - -### Features - -* **widget-datetime:** add now to datepicker ([#3484](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/3484)) ([79b8469](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/79b8469337dade3bd7472b3f42b826efc7e0987d)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.6...netlify-cms-widget-datetime@2.3.0) (2020-04-07) - - -### Features - -* **yaml:** support comments ([#3529](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/3529)) ([4afbbdd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/4afbbdd8a99241d239f28c5be544bb0ca77e345b)) - - - - - -## [2.2.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.5...netlify-cms-widget-datetime@2.2.6) (2020-02-17) - - -### Bug Fixes - -* **widget-datetime:** use default value when value is undefined ([#3269](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/3269)) ([8cc5fcb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/8cc5fcbb1957b224fe3adb01364eb0de658ad666)) - - - - - -## [2.2.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.4...netlify-cms-widget-datetime@2.2.5) (2019-11-07) - - -### Bug Fixes - -* **widget-date:** allow empty value ([#2705](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2705)) ([d058697](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/d0586976443c4255ba122fba33bbe045069fc461)) - - - - - -## [2.2.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.3...netlify-cms-widget-datetime@2.2.4) (2019-09-26) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.2...netlify-cms-widget-datetime@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.2-beta.0...netlify-cms-widget-datetime@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.1...netlify-cms-widget-datetime@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.1-beta.2...netlify-cms-widget-datetime@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.1-beta.1...netlify-cms-widget-datetime@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.1-beta.0...netlify-cms-widget-datetime@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.2.0...netlify-cms-widget-datetime@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.1.0...netlify-cms-widget-datetime@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.1.0-beta.0...netlify-cms-widget-datetime@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.8-beta.0...netlify-cms-widget-datetime@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/82cc794)) - - - - - -## [2.0.8-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.7...netlify-cms-widget-datetime@2.0.8-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/commit/ccef446)) - - - - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.6...netlify-cms-widget-datetime@2.0.7) (2018-11-29) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.5...netlify-cms-widget-datetime@2.0.6) (2018-11-12) - -**Note:** Version bump only for package netlify-cms-widget-datetime - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.4...netlify-cms-widget-datetime@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-datetime - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.3...netlify-cms-widget-datetime@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-datetime - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.2...netlify-cms-widget-datetime@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-datetime - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime/compare/netlify-cms-widget-datetime@2.0.1...netlify-cms-widget-datetime@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-datetime - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-datetime diff --git a/packages/netlify-cms-widget-datetime/README.md b/packages/netlify-cms-widget-datetime/README.md deleted file mode 100644 index 7333c130..00000000 --- a/packages/netlify-cms-widget-datetime/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-datetime/README.md)! diff --git a/packages/netlify-cms-widget-datetime/package.json b/packages/netlify-cms-widget-datetime/package.json deleted file mode 100644 index e4c3c723..00000000 --- a/packages/netlify-cms-widget-datetime/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "netlify-cms-widget-datetime", - "description": "Widget for editing dates and times in Netlify CMS.", - "version": "2.7.6", - "homepage": "https://www.netlifycms.org/docs/widgets/#datetime", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-datetime", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-datetime.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "date", - "time", - "datetime" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "netlify-cms-widget-date": "^2.5.7", - "react": "^16.8.4 || ^17.0.0" - }, - "dependencies": { - "react-datetime": "^3.1.1" - } -} diff --git a/packages/netlify-cms-widget-datetime/webpack.config.js b/packages/netlify-cms-widget-datetime/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-datetime/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-file/CHANGELOG.md b/packages/netlify-cms-widget-file/CHANGELOG.md deleted file mode 100644 index 82b1150c..00000000 --- a/packages/netlify-cms-widget-file/CHANGELOG.md +++ /dev/null @@ -1,476 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.12.5](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.12.4...netlify-cms-widget-file@2.12.5) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.12.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.12.3...netlify-cms-widget-file@2.12.4) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.12.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.12.2...netlify-cms-widget-file@2.12.3) (2022-09-09) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.12.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.12.1...netlify-cms-widget-file@2.12.2) (2022-09-08) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.12.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.12.0...netlify-cms-widget-file@2.12.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.11.1...netlify-cms-widget-file@2.12.0) (2022-03-28) - - -### Features - -* **image-widget:** media library gallery tools ([#6087](https://github.com/netlify/netlify-cms/issues/6087)) ([#6236](https://github.com/netlify/netlify-cms/issues/6236)) ([80c577a](https://github.com/netlify/netlify-cms/commit/80c577a462e91e29ce3517cf1419af35d9de3928)) - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.11.0...netlify-cms-widget-file@2.11.1) (2021-08-17) - - -### Bug Fixes - -* **deps:** update dependency array-move to v4 ([#5713](https://github.com/netlify/netlify-cms/issues/5713)) ([ca06a0b](https://github.com/netlify/netlify-cms/commit/ca06a0b23ec0885be0b80caf1cbf37b083a47f42)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-file@2.10.1...netlify-cms-widget-file@2.11.0) (2021-07-05) - - -### Features - -* image widget insert from url should be optional ([#5572](https://github.com/netlify/netlify-cms/issues/5572)) ([18724ff](https://github.com/netlify/netlify-cms/commit/18724ff991c4b8b16de1df40511dad368578a4b2)) - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.10.0...netlify-cms-widget-file@2.10.1) (2021-05-12) - - -### Bug Fixes - -* **deps:** update dependency react-sortable-hoc to v2 ([#5371](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/5371)) ([b5dabc2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/b5dabc212953348bee83d41c36ca1f949c87b6b5)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.9.2...netlify-cms-widget-file@2.10.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.9.1...netlify-cms-widget-file@2.9.2) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.9.0...netlify-cms-widget-file@2.9.1) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.8.0...netlify-cms-widget-file@2.9.0) (2021-02-01) - - -### Features - -* **widget-image:** enable images ordering ([#4857](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/4857)) ([30c1195](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/30c11954d586c43a00c8c61fa467873bfe1ed1fc)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.7.4...netlify-cms-widget-file@2.8.0) (2021-01-14) - - -### Features - -* **widget-file:** allow adding file from url ([#4700](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/4700)) ([9e277ad](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/9e277ad851ea598405e02a7c11624f337da18260)) - - - - - -## [2.7.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.7.3...netlify-cms-widget-file@2.7.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## 2.7.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.7.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.7.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.6.4...netlify-cms-widget-file@2.7.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.6.3...netlify-cms-widget-file@2.6.4) (2020-04-06) - - -### Bug Fixes - -* **widget-image:** multiple image support ([#3538](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3538)) ([76732f7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/76732f7208d8f46bbb6fd009729639ded30fae6e)) - - - - - -## [2.6.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.6.2...netlify-cms-widget-file@2.6.3) (2020-03-30) - - -### Bug Fixes - -* allow widgets to control value to be validated ([#3448](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3448)) ([ae1917c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/ae1917c8181892a439d0828d98992788fb48d65c)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.6.1...netlify-cms-widget-file@2.6.2) (2020-02-14) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.6.0...netlify-cms-widget-file@2.6.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.5.3...netlify-cms-widget-file@2.6.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.5.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.5.2...netlify-cms-widget-file@2.5.3) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## [2.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.5.1...netlify-cms-widget-file@2.5.2) (2020-01-26) - - -### Bug Fixes - -* **media-library:** pass correct value to Asset component ([#3140](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3140)) ([b1026c9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/b1026c980c70f0b45b47cbe555f4984aa9eea310)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.5.0...netlify-cms-widget-file@2.5.1) (2020-01-23) - - -### Bug Fixes - -* **widget-image:** hide image overflow in widget control ([#3131](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/3131)) ([db2cbb6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/db2cbb6f5d4136cc7fadba1c2d8977b0fd813c9b)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.5.0-beta.0...netlify-cms-widget-file@2.5.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.3...netlify-cms-widget-file@2.5.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -## [2.4.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.2...netlify-cms-widget-file@2.4.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.2-beta.0...netlify-cms-widget-file@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.1...netlify-cms-widget-file@2.4.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.1-beta.2...netlify-cms-widget-file@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.4.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.1-beta.1...netlify-cms-widget-file@2.4.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.1-beta.0...netlify-cms-widget-file@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.4.0...netlify-cms-widget-file@2.4.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/7987091)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.3.0...netlify-cms-widget-file@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/d142b32)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.3.0-beta.0...netlify-cms-widget-file@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.2.1-beta.0...netlify-cms-widget-file@2.3.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/82cc794)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.2.1-alpha.0...netlify-cms-widget-file@2.2.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/ccef446)) - - - - - -## [2.2.1-alpha.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.2.0...netlify-cms-widget-file@2.2.1-alpha.0) (2019-03-14) - -**Note:** Version bump only for package netlify-cms-widget-file - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.1.0...netlify-cms-widget-file@2.2.0) (2018-12-04) - - -### Features - -* add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/1fc2f50)) - - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.0.5...netlify-cms-widget-file@2.1.0) (2018-09-06) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/commit/0596904)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.0.4...netlify-cms-widget-file@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-file - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.0.3...netlify-cms-widget-file@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-file - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.0.2...netlify-cms-widget-file@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-file - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file/compare/netlify-cms-widget-file@2.0.1...netlify-cms-widget-file@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-file - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-file diff --git a/packages/netlify-cms-widget-file/README.md b/packages/netlify-cms-widget-file/README.md deleted file mode 100644 index 79ab5db0..00000000 --- a/packages/netlify-cms-widget-file/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-file/README.md)! diff --git a/packages/netlify-cms-widget-file/package.json b/packages/netlify-cms-widget-file/package.json deleted file mode 100644 index 0fcc44ec..00000000 --- a/packages/netlify-cms-widget-file/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "netlify-cms-widget-file", - "description": "Widget for uploading files in Netlify CMS.", - "version": "2.12.5", - "homepage": "https://www.netlifycms.org/docs/widgets/#file", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-file", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-file.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "file", - "upload", - "file-upload" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "array-move": "4.0.0", - "common-tags": "^1.8.0", - "react-sortable-hoc": "^2.0.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0", - "uuid": "^3.3.2" - } -} diff --git a/packages/netlify-cms-widget-file/webpack.config.js b/packages/netlify-cms-widget-file/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-file/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-image/CHANGELOG.md b/packages/netlify-cms-widget-image/CHANGELOG.md deleted file mode 100644 index 9f1adc9e..00000000 --- a/packages/netlify-cms-widget-image/CHANGELOG.md +++ /dev/null @@ -1,355 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.8.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-image@2.8.2...netlify-cms-widget-image@2.8.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.8.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-image@2.8.1...netlify-cms-widget-image@2.8.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.8.0...netlify-cms-widget-image@2.8.1) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.7.7...netlify-cms-widget-image@2.8.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.7.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.7.6...netlify-cms-widget-image@2.7.7) (2021-02-25) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.7.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.7.5...netlify-cms-widget-image@2.7.6) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.7.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.7.4...netlify-cms-widget-image@2.7.5) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.7.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.7.3...netlify-cms-widget-image@2.7.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## 2.7.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.7.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.7.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.6.2...netlify-cms-widget-image@2.7.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.6.1...netlify-cms-widget-image@2.6.2) (2020-02-14) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.6.0...netlify-cms-widget-image@2.6.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.5.0...netlify-cms-widget-image@2.6.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.5.0-beta.0...netlify-cms-widget-image@2.5.0) (2020-01-07) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.4.0...netlify-cms-widget-image@2.5.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.3...netlify-cms-widget-image@2.4.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.2...netlify-cms-widget-image@2.3.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.2-beta.0...netlify-cms-widget-image@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.1...netlify-cms-widget-image@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.1-beta.2...netlify-cms-widget-image@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.1-beta.1...netlify-cms-widget-image@2.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.1-beta.0...netlify-cms-widget-image@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.3.0...netlify-cms-widget-image@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.2.0...netlify-cms-widget-image@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.2.0-beta.0...netlify-cms-widget-image@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.1.2-beta.0...netlify-cms-widget-image@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/82cc794)) - - - - - -## [2.1.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.1.2-alpha.0...netlify-cms-widget-image@2.1.2-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/ccef446)) - - - - - -## [2.1.2-alpha.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.1.1...netlify-cms-widget-image@2.1.2-alpha.0) (2019-03-14) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.1.0...netlify-cms-widget-image@2.1.1) (2018-12-04) - -**Note:** Version bump only for package netlify-cms-widget-image - - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.0.5...netlify-cms-widget-image@2.1.0) (2018-09-06) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/commit/0596904)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.0.4...netlify-cms-widget-image@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-image - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.0.3...netlify-cms-widget-image@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-image - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.0.2...netlify-cms-widget-image@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-image - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image/compare/netlify-cms-widget-image@2.0.1...netlify-cms-widget-image@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-image - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-image diff --git a/packages/netlify-cms-widget-image/README.md b/packages/netlify-cms-widget-image/README.md deleted file mode 100644 index 423fc8d8..00000000 --- a/packages/netlify-cms-widget-image/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-image/README.md)! diff --git a/packages/netlify-cms-widget-image/package.json b/packages/netlify-cms-widget-image/package.json deleted file mode 100644 index a9396d5c..00000000 --- a/packages/netlify-cms-widget-image/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "netlify-cms-widget-image", - "description": "Widget for uploading images in Netlify CMS.", - "version": "2.8.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#image", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-image", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-image.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "image", - "upload", - "image-upload" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "netlify-cms-ui-default": "^2.12.1", - "netlify-cms-widget-file": "^2.9.2", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-image/webpack.config.js b/packages/netlify-cms-widget-image/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-image/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-list/CHANGELOG.md b/packages/netlify-cms-widget-list/CHANGELOG.md deleted file mode 100644 index ecd7631b..00000000 --- a/packages/netlify-cms-widget-list/CHANGELOG.md +++ /dev/null @@ -1,553 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.10.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-list@2.10.2...netlify-cms-widget-list@2.10.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.10.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-list@2.10.1...netlify-cms-widget-list@2.10.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-list@2.10.0...netlify-cms-widget-list@2.10.1) (2021-08-04) - - -### Bug Fixes - -* **widget-list:** add missing translations in widget list top bar ([#5471](https://github.com/netlify/netlify-cms/issues/5471)) ([#5679](https://github.com/netlify/netlify-cms/issues/5679)) ([db560cc](https://github.com/netlify/netlify-cms/commit/db560cc082fcc0a9842919e28f715e44a6e4625a)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-list@2.9.3...netlify-cms-widget-list@2.10.0) (2021-07-14) - - -### Features - -* **list:** Add heading for list widgets ([#5544](https://github.com/netlify/netlify-cms/issues/5544)) ([d60df87](https://github.com/netlify/netlify-cms/commit/d60df8786d7ea01af94c86a6e889654ce20e53ca)) - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-list@2.9.2...netlify-cms-widget-list@2.9.3) (2021-07-07) - - -### Bug Fixes - -* **list-control:** better value validation ([#5592](https://github.com/netlify/netlify-cms/issues/5592)) ([fb0f825](https://github.com/netlify/netlify-cms/commit/fb0f8259eae60c27a3a35c3db834c8311131d328)) - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.9.1...netlify-cms-widget-list@2.9.2) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.9.0...netlify-cms-widget-list@2.9.1) (2021-05-12) - - -### Bug Fixes - -* **deps:** update dependency react-sortable-hoc to v2 ([#5371](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/5371)) ([b5dabc2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/b5dabc212953348bee83d41c36ca1f949c87b6b5)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.5...netlify-cms-widget-list@2.9.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.8.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.4...netlify-cms-widget-list@2.8.5) (2021-04-06) - - -### Bug Fixes - -* allow any default list as default value for list widgets ([#5030](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/5030)) ([83c2354](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/83c235423e76023fe10f167c8f9087cba7a4c922)) - - - - - -## [2.8.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.3...netlify-cms-widget-list@2.8.4) (2021-02-25) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.8.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.2...netlify-cms-widget-list@2.8.3) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.8.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.1...netlify-cms-widget-list@2.8.2) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.8.0...netlify-cms-widget-list@2.8.1) (2020-11-26) - - -### Bug Fixes - -* list markdown widgets ([#4492](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/4492)) ([4789d20](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/4789d205386f589c3556df32700df25ad078904f)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.7.0...netlify-cms-widget-list@2.8.0) (2020-10-25) - - -### Bug Fixes - -* **widget-list:** don't split an empty string ([#4464](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/4464)) ([f3a8eac](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/f3a8eac816710dbc639ad40b06742fa90885e613)) - - -### Features - -* add add_to_top option to list widget ([#4465](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/4465)) ([4c962f9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/4c962f9149722074652c8939486650a4ddb1d7b3)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.6.6...netlify-cms-widget-list@2.7.0) (2020-10-20) - - -### Features - -* **widget-list:** add min max configuration ([#4394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/4394)) ([5fdfe40](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/5fdfe40dd29e9e22c9ae7d6219bc057f7ea7280b)) - - - - - -## [2.6.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.6.5...netlify-cms-widget-list@2.6.6) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.6.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.6.4...netlify-cms-widget-list@2.6.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## 2.6.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.6.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.6.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.6.0...netlify-cms-widget-list@2.6.1) (2020-07-16) - - -### Bug Fixes - -* **prop-types:** check for react components via PropTypes.elementType ([#4025](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/4025)) ([d3831b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/d3831b1ed44fcff51a63f6645a5aa68332467dab)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.5.1...netlify-cms-widget-list@2.6.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.5.0...netlify-cms-widget-list@2.5.1) (2020-06-01) - - -### Bug Fixes - -* Error UI improvements for nested lists/objects ([#3726](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3726)) ([3978578](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/397857855b2c8514c2f7ce83756af6b6698abc3d)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.6...netlify-cms-widget-list@2.5.0) (2020-05-19) - - -### Features - -* **netlify-cms-widget-list:** allow 'summary' field ([#3616](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3616)) ([7cc4c89](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/7cc4c89539ddbd410ec7a1767c66f04e8d711cc5)) -* **widget-list:** add hiding list content with minimize_collapsed option ([#3607](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3607)) ([4dd58c5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/4dd58c5dcb22f4c0456a36d6c38883b54d8a7c4d)) - - - - - -## [2.4.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.4...netlify-cms-widget-list@2.4.6) (2020-05-04) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.4.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.3...netlify-cms-widget-list@2.4.4) (2020-04-20) - - -### Bug Fixes - -* list widget item collapse toggle ([#3623](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3623)) ([3a666e2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/3a666e26b507f16767d0dafb82cd8a030424eec3)) -* list widget validation after sort ([#3611](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3611)) ([3d0856e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/3d0856ea884f5acdceb23ea09e39fb67b0c902a9)) - - - - - -## [2.4.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.2...netlify-cms-widget-list@2.4.3) (2020-02-14) - - -### Bug Fixes - -* remove empty list item ([#3245](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3245)) ([f915bf3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/f915bf375fc8faa9b4ed5b3684861dfbe462a032)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.1...netlify-cms-widget-list@2.4.2) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.0...netlify-cms-widget-list@2.4.1) (2020-01-07) - - -### Bug Fixes - -* cleanup nested widget validation ([#2991](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2991)) ([e4ba4d9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/e4ba4d9d749c864e594c10e0bb31b0b8c4e6e60b)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.4.0-beta.0...netlify-cms-widget-list@2.4.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -# [2.4.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.5-beta.1...netlify-cms-widget-list@2.4.0-beta.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.3.5-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.5-beta.0...netlify-cms-widget-list@2.3.5-beta.1) (2019-11-07) - - -### Bug Fixes - -* **widget-list:** when single field value is object widget ([#2387](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2387)) ([90748ff](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/90748ff4fe25f47dfc6aabd46cfc02df079bc126)) - - - - - -## [2.3.5-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.4...netlify-cms-widget-list@2.3.5-beta.0) (2019-09-04) - - -### Bug Fixes - -* pass List instead of array to onChange ([#2611](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2611)) ([a801636](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/a801636)) - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.3...netlify-cms-widget-list@2.3.4) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.2...netlify-cms-widget-list@2.3.3) (2019-07-11) - - -### Bug Fixes - -* **widget-list:** honor default values for widgets in lists ([#2395](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2395)) ([83bd5d5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/83bd5d5)) - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.2-beta.0...netlify-cms-widget-list@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.1...netlify-cms-widget-list@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.1-beta.2...netlify-cms-widget-list@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.1-beta.1...netlify-cms-widget-list@2.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.1-beta.0...netlify-cms-widget-list@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.3.0...netlify-cms-widget-list@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.2.0...netlify-cms-widget-list@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.2.0-beta.0...netlify-cms-widget-list@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-list - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.1.2-beta.0...netlify-cms-widget-list@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/82cc794)) - - - - - -## [2.1.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.1.1...netlify-cms-widget-list@2.1.2-beta.0) (2019-03-15) - - -### Bug Fixes - -* **deps:** update dependency react-sortable-hoc to v1 ([#2198](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2198)) ([b5180e9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/b5180e9)) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/ccef446)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.1.0...netlify-cms-widget-list@2.1.1) (2019-02-08) - - -### Bug Fixes - -* **netlify-cms-core:** fix fields metadata for objects and lists ([#2011](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/2011)) ([2d1d1c1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/2d1d1c1)) -* **netlify-cms-core:** validate nested fields ([#1873](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/1873)) ([627e600](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/627e600)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.7...netlify-cms-widget-list@2.1.0) (2018-12-27) - - -### Features - -* **netlify-cms-widget-list:** add variable type definitions to list widget ([#1857](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/1857)) ([8ddc168](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/8ddc168)) - - - - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.6...netlify-cms-widget-list@2.0.7) (2018-11-12) - - -### Bug Fixes - -* **widget-list:** fix list item deletion ([#1815](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/1815)) ([cd2036f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/cd2036f)) - - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.5...netlify-cms-widget-list@2.0.6) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-widget-list - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.4...netlify-cms-widget-list@2.0.5) (2018-08-24) - - -### Bug Fixes - -* **list-widget:** fix single field usage in list widget ([#1395](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/issues/1395)) ([06d3650](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/commit/06d3650)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.3...netlify-cms-widget-list@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-list - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.2...netlify-cms-widget-list@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-list - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list/compare/netlify-cms-widget-list@2.0.1...netlify-cms-widget-list@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-list - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-list diff --git a/packages/netlify-cms-widget-list/README.md b/packages/netlify-cms-widget-list/README.md deleted file mode 100644 index 168c1e29..00000000 --- a/packages/netlify-cms-widget-list/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-list/README.md)! diff --git a/packages/netlify-cms-widget-list/package.json b/packages/netlify-cms-widget-list/package.json deleted file mode 100644 index 1b6c178d..00000000 --- a/packages/netlify-cms-widget-list/package.json +++ /dev/null @@ -1,39 +0,0 @@ -{ - "name": "netlify-cms-widget-list", - "description": "Widget for editing lists in Netlify CMS.", - "version": "2.10.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#list", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-list", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-list.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "list", - "object" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-sortable-hoc": "^2.0.0" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-lib-widgets": "^1.6.1", - "netlify-cms-ui-default": "^2.12.1", - "netlify-cms-widget-object": "^2.6.2", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - } -} diff --git a/packages/netlify-cms-widget-list/src/__tests__/ListControl.spec.js b/packages/netlify-cms-widget-list/src/__tests__/ListControl.spec.js deleted file mode 100644 index 360958b2..00000000 --- a/packages/netlify-cms-widget-list/src/__tests__/ListControl.spec.js +++ /dev/null @@ -1,792 +0,0 @@ -import React from 'react'; -import { fireEvent, render } from '@testing-library/react'; -import { fromJS } from 'immutable'; - -import ListControl from '../ListControl'; - -jest.mock('netlify-cms-widget-object', () => { - const React = require('react'); - - class MockObjectControl extends React.Component { - render() { - return {this.props.children}; - } - } - - return { - controlComponent: MockObjectControl, - }; -}); -jest.mock('netlify-cms-ui-default', () => { - const actual = jest.requireActual('netlify-cms-ui-default'); - - function ListItemTopBar(props) { - return ( - - - {props.children} - - ); - } - - return { - ...actual, - ListItemTopBar, - }; -}); -jest.mock('uuid/v4'); - -describe('ListControl', () => { - const props = { - onChange: jest.fn(), - onChangeObject: jest.fn(), - onValidateObject: jest.fn(), - validate: jest.fn(), - mediaPaths: fromJS({}), - getAsset: jest.fn(), - onOpenMediaLibrary: jest.fn(), - onAddAsset: jest.fn(), - onRemoveInsertedMedia: jest.fn(), - classNameWrapper: 'classNameWrapper', - setActiveStyle: jest.fn(), - setInactiveStyle: jest.fn(), - editorControl: jest.fn(), - resolveWidget: jest.fn(), - clearFieldErrors: jest.fn(), - fieldsErrors: fromJS({}), - entry: fromJS({ - path: 'posts/index.md', - }), - forID: 'forID', - t: key => key, - }; - - beforeEach(() => { - jest.clearAllMocks(); - const uuid = require('uuid/v4'); - let id = 0; - uuid.mockImplementation(() => { - return id++; - }); - }); - it('should render empty list', () => { - const field = fromJS({ name: 'list', label: 'List' }); - const { asFragment } = render(); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render list with string array', () => { - const field = fromJS({ name: 'list', label: 'List' }); - const { asFragment } = render( - , - ); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render list with nested object', () => { - const field = fromJS({ - name: 'list', - label: 'List', - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { asFragment, getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render list with nested object with collapse = false', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { asFragment, getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should collapse all items on top bar collapse click', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - - fireEvent.click(getByTestId('expand-button')); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - }); - - it('should collapse a single item on collapse item click', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - - fireEvent.click(getByTestId('styled-list-item-top-bar-0')); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - }); - - it('should expand all items on top bar expand click', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - - fireEvent.click(getByTestId('expand-button')); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - }); - - it('should expand a single item on expand item click', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - field: { - name: 'object', - widget: 'object', - label: 'Object', - fields: [{ name: 'title', widget: 'string', label: 'Title' }], - }, - }); - const { getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - - fireEvent.click(getByTestId('styled-list-item-top-bar-0')); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - }); - - it('should use widget name when no summary or label are configured for mixed types', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - types: [ - { - name: 'type_1_object', - widget: 'object', - fields: [ - { label: 'First Name', name: 'first_name', widget: 'string' }, - { label: 'Last Name', name: 'last_name', widget: 'string' }, - ], - }, - ], - }); - - const { getAllByText } = render( - , - ); - expect(getAllByText('type_1_object')[1]).toBeInTheDocument(); - }); - - it('should use label when no summary is configured for mixed types', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - types: [ - { - label: 'Type 1 Object', - name: 'type_1_object', - widget: 'object', - fields: [ - { label: 'First Name', name: 'first_name', widget: 'string' }, - { label: 'Last Name', name: 'last_name', widget: 'string' }, - ], - }, - ], - }); - - const { getAllByText } = render( - , - ); - expect(getAllByText('Type 1 Object')[1]).toBeInTheDocument(); - }); - - it('should use summary when configured for mixed types', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - types: [ - { - label: 'Type 1 Object', - name: 'type_1_object', - summary: '{{first_name}} - {{last_name}} - {{filename}}.{{extension}}', - widget: 'object', - fields: [ - { label: 'First Name', name: 'first_name', widget: 'string' }, - { label: 'Last Name', name: 'last_name', widget: 'string' }, - ], - }, - ], - }); - - const { getByText } = render( - , - ); - expect(getByText('hello - world - index.md')).toBeInTheDocument(); - }); - - it('should use widget name when no summary or label are configured for a single field', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - field: { name: 'name', widget: 'string' }, - }); - - const { getByText } = render(); - expect(getByText('name')).toBeInTheDocument(); - }); - - it('should use label when no summary is configured for a single field', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - field: { name: 'name', widget: 'string', label: 'Name' }, - }); - - const { getByText } = render(); - expect(getByText('Name')).toBeInTheDocument(); - }); - - it('should use summary when configured for a single field', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - summary: 'Name - {{fields.name}}', - field: { name: 'name', widget: 'string', label: 'Name' }, - }); - - const { getByText } = render(); - expect(getByText('Name - Name')).toBeInTheDocument(); - }); - - it('should use first field value when no summary or label are configured for multiple fields', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - fields: [ - { name: 'first_name', widget: 'string', label: 'First Name' }, - { name: 'last_name', widget: 'string', label: 'Last Name' }, - ], - }); - - const { getByText } = render( - , - ); - expect(getByText('hello')).toBeInTheDocument(); - }); - - it('should show `No ` when value is missing from first field for multiple fields', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - fields: [ - { name: 'first_name', widget: 'string', label: 'First Name' }, - { name: 'last_name', widget: 'string', label: 'Last Name' }, - ], - }); - - const { getByText } = render( - , - ); - expect(getByText('No first_name')).toBeInTheDocument(); - }); - - it('should use summary when configured for multiple fields', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: true, - summary: '{{first_name}} - {{last_name}} - {{filename}}.{{extension}}', - fields: [ - { name: 'first_name', widget: 'string', label: 'First Name' }, - { name: 'last_name', widget: 'string', label: 'Last Name' }, - ], - }); - - const { getByText } = render( - , - ); - expect(getByText('hello - world - index.md')).toBeInTheDocument(); - }); - - it('should render list with fields with default collapse ("true") and minimize_collapsed ("false")', () => { - const field = fromJS({ - name: 'list', - label: 'List', - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render list with fields with collapse = "false" and default minimize_collapsed ("false")', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should render list with fields with default collapse ("true") and minimize_collapsed = "true"', () => { - const field = fromJS({ - name: 'list', - label: 'List', - minimize_collapsed: true, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getByTestId, queryByTestId } = render( - , - ); - - expect(queryByTestId('styled-list-item-top-bar-0')).toBeNull(); - expect(queryByTestId('styled-list-item-top-bar-1')).toBeNull(); - - expect(queryByTestId('object-control-0')).toBeNull(); - expect(queryByTestId('object-control-1')).toBeNull(); - - expect(asFragment()).toMatchSnapshot(); - - fireEvent.click(getByTestId('expand-button')); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'true'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'true'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'true'); - }); - - it('should render list with fields with collapse = "false" and default minimize_collapsed = "true"', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getByTestId, queryByTestId } = render( - , - ); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('styled-list-item-top-bar-1')).toHaveAttribute('collapsed', 'false'); - - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-1')).toHaveAttribute('collapsed', 'false'); - - expect(asFragment()).toMatchSnapshot(); - - fireEvent.click(getByTestId('expand-button')); - - expect(queryByTestId('styled-list-item-top-bar-0')).toBeNull(); - expect(queryByTestId('styled-list-item-top-bar-1')).toBeNull(); - - expect(queryByTestId('object-control-0')).toBeNull(); - expect(queryByTestId('object-control-1')).toBeNull(); - }); - - it('should add to list when add button is clicked', () => { - const field = fromJS({ - name: 'list', - label: 'List', - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getByText, queryByTestId, rerender, getByTestId } = render( - , - ); - - expect(queryByTestId('object-control-0')).toBeNull(); - - fireEvent.click(getByText('editor.editorWidgets.list.add')); - - expect(props.onChange).toHaveBeenCalledTimes(1); - expect(props.onChange).toHaveBeenCalledWith(fromJS([{}])); - - rerender(); - - expect(getByTestId('styled-list-item-top-bar-0')).toHaveAttribute('collapsed', 'false'); - expect(getByTestId('object-control-0')).toHaveAttribute('collapsed', 'false'); - - expect(asFragment()).toMatchSnapshot(); - }); - - it('should remove from list when remove button is clicked', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const { asFragment, getAllByText, rerender } = render( - , - ); - - expect(asFragment()).toMatchSnapshot(); - - let mock; - try { - mock = jest.spyOn(console, 'error').mockImplementation(() => undefined); - - const items = getAllByText('Remove'); - fireEvent.click(items[0]); - - expect(props.onChange).toHaveBeenCalledTimes(1); - expect(props.onChange).toHaveBeenCalledWith(fromJS([{ string: 'item 2' }]), undefined); - - rerender(); - - expect(asFragment()).toMatchSnapshot(); - } finally { - mock.mockRestore(); - } - }); - - it('should give validation error if below min elements', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: true, - min: 2, - max: 3, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([{ string: 'item 1' }]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', [ - { - message: 'editor.editorControlPane.widget.rangeCount', - type: 'RANGE', - }, - ]); - }); - - it('should give min validation error if below min elements', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: true, - min: 2, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([{ string: 'item 1' }]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', [ - { - message: 'editor.editorControlPane.widget.rangeMin', - type: 'RANGE', - }, - ]); - }); - - it('should give validation error if above max elements', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: true, - min: 2, - max: 3, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([ - { string: 'item 1' }, - { string: 'item 2' }, - { string: 'item 3' }, - { string: 'item 4' }, - ]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', [ - { - message: 'editor.editorControlPane.widget.rangeCount', - type: 'RANGE', - }, - ]); - }); - - it('should give max validation error if above max elements', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: true, - max: 3, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([ - { string: 'item 1' }, - { string: 'item 2' }, - { string: 'item 3' }, - { string: 'item 4' }, - ]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', [ - { - message: 'editor.editorControlPane.widget.rangeMax', - type: 'RANGE', - }, - ]); - }); - - it('should give no validation error if between min and max elements', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: true, - min: 2, - max: 3, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([{ string: 'item 1' }, { string: 'item 2' }, { string: 'item 3' }]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', []); - }); - - it('should give no validation error if no elements and optional', () => { - const field = fromJS({ - name: 'list', - label: 'List', - collapsed: false, - minimize_collapsed: true, - required: false, - min: 2, - max: 3, - fields: [{ label: 'String', name: 'string', widget: 'string' }], - }); - const listControl = new ListControl({ - ...props, - field, - value: fromJS([]), - }); - - listControl.validate(); - expect(props.onValidateObject).toHaveBeenCalledWith('forID', []); - }); -}); diff --git a/packages/netlify-cms-widget-list/src/__tests__/__snapshots__/ListControl.spec.js.snap b/packages/netlify-cms-widget-list/src/__tests__/__snapshots__/ListControl.spec.js.snap deleted file mode 100644 index 069e7a49..00000000 --- a/packages/netlify-cms-widget-list/src/__tests__/__snapshots__/ListControl.spec.js.snap +++ /dev/null @@ -1,2213 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`ListControl should add to list when add button is clicked 1`] = ` - - .emotion-18 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: none; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 1 list -
    - -
    -
    -
    - - - -
    - No string -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should remove from list when remove button is clicked 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: none; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - item 1 -
    - -
    -
    - - - -
    - item 2 -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should remove from list when remove button is clicked 2`] = ` - - .emotion-18 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; - padding-bottom: 0; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: block; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -
    -
    -
    - - 1 list -
    - -
    -
    -
    - - - -
    - item 2 -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render empty list 1`] = ` - - - -`; - -exports[`ListControl should render list with fields with collapse = "false" and default minimize_collapsed ("false") 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: none; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - item 1 -
    - -
    -
    - - - -
    - item 2 -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render list with fields with collapse = "false" and default minimize_collapsed = "true" 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: none; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - item 1 -
    - -
    -
    - - - -
    - item 2 -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render list with fields with default collapse ("true") and minimize_collapsed ("false") 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; - padding-bottom: 0; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: block; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - item 1 -
    - -
    -
    - - - -
    - item 2 -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render list with fields with default collapse ("true") and minimize_collapsed = "true" 1`] = ` - - .emotion-14 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    -`; - -exports[`ListControl should render list with nested object 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; - padding-bottom: 0; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: block; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - Object -
    - -
    -
    - - - -
    - Object -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render list with nested object with collapse = false 1`] = ` - - .emotion-22 { - padding: 0 14px 14px; -} - -.emotion-12 { - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - background-color: #dfdfe3; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: justify; - -webkit-justify-content: space-between; - -ms-flex-pack: justify; - justify-content: space-between; - margin: 0 -14px; - padding: 13px; -} - -.emotion-5 { - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - font-size: 14px; - font-weight: 500; - line-height: 1; -} - -.emotion-3 { - border: 0; - border-radius: 5px; - cursor: pointer; - padding: 4px; - background-color: transparent; - color: inherit; -} - -.emotion-3:last-of-type { - margin-right: 4px; -} - -.emotion-10 { - border: 0; - border-radius: 5px; - cursor: pointer; - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-box-pack: center; - -webkit-justify-content: center; - -ms-flex-pack: center; - justify-content: center; - -webkit-align-items: center; - -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; - padding: 2px 12px; - font-size: 12px; - font-weight: bold; - border-radius: 3px; -} - -.emotion-10 .emotion-0 { - margin-left: 6px; -} - -.emotion-8 { - display: inline-block; - line-height: 0; - width: 12px; - height: 12px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-8 path:not(.no-fill), -.emotion-8 circle:not(.no-fill), -.emotion-8 polygon:not(.no-fill), -.emotion-8 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-8 path.clipped { - fill: transparent; -} - -.emotion-8 svg { - width: 100%; - height: 100%; -} - -.emotion-1 { - display: inline-block; - line-height: 0; - width: 18px; - height: 18px; - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} - -.emotion-1 path:not(.no-fill), -.emotion-1 circle:not(.no-fill), -.emotion-1 polygon:not(.no-fill), -.emotion-1 rect:not(.no-fill) { - fill: currentColor; -} - -.emotion-1 path.clipped { - fill: transparent; -} - -.emotion-1 svg { - width: 100%; - height: 100%; -} - -.emotion-16 { - margin-top: 18px; -} - -.emotion-16:first-of-type { - margin-top: 26px; -} - -.emotion-14 { - display: none; - border-top: 0; - color: inherit; - background-color: #dfdfe3; - padding: 13px; - border-radius: 0 0 5px 5px; -} - -
    -
    -
    - - 2 list -
    - -
    -
    -
    - - - -
    - Object -
    - -
    -
    - - - -
    - Object -
    - -
    -
    -
    -
    -`; - -exports[`ListControl should render list with string array 1`] = ` - - - -`; diff --git a/packages/netlify-cms-widget-list/webpack.config.js b/packages/netlify-cms-widget-list/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-list/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-map/CHANGELOG.md b/packages/netlify-cms-widget-map/CHANGELOG.md deleted file mode 100644 index 9b7fe5bb..00000000 --- a/packages/netlify-cms-widget-map/CHANGELOG.md +++ /dev/null @@ -1,220 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [1.5.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-map@1.5.2...netlify-cms-widget-map@1.5.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.5.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-map@1.5.1...netlify-cms-widget-map@1.5.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.5.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-map@1.5.0...netlify-cms-widget-map@1.5.1) (2021-12-08) - - -### Bug Fixes - -* **widget-map:** update ol to latest version ([4a4adf0](https://github.com/netlify/netlify-cms/commit/4a4adf0dbd592639a3aab478c43bcc181657552e)) - - - - - -# [1.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.4.6...netlify-cms-widget-map@1.5.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [1.4.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.4.5...netlify-cms-widget-map@1.4.6) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.4.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.4.4...netlify-cms-widget-map@1.4.5) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.4.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.4.3...netlify-cms-widget-map@1.4.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## 1.4.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 1.4.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 1.4.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [1.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.3...netlify-cms-widget-map@1.4.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [1.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.2...netlify-cms-widget-map@1.3.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.2-beta.0...netlify-cms-widget-map@1.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.1...netlify-cms-widget-map@1.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.1-beta.2...netlify-cms-widget-map@1.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.1-beta.1...netlify-cms-widget-map@1.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -## [1.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.1-beta.0...netlify-cms-widget-map@1.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/6ffd13b)) - - - - - -## [1.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.3.0...netlify-cms-widget-map@1.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/7987091)) - - - - - -# [1.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.2.0...netlify-cms-widget-map@1.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/d142b32)) - - - - - -# [1.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.2.0-beta.0...netlify-cms-widget-map@1.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-map - - - - - -# [1.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.1.1-beta.0...netlify-cms-widget-map@1.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/82cc794)) - - - - - -## [1.1.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/compare/netlify-cms-widget-map@1.1.0...netlify-cms-widget-map@1.1.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/ccef446)) - - - - - -# 1.1.0 (2019-02-08) - - -### Features - -* **netlify-cms-widget-map:** add map widget ([#2051](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/issues/2051)) ([18f34d2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map/commit/18f34d2)) diff --git a/packages/netlify-cms-widget-map/README.md b/packages/netlify-cms-widget-map/README.md deleted file mode 100644 index efcf1fcf..00000000 --- a/packages/netlify-cms-widget-map/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-map/README.md)! diff --git a/packages/netlify-cms-widget-map/package.json b/packages/netlify-cms-widget-map/package.json deleted file mode 100644 index f53888b1..00000000 --- a/packages/netlify-cms-widget-map/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "netlify-cms-widget-map", - "description": "Widget for editing spatial data in Netlify CMS.", - "version": "1.5.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#map", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-map", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-map.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "spatial", - "map" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "lodash": "^4.17.11", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - }, - "dependencies": { - "ol": "^6.9.0" - } -} diff --git a/packages/netlify-cms-widget-map/webpack.config.js b/packages/netlify-cms-widget-map/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-map/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-markdown/CHANGELOG.md b/packages/netlify-cms-widget-markdown/CHANGELOG.md deleted file mode 100644 index 6b2e596e..00000000 --- a/packages/netlify-cms-widget-markdown/CHANGELOG.md +++ /dev/null @@ -1,814 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.15.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.15.2...netlify-cms-widget-markdown@2.15.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.15.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.15.1...netlify-cms-widget-markdown@2.15.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.15.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.15.0...netlify-cms-widget-markdown@2.15.1) (2022-04-13) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.15.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.14.4...netlify-cms-widget-markdown@2.15.0) (2022-01-21) - - -### Features - -* use keyboard shortcuts to insert bullet points ([#6134](https://github.com/netlify/netlify-cms/issues/6134)) ([dd149f6](https://github.com/netlify/netlify-cms/commit/dd149f6d0479d20eef0bc9cede738784c9cdb4fd)) - - - - - -## [2.14.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.14.3...netlify-cms-widget-markdown@2.14.4) (2021-10-28) - - -### Bug Fixes - -* **richtext:** improvement to the Rich Text Editor [#5446](https://github.com/netlify/netlify-cms/issues/5446) ([#5897](https://github.com/netlify/netlify-cms/issues/5897)) ([06c7e25](https://github.com/netlify/netlify-cms/commit/06c7e251ce5e97a4949aa308070c3a659b50c780)) - - - - - -## [2.14.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.14.2...netlify-cms-widget-markdown@2.14.3) (2021-10-28) - - -### Bug Fixes - -* dropdown overflow in markdown widget ([#5879](https://github.com/netlify/netlify-cms/issues/5879)) ([3ec1611](https://github.com/netlify/netlify-cms/commit/3ec161122d13e01dacb65fa9c109be9612b54d47)) - - - - - -## [2.14.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.14.1...netlify-cms-widget-markdown@2.14.2) (2021-08-17) - - -### Bug Fixes - -* **markdown-widget:** support arbitrary component order ([#5597](https://github.com/netlify/netlify-cms/issues/5597)) ([fbfab7c](https://github.com/netlify/netlify-cms/commit/fbfab7cda54aba68c948188d0ad5660431d275fc)) - - - - - -## [2.14.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.14.0...netlify-cms-widget-markdown@2.14.1) (2021-08-04) - - -### Bug Fixes - -* **markdown-widget:** apply list item style on each block in a selection ([#5676](https://github.com/netlify/netlify-cms/issues/5676)) ([04e5305](https://github.com/netlify/netlify-cms/commit/04e53054ceba8e2b6f3a2e7f1de5ecc3abe8431a)) - - - - - -# [2.14.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.13.6...netlify-cms-widget-markdown@2.14.0) (2021-07-25) - - -### Features - -* **widget-markdown:** allow registering remark plugins ([#5633](https://github.com/netlify/netlify-cms/issues/5633)) ([437f4bc](https://github.com/netlify/netlify-cms/commit/437f4bc634c5a52758bd06ab1709f2e66a71dce7)) - - - - - -## [2.13.6](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-markdown@2.13.5...netlify-cms-widget-markdown@2.13.6) (2021-07-25) - - -### Bug Fixes - -* **widget-markdown:** Hitting Enter key in a list item doesn't create a new list item ([#5550](https://github.com/netlify/netlify-cms/issues/5550)) ([ab3e8e1](https://github.com/netlify/netlify-cms/commit/ab3e8e1f5a5fecd343e32cc31912ec912449e713)) - - - - - -## [2.13.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.13.4...netlify-cms-widget-markdown@2.13.5) (2021-06-24) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.13.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.13.3...netlify-cms-widget-markdown@2.13.4) (2021-06-01) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.13.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.13.2...netlify-cms-widget-markdown@2.13.3) (2021-05-30) - - -### Bug Fixes - -* **widget-markdown:** fix quote block and list highlighting ([#5422](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/5422)) ([b9624fc](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/b9624fc67376cd6c6850f9b1adbfa5c80f2a0ac0)) - - - - - -## [2.13.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.13.1...netlify-cms-widget-markdown@2.13.2) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.13.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.13.0...netlify-cms-widget-markdown@2.13.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update react-select to v3 ([#5394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/5394)) ([03be13c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/03be13c1e87b318fd10ae6f6ab54cd2634fb9662)) - - - - - -# [2.13.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.12...netlify-cms-widget-markdown@2.13.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.12.12](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.11...netlify-cms-widget-markdown@2.12.12) (2021-04-01) - - -### Bug Fixes - -* **widget-markdown:** improve UX in Markdown editor - link editing and selected heading underline ([#5104](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/5104)) ([dde1a9d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/dde1a9db5483912f626f13239d7a3d06d6c4e05c)) - - - - - -## [2.12.11](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.10...netlify-cms-widget-markdown@2.12.11) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.12.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.9...netlify-cms-widget-markdown@2.12.10) (2021-02-10) - - -### Bug Fixes - -* **widget-markdown:** set toolbar item dropdown width to 'max-content' ([ecbf82e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/ecbf82e961217869a2354e520cd7ccbfa8151c18)) - - - - - -## [2.12.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.8...netlify-cms-widget-markdown@2.12.9) (2021-02-01) - - -### Bug Fixes - -* **security-markdown-widget:** allow sanitization of preview content ([#4886](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/4886)) ([27aec85](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/27aec85550c0be52c55f7b33314ecd52727fdcb5)) - - - - - -## [2.12.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.7...netlify-cms-widget-markdown@2.12.8) (2020-11-30) - - -### Bug Fixes - -* **deps:** update dependency is-hotkey to ^0.2.0 ([#4652](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/4652)) ([7828e15](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/7828e15453e55b5201f23b58817d73ecbd30a912)) - - - - - -## [2.12.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.6...netlify-cms-widget-markdown@2.12.7) (2020-10-20) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#4432](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/4432)) ([a5750d7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/a5750d782e9b4f0060362459037086f4d2f18acf)) - - - - - -## [2.12.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.5...netlify-cms-widget-markdown@2.12.6) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.12.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.4...netlify-cms-widget-markdown@2.12.5) (2020-09-15) - - -### Bug Fixes - -* **deps:** update dependency re-resizable to v6 ([#4308](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/4308)) ([de068cb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/de068cba1d44ec76e47e28d724427a9f4a53e0fd)) - - - - - -## 2.12.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.12.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.12.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.12.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.12.0...netlify-cms-widget-markdown@2.12.1) (2020-07-16) - - -### Bug Fixes - -* **prop-types:** check for react components via PropTypes.elementType ([#4025](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/4025)) ([d3831b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/d3831b1ed44fcff51a63f6645a5aa68332467dab)) - - - - - -# [2.12.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.11.3...netlify-cms-widget-markdown@2.12.0) (2020-06-18) - - -### Bug Fixes - -* **deps:** update dependency react-monaco-editor to ^0.36.0 ([#3871](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3871)) ([dc429f8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/dc429f8ffa40bc6d5f024823a10ae99a49aebdb5)) -* **widget-markdown:** don't strip new lines from text nodes ([#3813](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3813)) ([7bc75d0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/7bc75d095bcdae0a85d95ed9d0c9188a89136805)) -* **widget-markdown:** headings dropdown not showing properly no firefox ([#3903](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3903)) ([2b01e00](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/2b01e009c69ecb932815eda69385703e5774d775)) -* update rehype-remark ([#3864](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3864)) ([53cba02](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/53cba022442ee2e996a8917fced57a311fe22da0)) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.11.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.11.2...netlify-cms-widget-markdown@2.11.3) (2020-05-19) - - -### Bug Fixes - -* **deps:** update dependency rehype-stringify to v7 ([#3729](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3729)) ([a33aebb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/a33aebbc58e345b3659a6fd93de9f9e755e57525)) - - - - - -## [2.11.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.11.1...netlify-cms-widget-markdown@2.11.2) (2020-05-04) - - -### Bug Fixes - -* prevent escaping of footnotes and references ([#3646](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3646)) ([028ab53](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/028ab535df3e840bdf75c083ca7fbb275e0c61b3)) - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.11.0...netlify-cms-widget-markdown@2.11.1) (2020-04-16) - - -### Bug Fixes - -* **markdown widget:** adds keyboard shortcuts ([#3005](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3005)) ([#3582](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3582)) ([99071c1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/99071c14e4a03d9897b21f1a43a5104510521dda)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.10.2...netlify-cms-widget-markdown@2.11.0) (2020-04-07) - - -### Features - -* **yaml:** support comments ([#3529](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3529)) ([4afbbdd](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/4afbbdd8a99241d239f28c5be544bb0ca77e345b)) - - - - - -## [2.10.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.10.1...netlify-cms-widget-markdown@2.10.2) (2020-03-30) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.10.0...netlify-cms-widget-markdown@2.10.1) (2020-03-19) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.9.3...netlify-cms-widget-markdown@2.10.0) (2020-03-12) - - -### Bug Fixes - -* ja locale labels ([#3367](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3367)) ([50837b0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/50837b0068ac8972ce16cbf5f238aa5a2c5bd6e9)) - - -### Features - -* Configure included editor components per field, add optional minimal height ([#3299](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3299)) ([b7b4bcb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/b7b4bcb609fd90554c82bfd685f4af1b818083c1)) - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.9.2...netlify-cms-widget-markdown@2.9.3) (2020-02-19) - - -### Bug Fixes - -* **widget-markdown:** don't add duplicate marks ([#3290](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3290)) ([2a0aef2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/2a0aef27d1c1c7eac146f890d896233262322c7f)) - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.9.1...netlify-cms-widget-markdown@2.9.2) (2020-02-17) - - -### Bug Fixes - -* **widget-markdown:** allow shortcodes as list items ([#3278](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3278)) ([cdd3747](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/cdd3747850cca77f61b663cbfeda9765a72eb8d0)) - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.9.0...netlify-cms-widget-markdown@2.9.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.4...netlify-cms-widget-markdown@2.9.0) (2020-02-10) - - -### Features - -* field based media/public folders ([#3208](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3208)) ([97bc0c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/97bc0c8dc489e736f89d748ba832d78400fe4332)) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.8.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.3...netlify-cms-widget-markdown@2.8.4) (2020-02-06) - - -### Bug Fixes - -* **locale:** remove hard coded strings ([#3193](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3193)) ([fc91bf8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/fc91bf8781e65ce1dc946363dbb10419a145c66b)) - - - - - -## [2.8.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.2...netlify-cms-widget-markdown@2.8.3) (2020-02-01) - - -### Bug Fixes - -* **editor:** merge adjacent text nodes with same marks ([#3173](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3173)) ([b4c5fc7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/b4c5fc77839a7459fd2733f105514a86c8c43c22)) - - - - - -## [2.8.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.1...netlify-cms-widget-markdown@2.8.2) (2020-01-15) - - -### Reverts - -* don't force multiline flag for editor component patterns ([#3089](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3089)) ([c4cbae7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/c4cbae77255d1f422fd62258a01007956d512392)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.0...netlify-cms-widget-markdown@2.8.1) (2020-01-14) - - -### Bug Fixes - -* **core:** force multiline flag for editor component patterns ([#3082](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3082)) ([476f450](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/476f45096efa1723936a73f2e2e04d5c7ccd293f)) -* **widget-markdown:** allow multiline shortcodes ([#3066](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3066)) ([2929909](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/29299097cff0c280d2e97d37fe3b9888a3067554)) -* **widget-markdown:** ensure remarkToSlate result matches slate schema ([#3085](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3085)) ([fde0c5a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/fde0c5a9a776dc814bbe3a483aa286f46f45d98d)) -* **widget-markdown:** stop double pasting in raw editor ([#3083](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3083)) ([09564bf](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/09564bf8b64b2e431faf2421576b4010f05d516d)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.8.0-beta.0...netlify-cms-widget-markdown@2.8.0) (2020-01-07) - - -### Bug Fixes - -* **widget-markdown:** cut/copy selection only in raw mode ([#3024](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/3024)) ([1b755b3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/1b755b3be8e383fc8878a1485bd0ded2fc04025c)) -* avoid nested select widget z-index conflicts ([#2990](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2990)) ([fe09720](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/fe097202f0220b2eab426848b928258524ba6e72)) - - - - - -# [2.8.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.7.0...netlify-cms-widget-markdown@2.8.0-beta.0) (2019-12-18) - - -### Features - -* bundle assets with content ([#2958](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2958)) ([2b41d8a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/2b41d8a838a9c8a6b21cde2ddd16b9288334e298)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.7.0-beta.0...netlify-cms-widget-markdown@2.7.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.7.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.6.1-beta.0...netlify-cms-widget-markdown@2.7.0-beta.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.6.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.6.0...netlify-cms-widget-markdown@2.6.1-beta.0) (2019-12-02) - - -### Bug Fixes - -* **widget-markdown:** fix carriage return issue ([#2899](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2899)) ([1ff9db0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/1ff9db0915e93dab3f1c96459abf929d40398f85)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.5.2...netlify-cms-widget-markdown@2.6.0) (2019-11-18) - - -### Features - -* **widget-markdown:** add headings dropdown ([#2879](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2879)) ([78face3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/78face334f2dc7c99f5805551c052587e54d5753)) - - - - - -## [2.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.5.1...netlify-cms-widget-markdown@2.5.2) (2019-11-18) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.5.0...netlify-cms-widget-markdown@2.5.1) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.5.0-beta.1...netlify-cms-widget-markdown@2.5.0) (2019-06-14) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.5.0-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.5.0-beta.0...netlify-cms-widget-markdown@2.5.0-beta.1) (2019-05-15) - - -### Bug Fixes - -* **widget-markdown:** ensure correct value on list reorder ([#2298](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2298)) ([60caca0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/60caca0)) - - - - - -# [2.5.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.2...netlify-cms-widget-markdown@2.5.0-beta.0) (2019-04-10) - - -### Features - -* **editor-components:** match any characters with shortcodes ([#2268](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2268)) ([14b6292](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/14b6292)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.2-beta.0...netlify-cms-widget-markdown@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.1...netlify-cms-widget-markdown@2.4.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.1-beta.2...netlify-cms-widget-markdown@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.4.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.1-beta.1...netlify-cms-widget-markdown@2.4.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.1-beta.0...netlify-cms-widget-markdown@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.4.0...netlify-cms-widget-markdown@2.4.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/7987091)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.3.0...netlify-cms-widget-markdown@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/d142b32)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.3.0-beta.0...netlify-cms-widget-markdown@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-markdown - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.2.1-beta.0...netlify-cms-widget-markdown@2.3.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/82cc794)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.2.0...netlify-cms-widget-markdown@2.2.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/ccef446)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.1.1...netlify-cms-widget-markdown@2.2.0) (2019-03-08) - - -### Features - -* **core:** recover entry after unexpected quit ([#2129](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/2129)) ([686504a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/686504a)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.1.0...netlify-cms-widget-markdown@2.1.1) (2019-02-08) - - -### Bug Fixes - -* **markdown-widget:** handle leading or trailing whitespace ([#1517](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1517)) ([ade03d0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/ade03d0)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.10...netlify-cms-widget-markdown@2.1.0) (2018-12-11) - - -### Features - -* **editor-components:** support title in image component ([#1862](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1862)) ([cbb7762](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/cbb7762)) - - - - - -## [2.0.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.9...netlify-cms-widget-markdown@2.0.10) (2018-11-29) - - -### Bug Fixes - -* **netlify-cms-widget-markdown:** add missing border radius on toolbar ([#1905](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1905)) ([3772171](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/3772171)) - - - - - -## [2.0.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.8...netlify-cms-widget-markdown@2.0.9) (2018-11-12) - - -### Bug Fixes - -* **editor-component-image:** fix null on empty markdown image alt ([#1778](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1778)) ([9b72419](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/9b72419)) -* **editor-components:** fix default value processing ([#1848](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1848)) ([a0cfa1a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/a0cfa1a)) - - - - - - -## [2.0.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.7...netlify-cms-widget-markdown@2.0.8) (2018-09-06) - - -### Bug Fixes - -* add support for default field values in editor components ([#1616](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/issues/1616)) ([0d01809](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/commit/0d01809)) - - - - - -## [2.0.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.6...netlify-cms-widget-markdown@2.0.7) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.5...netlify-cms-widget-markdown@2.0.6) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.4...netlify-cms-widget-markdown@2.0.5) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.3...netlify-cms-widget-markdown@2.0.4) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown/compare/netlify-cms-widget-markdown@2.0.2...netlify-cms-widget-markdown@2.0.3) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown - - -## 2.0.2 (2018-07-27) - - -### Bug Fixes - -* bug fixes from linters ([#1524](https://github.com/netlify/netlify-cms/issues/1524)) ([6632e5d](https://github.com/netlify/netlify-cms/commit/6632e5d)) - - - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-markdown diff --git a/packages/netlify-cms-widget-markdown/README.md b/packages/netlify-cms-widget-markdown/README.md deleted file mode 100644 index 4806791c..00000000 --- a/packages/netlify-cms-widget-markdown/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-markdown/README.md)! diff --git a/packages/netlify-cms-widget-markdown/package.json b/packages/netlify-cms-widget-markdown/package.json deleted file mode 100644 index eb65540d..00000000 --- a/packages/netlify-cms-widget-markdown/package.json +++ /dev/null @@ -1,60 +0,0 @@ -{ - "name": "netlify-cms-widget-markdown", - "description": "Widget for editing markdown in Netlify CMS.", - "version": "2.15.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#markdown", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-markdown", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-markdown.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "markdown", - "editor" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "dompurify": "^2.2.6", - "is-hotkey": "^0.2.0", - "mdast-util-definitions": "^1.2.3", - "mdast-util-to-string": "^1.0.5", - "rehype-parse": "^6.0.0", - "rehype-remark": "^8.0.0", - "rehype-stringify": "^7.0.0", - "remark-parse": "^6.0.3", - "remark-rehype": "^4.0.0", - "remark-stringify": "^6.0.4", - "slate": "^0.47.0", - "slate-base64-serializer": "^0.2.107", - "slate-plain-serializer": "^0.7.1", - "slate-react": "^0.22.0", - "slate-soft-break": "^0.9.0", - "unified": "^7.1.0", - "unist-builder": "^1.0.3", - "unist-util-visit-parents": "^2.0.1" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-dom": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - }, - "devDependencies": { - "commonmark": "^0.30.0", - "commonmark-spec": "^0.30.0", - "slate-hyperscript": "^0.13.3" - } -} diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/VisualEditor.spec.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/VisualEditor.spec.js deleted file mode 100644 index 22905368..00000000 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/VisualEditor.spec.js +++ /dev/null @@ -1,56 +0,0 @@ -import { Map, fromJS } from 'immutable'; - -import { mergeMediaConfig } from '../VisualEditor'; - -describe('VisualEditor', () => { - describe('mergeMediaConfig', () => { - it('should copy editor media settings to image component', () => { - const editorComponents = Map({ - image: { - id: 'image', - label: 'Image', - type: 'shortcode', - icon: 'exclamation-triangle', - widget: 'object', - pattern: {}, - fields: fromJS([ - { - label: 'Image', - name: 'image', - widget: 'image', - media_library: { allow_multiple: false }, - }, - { label: 'Alt Text', name: 'alt' }, - { label: 'Title', name: 'title' }, - ]), - }, - }); - - const field = fromJS({ - label: 'Body', - name: 'body', - widget: 'markdown', - media_folder: '/{{media_folder}}/posts/images/widget/body', - public_folder: '{{public_folder}}/posts/images/widget/body', - media_library: { config: { max_file_size: 1234 } }, - }); - - mergeMediaConfig(editorComponents, field); - - expect(editorComponents.get('image').fields).toEqual( - fromJS([ - { - label: 'Image', - name: 'image', - widget: 'image', - media_library: { allow_multiple: false, config: { max_file_size: 1234 } }, - media_folder: '/{{media_folder}}/posts/images/widget/body', - public_folder: '{{public_folder}}/posts/images/widget/body', - }, - { label: 'Alt Text', name: 'alt' }, - { label: 'Title', name: 'title' }, - ]), - ); - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/__snapshots__/parser.spec.js.snap b/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/__snapshots__/parser.spec.js.snap deleted file mode 100644 index c11df3ea..00000000 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/__snapshots__/parser.spec.js.snap +++ /dev/null @@ -1,641 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Compile markdown to Slate Raw AST should compile kitchen sink example 1`] = ` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "An exhibit of Markdown", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "This note demonstrates some of what Markdown is capable of doing.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "Note: Feel free to play with this page. Unlike regular notes, this doesn't -automatically save itself.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Basic formatting", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Paragraphs can be written like so. A paragraph is the basic block of Markdown. -A paragraph is what text will turn into when there is no reason it should -become anything else.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Paragraphs must be separated by a blank line. Basic formatting of ", - }, - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "italics", - }, - Object { - "object": "text", - "text": " and -", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - ], - "object": "text", - "text": "bold", - }, - Object { - "object": "text", - "text": " is supported. This ", - }, - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "can be ", - }, - Object { - "marks": Array [ - Object { - "type": "italic", - }, - Object { - "type": "bold", - }, - ], - "object": "text", - "text": "nested", - }, - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": " like", - }, - Object { - "object": "text", - "text": " so.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Lists", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Ordered list", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "data": Object { - "start": 1, - }, - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Item 1 2. A second item 3. Number 3 4. Ⅳ", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - ], - "object": "block", - "type": "numbered-list", - }, - Object { - "nodes": Array [ - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "Note: the fourth item uses the Unicode character for Roman numeral four.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Unordered list", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "data": Object { - "start": null, - }, - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "An item Another item Yet another item And there's more...", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - ], - "object": "block", - "type": "bulleted-list", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Paragraph modifiers", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Code block", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "data": Object { - "lang": null, - }, - "nodes": Array [ - Object { - "object": "text", - "text": "Code blocks are very useful for developers and other people who look at -code or other things that are written in plain text. As you can see, it -uses a fixed-width font.", - }, - ], - "object": "block", - "type": "code-block", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "You can also make ", - }, - Object { - "marks": Array [ - Object { - "type": "code", - }, - ], - "object": "text", - "text": "inline code", - }, - Object { - "object": "text", - "text": " to add code into other things.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Quote", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Here is a quote. What this is should be self explanatory. Quotes are -automatically indented when they are used.", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "quote", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Headings", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "There are six levels of headings. They correspond with the six levels of HTML -headings. You've probably noticed them already in the page. Each level down -uses one more hash character.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Headings ", - }, - Object { - "marks": Array [ - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "can", - }, - Object { - "object": "text", - "text": " also contain ", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - ], - "object": "text", - "text": "formatting", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "They can even contain ", - }, - Object { - "marks": Array [ - Object { - "type": "code", - }, - ], - "object": "text", - "text": "inline code", - }, - ], - "object": "block", - "type": "heading-three", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Of course, demonstrating what headings look like messes up the structure of the -page.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "I don't recommend using more than three or four levels of headings here, -because, when you're smallest heading isn't too small, and you're largest -heading isn't too big, and you want each size up to look noticeably larger and -more important, there there are only so many sizes that you can use.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "URLs", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "URLs can be made in a handful of ways:", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "data": Object { - "start": null, - }, - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "A named link to MarkItDown. The easiest way to do these is to select what you", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "want to make a link and hit ", - }, - Object { - "marks": Array [ - Object { - "type": "code", - }, - ], - "object": "text", - "text": "Ctrl+L", - }, - Object { - "object": "text", - "text": ". Another named link to", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - Object { - "data": Object { - "title": null, - "url": "http://www.markitdown.net/", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "MarkItDown", - }, - ], - "object": "inline", - "type": "link", - }, - Object { - "object": "text", - "text": " Sometimes you just want a URL like", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - Object { - "data": Object { - "title": null, - "url": "http://www.markitdown.net/", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "http://www.markitdown.net/", - }, - ], - "object": "inline", - "type": "link", - }, - Object { - "object": "text", - "text": ".", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - ], - "object": "block", - "type": "bulleted-list", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Horizontal rule", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "A horizontal rule is a line that goes across the middle of the page.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "block", - "type": "thematic-break", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "It's sometimes handy for breaking things up.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Images", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Markdown can also contain images. I'll need to add something here sometime.", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Finally", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "There's actually a lot more to Markdown than this. See the official -introduction and syntax for more information. However, be aware that this is -not using the official implementation, and this might work subtly differently - in some of the little things.", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`; diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/parser.spec.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/parser.spec.js deleted file mode 100644 index fa20fad5..00000000 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/parser.spec.js +++ /dev/null @@ -1,810 +0,0 @@ -import { markdownToSlate } from '../../serializers'; - -const parser = markdownToSlate; - -describe('Compile markdown to Slate Raw AST', () => { - it('should compile simple markdown', () => { - const value = ` -# H1 - -sweet body -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "sweet body", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile a markdown ordered list', () => { - const value = ` -# H1 - -1. yo -2. bro -3. fro -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "data": Object { - "start": 1, - }, - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "yo", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "bro", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "fro", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - ], - "object": "block", - "type": "numbered-list", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile bulleted lists', () => { - const value = ` -# H1 - -* yo -* bro -* fro -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "data": Object { - "start": null, - }, - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "yo", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "bro", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "fro", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "list-item", - }, - ], - "object": "block", - "type": "bulleted-list", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile multiple header levels', () => { - const value = ` -# H1 - -## H2 - -### H3 -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H2", - }, - ], - "object": "block", - "type": "heading-two", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H3", - }, - ], - "object": "block", - "type": "heading-three", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile horizontal rules', () => { - const value = ` -# H1 - ---- - -blue moon -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "block", - "type": "thematic-break", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "blue moon", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile horizontal rules', () => { - const value = ` -# H1 - ---- - -blue moon -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "H1", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "block", - "type": "thematic-break", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "blue moon", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile soft breaks (double space)', () => { - const value = ` -blue moon -footballs -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "blue moon", - }, - Object { - "data": undefined, - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "inline", - "type": "break", - }, - Object { - "object": "text", - "text": "footballs", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile images', () => { - const value = ` -![super](duper.jpg) -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - Object { - "data": Object { - "alt": "super", - "title": null, - "url": "duper.jpg", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "inline", - "type": "image", - }, - Object { - "object": "text", - "text": "", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile code blocks', () => { - const value = ` -\`\`\`javascript -var a = 1; -\`\`\` -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "data": Object { - "lang": "javascript", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "var a = 1;", - }, - ], - "object": "block", - "type": "code-block", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile nested inline markup', () => { - const value = ` -# Word - -This is **some *hot* content** - -perhaps **scalding** even -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Word", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "This is ", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - ], - "object": "text", - "text": "some ", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - Object { - "type": "italic", - }, - ], - "object": "text", - "text": "hot", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - ], - "object": "text", - "text": " content", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "perhaps ", - }, - Object { - "marks": Array [ - Object { - "type": "bold", - }, - ], - "object": "text", - "text": "scalding", - }, - Object { - "object": "text", - "text": " even", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile inline code', () => { - const value = ` -# Word - -This is some sweet \`inline code\` yo! -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Word", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "This is some sweet ", - }, - Object { - "marks": Array [ - Object { - "type": "code", - }, - ], - "object": "text", - "text": "inline code", - }, - Object { - "object": "text", - "text": " yo!", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile links', () => { - const value = ` -# Word - -How far is it to [Google](https://google.com) land? -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "Word", - }, - ], - "object": "block", - "type": "heading-one", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "How far is it to ", - }, - Object { - "data": Object { - "title": null, - "url": "https://google.com", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "Google", - }, - ], - "object": "inline", - "type": "link", - }, - Object { - "object": "text", - "text": " land?", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile plugins', () => { - const value = ` -![test](test.png) - -{{< test >}} -`; - expect(parser(value)).toMatchInlineSnapshot(` -Object { - "nodes": Array [ - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - Object { - "data": Object { - "alt": "test", - "title": null, - "url": "test.png", - }, - "nodes": Array [ - Object { - "object": "text", - "text": "", - }, - ], - "object": "inline", - "type": "image", - }, - Object { - "object": "text", - "text": "", - }, - ], - "object": "block", - "type": "paragraph", - }, - Object { - "nodes": Array [ - Object { - "object": "text", - "text": "{{< test >}}", - }, - ], - "object": "block", - "type": "paragraph", - }, - ], - "object": "block", - "type": "root", -} -`); - }); - - it('should compile kitchen sink example', () => { - const value = ` -# An exhibit of Markdown - -This note demonstrates some of what Markdown is capable of doing. - -*Note: Feel free to play with this page. Unlike regular notes, this doesn't -automatically save itself.* - -## Basic formatting - -Paragraphs can be written like so. A paragraph is the basic block of Markdown. -A paragraph is what text will turn into when there is no reason it should -become anything else. - -Paragraphs must be separated by a blank line. Basic formatting of *italics* and -**bold** is supported. This *can be **nested** like* so. - -## Lists - -### Ordered list - -1. Item 1 2. A second item 3. Number 3 4. Ⅳ - -*Note: the fourth item uses the Unicode character for Roman numeral four.* - -### Unordered list - -* An item Another item Yet another item And there's more... - -## Paragraph modifiers - -### Code block - - Code blocks are very useful for developers and other people who look at - code or other things that are written in plain text. As you can see, it - uses a fixed-width font. - -You can also make \`inline code\` to add code into other things. - -### Quote - -> Here is a quote. What this is should be self explanatory. Quotes are -automatically indented when they are used. - -## Headings - -There are six levels of headings. They correspond with the six levels of HTML -headings. You've probably noticed them already in the page. Each level down -uses one more hash character. - -### Headings *can* also contain **formatting** - -### They can even contain \`inline code\` - -Of course, demonstrating what headings look like messes up the structure of the -page. - -I don't recommend using more than three or four levels of headings here, -because, when you're smallest heading isn't too small, and you're largest -heading isn't too big, and you want each size up to look noticeably larger and -more important, there there are only so many sizes that you can use. - -## URLs - -URLs can be made in a handful of ways: - -* A named link to MarkItDown. The easiest way to do these is to select what you -* want to make a link and hit \`Ctrl+L\`. Another named link to -* [MarkItDown](http://www.markitdown.net/) Sometimes you just want a URL like -* . - -## Horizontal rule - -A horizontal rule is a line that goes across the middle of the page. - ---- - -It's sometimes handy for breaking things up. - -## Images - -Markdown can also contain images. I'll need to add something here sometime. - -## Finally - -There's actually a lot more to Markdown than this. See the official -introduction and syntax for more information. However, be aware that this is -not using the official implementation, and this might work subtly differently - in some of the little things. -`; - expect(parser(value)).toMatchSnapshot(); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/slate.spec.js b/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/slate.spec.js deleted file mode 100644 index 2c4dc853..00000000 --- a/packages/netlify-cms-widget-markdown/src/MarkdownControl/__tests__/slate.spec.js +++ /dev/null @@ -1,50 +0,0 @@ -/** @jsx h */ - -import { Editor } from 'slate'; - -import h from '../../../test-helpers/h'; -import plugins from '../plugins/visual'; -import schema from '../schema'; - -function run(input, output, fn) { - const editor = new Editor({ plugins: plugins(), schema: schema() }); - const opts = { preserveSelection: true }; - editor.setValue(input); - fn(editor); - const actual = editor.value.toJSON(opts); - editor.setValue(output); - const expected = editor.value.toJSON(opts); - return [actual, expected]; -} - -// If we want to use slate-hyperscript for testing our schema direct, we can use -// this setup. -describe.skip('slate', () => { - test('test', () => { - const input = ( - - - - a - - - - ); - const output = ( - - - - b - - - - ); - - function fn(editor) { - editor.deleteBackward().insertText('b').setBlocks('heading-one'); - } - - const [actual, expected] = run(input, output, fn); - expect(actual).toEqual(expected); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/__tests__/__snapshots__/renderer.spec.js.snap b/packages/netlify-cms-widget-markdown/src/__tests__/__snapshots__/renderer.spec.js.snap deleted file mode 100644 index 6ced837f..00000000 --- a/packages/netlify-cms-widget-markdown/src/__tests__/__snapshots__/renderer.spec.js.snap +++ /dev/null @@ -1,239 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Markdown Preview renderer HTML rendering should render HTML 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Paragraph with inline element

    ", - } - } -/> -`; - -exports[`Markdown Preview renderer HTML sanitization should not sanitize HTML 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    ", - } - } -/> -`; - -exports[`Markdown Preview renderer HTML sanitization should sanitize HTML 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    ", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Code should render code 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Use the printf() function.

    ", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Code should render code 2 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    There is a literal backtick (\`) here.

    ", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering General should render markdown 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    H1 -

    Text with bold & em elements

    -

    H2

    -
      -
    • ul item 1
    • -
    • ul item 2
    • -
    -

    H3

    -
      -
    1. ol item 1
    2. -
    3. ol item 2
    4. -
    5. ol item 3
    6. -
    -

    H4

    -

    link title

    -
    H5
    -

    \\"alt

    -
    H6
    -

    ", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering HTML should render HTML as is when using Markdown 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title -
    - -
    -
    Test HTML content
    -
    Testing HTML in Markdown
    -
    -
    -

    Test

    ", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 1 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 2 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 3 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 4 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 5 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Headings should render Heading 6 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    Title", - } - } -/> -`; - -exports[`Markdown Preview renderer Markdown rendering Links should render links 1`] = ` -.emotion-0 { - margin: 15px 2px; -} - -
    I get 10 times more traffic from Google than from Yahoo or MSN.

    ", - } - } -/> -`; diff --git a/packages/netlify-cms-widget-markdown/src/__tests__/renderer.spec.js b/packages/netlify-cms-widget-markdown/src/__tests__/renderer.spec.js deleted file mode 100644 index 079adced..00000000 --- a/packages/netlify-cms-widget-markdown/src/__tests__/renderer.spec.js +++ /dev/null @@ -1,261 +0,0 @@ -import React from 'react'; -import { create, act } from 'react-test-renderer'; -import { padStart } from 'lodash'; -import { Map } from 'immutable'; - -import MarkdownPreview from '../MarkdownPreview'; -import { markdownToHtml } from '../serializers'; - -describe('Markdown Preview renderer', () => { - describe('Markdown rendering', () => { - describe('General', () => { - it('should render markdown', async () => { - const value = ` -# H1 - -Text with **bold** & _em_ elements - -## H2 - -* ul item 1 -* ul item 2 - -### H3 - -1. ol item 1 -1. ol item 2 -1. ol item 3 - -#### H4 - -[link title](http://google.com) - -##### H5 - -![alt text](https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg) - -###### H6 - -![](https://pbs.twimg.com/profile_images/678903331176214528/TQTdqGwD.jpg) -`; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); - - describe('Headings', () => { - for (const heading of [...Array(6).keys()]) { - it(`should render Heading ${heading + 1}`, async () => { - const value = padStart(' Title', heading + 7, '#'); - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - } - }); - - describe('Lists', () => { - it('should render lists', async () => { - const value = ` -1. ol item 1 -1. ol item 2 - * Sublist 1 - * Sublist 2 - * Sublist 3 - 1. Sub-Sublist 1 - 1. Sub-Sublist 2 - 1. Sub-Sublist 3 -1. ol item 3 -`; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchInlineSnapshot(` -.emotion-0 { - margin: 15px 2px; -} - -
    -
  • ol item 1
  • -
  • ol item 2
      -
    • Sublist 1
    • -
    • Sublist 2
    • -
    • Sublist 3
        -
      1. Sub-Sublist 1
      2. -
      3. Sub-Sublist 2
      4. -
      5. Sub-Sublist 3
      6. -
    • -
  • -
  • ol item 3
  • -", - } - } -/> -`); - }); - }); - - describe('Links', () => { - it('should render links', async () => { - const value = ` -I get 10 times more traffic from [Google] than from [Yahoo] or [MSN]. - - [Google]: http://google.com/ "Google" - [Yahoo]: http://search.yahoo.com/ "Yahoo Search" - [MSN]: http://search.msn.com/ "MSN Search" -`; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); - - describe('Code', () => { - it('should render code', async () => { - const value = 'Use the `printf()` function.'; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - - it('should render code 2', async () => { - const value = '``There is a literal backtick (`) here.``'; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); - - describe('HTML', () => { - it('should render HTML as is when using Markdown', async () => { - const value = ` -# Title - -
    - -
    -
    Test HTML content
    -
    Testing HTML in Markdown
    -
    -
    - -

    Test

    -`; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); - }); - - describe('HTML rendering', () => { - it('should render HTML', async () => { - const value = '

    Paragraph with inline element

    '; - const html = await markdownToHtml(value); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); - - describe('HTML sanitization', () => { - it('should sanitize HTML', async () => { - const value = ``; - const field = Map({ sanitize_preview: true }); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - - it('should not sanitize HTML', async () => { - const value = ``; - const field = Map({ sanitize_preview: false }); - - let root; - await act(async () => { - root = create( - , - ); - }); - - expect(root.toJSON()).toMatchSnapshot(); - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/commonmarkExpected.json b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/commonmarkExpected.json deleted file mode 100644 index 2e74df14..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/commonmarkExpected.json +++ /dev/null @@ -1,625 +0,0 @@ -{ - "\tfoo\tbaz\t\tbim\n": "NOT_TO_EQUAL", - " \tfoo\tbaz\t\tbim\n": "NOT_TO_EQUAL", - " a\ta\n ὐ\ta\n": "NOT_TO_EQUAL", - " - foo\n\n\tbar\n": "NOT_TO_EQUAL", - "- foo\n\n\t\tbar\n": "NOT_TO_EQUAL", - ">\t\tfoo\n": "NOT_TO_EQUAL", - "-\t\tfoo\n": "NOT_TO_EQUAL", - " foo\n\tbar\n": "TO_EQUAL", - " - foo\n - bar\n\t - baz\n": "NOT_TO_EQUAL", - "#\tFoo\n": "TO_EQUAL", - "*\t*\t*\t\n": "TO_ERROR", - "- `one\n- two`\n": "TO_EQUAL", - "***\n---\n___\n": "NOT_TO_EQUAL", - "+++\n": "TO_EQUAL", - "===\n": "TO_EQUAL", - "--\n**\n__\n": "TO_EQUAL", - " ***\n ***\n ***\n": "NOT_TO_EQUAL", - " ***\n": "TO_EQUAL", - "Foo\n ***\n": "TO_EQUAL", - "_____________________________________\n": "NOT_TO_EQUAL", - " - - -\n": "NOT_TO_EQUAL", - " ** * ** * ** * **\n": "NOT_TO_EQUAL", - "- - - -\n": "NOT_TO_EQUAL", - "- - - - \n": "NOT_TO_EQUAL", - "_ _ _ _ a\n\na------\n\n---a---\n": "TO_EQUAL", - " *-*\n": "NOT_TO_EQUAL", - "- foo\n***\n- bar\n": "NOT_TO_EQUAL", - "Foo\n***\nbar\n": "NOT_TO_EQUAL", - "Foo\n---\nbar\n": "TO_EQUAL", - "* Foo\n* * *\n* Bar\n": "NOT_TO_EQUAL", - "- Foo\n- * * *\n": "NOT_TO_EQUAL", - "# foo\n## foo\n### foo\n#### foo\n##### foo\n###### foo\n": "TO_EQUAL", - "####### foo\n": "TO_EQUAL", - "#5 bolt\n\n#hashtag\n": "TO_EQUAL", - "\\## foo\n": "TO_EQUAL", - "# foo *bar* \\*baz\\*\n": "NOT_TO_EQUAL", - "# foo \n": "TO_EQUAL", - " ### foo\n ## foo\n # foo\n": "TO_EQUAL", - " # foo\n": "TO_EQUAL", - "foo\n # bar\n": "TO_EQUAL", - "## foo ##\n ### bar ###\n": "TO_EQUAL", - "# foo ##################################\n##### foo ##\n": "TO_EQUAL", - "### foo ### \n": "TO_EQUAL", - "### foo ### b\n": "TO_EQUAL", - "# foo#\n": "NOT_TO_EQUAL", - "### foo \\###\n## foo #\\##\n# foo \\#\n": "NOT_TO_EQUAL", - "****\n## foo\n****\n": "NOT_TO_EQUAL", - "Foo bar\n# baz\nBar foo\n": "TO_EQUAL", - "## \n#\n### ###\n": "TO_ERROR", - "Foo *bar*\n=========\n\nFoo *bar*\n---------\n": "TO_EQUAL", - "Foo *bar\nbaz*\n====\n": "NOT_TO_EQUAL", - "Foo\n-------------------------\n\nFoo\n=\n": "TO_EQUAL", - " Foo\n---\n\n Foo\n-----\n\n Foo\n ===\n": "NOT_TO_EQUAL", - " Foo\n ---\n\n Foo\n---\n": "NOT_TO_EQUAL", - "Foo\n ---- \n": "NOT_TO_EQUAL", - "Foo\n ---\n": "TO_EQUAL", - "Foo\n= =\n\nFoo\n--- -\n": "NOT_TO_EQUAL", - "Foo \n-----\n": "TO_EQUAL", - "Foo\\\n----\n": "TO_EQUAL", - "`Foo\n----\n`\n\n\n": "NOT_TO_EQUAL", - "> Foo\n---\n": "NOT_TO_EQUAL", - "> foo\nbar\n===\n": "NOT_TO_EQUAL", - "- Foo\n---\n": "NOT_TO_EQUAL", - "Foo\nBar\n---\n": "NOT_TO_EQUAL", - "---\nFoo\n---\nBar\n---\nBaz\n": "NOT_TO_EQUAL", - "\n====\n": "TO_EQUAL", - "---\n---\n": "TO_ERROR", - "- foo\n-----\n": "NOT_TO_EQUAL", - " foo\n---\n": "NOT_TO_EQUAL", - "> foo\n-----\n": "NOT_TO_EQUAL", - "\\> foo\n------\n": "NOT_TO_EQUAL", - "Foo\n\nbar\n---\nbaz\n": "TO_EQUAL", - "Foo\nbar\n\n---\n\nbaz\n": "NOT_TO_EQUAL", - "Foo\nbar\n* * *\nbaz\n": "NOT_TO_EQUAL", - "Foo\nbar\n\\---\nbaz\n": "NOT_TO_EQUAL", - " a simple\n indented code block\n": "TO_EQUAL", - " - foo\n\n bar\n": "NOT_TO_EQUAL", - "1. foo\n\n - bar\n": "TO_EQUAL", - " \n *hi*\n\n - one\n": "NOT_TO_EQUAL", - " chunk1\n\n chunk2\n \n \n \n chunk3\n": "TO_EQUAL", - " chunk1\n \n chunk2\n": "TO_EQUAL", - "Foo\n bar\n\n": "TO_EQUAL", - " foo\nbar\n": "TO_EQUAL", - "# Heading\n foo\nHeading\n------\n foo\n----\n": "NOT_TO_EQUAL", - " foo\n bar\n": "TO_EQUAL", - "\n \n foo\n \n\n": "TO_EQUAL", - " foo \n": "TO_EQUAL", - "```\n<\n >\n```\n": "NOT_TO_EQUAL", - "~~~\n<\n >\n~~~\n": "NOT_TO_EQUAL", - "``\nfoo\n``\n": "TO_EQUAL", - "```\naaa\n~~~\n```\n": "NOT_TO_EQUAL", - "~~~\naaa\n```\n~~~\n": "NOT_TO_EQUAL", - "````\naaa\n```\n``````\n": "NOT_TO_EQUAL", - "~~~~\naaa\n~~~\n~~~~\n": "NOT_TO_EQUAL", - "```\n": "TO_EQUAL", - "`````\n\n```\naaa\n": "NOT_TO_EQUAL", - "> ```\n> aaa\n\nbbb\n": "TO_EQUAL", - "```\n\n \n```\n": "NOT_TO_EQUAL", - "```\n```\n": "TO_EQUAL", - " ```\n aaa\naaa\n```\n": "TO_EQUAL", - " ```\naaa\n aaa\naaa\n ```\n": "TO_EQUAL", - " ```\n aaa\n aaa\n aaa\n ```\n": "TO_EQUAL", - " ```\n aaa\n ```\n": "NOT_TO_EQUAL", - "```\naaa\n ```\n": "TO_EQUAL", - " ```\naaa\n ```\n": "TO_EQUAL", - "```\naaa\n ```\n": "NOT_TO_EQUAL", - "``` ```\naaa\n": "TO_EQUAL", - "~~~~~~\naaa\n~~~ ~~\n": "NOT_TO_EQUAL", - "foo\n```\nbar\n```\nbaz\n": "TO_EQUAL", - "foo\n---\n~~~\nbar\n~~~\n# baz\n": "TO_EQUAL", - "```ruby\ndef foo(x)\n return 3\nend\n```\n": "TO_EQUAL", - "~~~~ ruby startline=3 $%@#$\ndef foo(x)\n return 3\nend\n~~~~~~~\n": "TO_EQUAL", - "````;\n````\n": "TO_EQUAL", - "``` aa ```\nfoo\n": "TO_EQUAL", - "```\n``` aaa\n```\n": "NOT_TO_EQUAL", - "
    \n
    \n**Hello**,\n\n_world_.\n
    \n
    \n": "NOT_TO_EQUAL", - "\n \n \n \n
    \n hi\n
    \n\nokay.\n": "TO_EQUAL", - "
    \n*foo*\n": "NOT_TO_EQUAL", - "
    \n\n*Markdown*\n\n
    \n": "TO_EQUAL", - "
    \n
    \n": "TO_EQUAL", - "
    \n
    \n": "TO_EQUAL", - "
    \n*foo*\n\n*bar*\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "
    \nfoo\n
    \n": "TO_EQUAL", - "
    \n``` c\nint x = 33;\n```\n": "NOT_TO_EQUAL", - "\n*bar*\n\n": "NOT_TO_EQUAL", - "\n*bar*\n\n": "NOT_TO_EQUAL", - "\n*bar*\n\n": "NOT_TO_EQUAL", - "\n*bar*\n": "NOT_TO_EQUAL", - "\n*foo*\n\n": "NOT_TO_EQUAL", - "\n\n*foo*\n\n\n": "TO_EQUAL", - "*foo*\n": "TO_EQUAL", - "
    \nimport Text.HTML.TagSoup\n\nmain :: IO ()\nmain = print $ parseTags tags\n
    \nokay\n": "TO_EQUAL", - "\nokay\n": "TO_EQUAL", - "\nh1 {color:red;}\n\np {color:blue;}\n\nokay\n": "TO_EQUAL", - "\n\nfoo\n": "TO_EQUAL", - ">
    \n> foo\n\nbar\n": "TO_EQUAL", - "-
    \n- foo\n": "TO_EQUAL", - "\n*foo*\n": "TO_EQUAL", - "*bar*\n*baz*\n": "NOT_TO_EQUAL", - "1. *bar*\n": "NOT_TO_EQUAL", - "\nokay\n": "TO_EQUAL", - "';\n\n?>\nokay\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\nokay\n": "NOT_TO_EQUAL", - " \n\n \n": "NOT_TO_EQUAL", - "
    \n\n
    \n": "NOT_TO_EQUAL", - "Foo\n
    \nbar\n
    \n": "TO_EQUAL", - "
    \nbar\n
    \n*foo*\n": "NOT_TO_EQUAL", - "Foo\n\nbaz\n": "TO_EQUAL", - "
    \n\n*Emphasized* text.\n\n
    \n": "TO_EQUAL", - "
    \n*Emphasized* text.\n
    \n": "NOT_TO_EQUAL", - "\n\n\n\n\n\n\n\n
    \nHi\n
    \n": "TO_EQUAL", - "\n\n \n\n \n\n \n\n
    \n Hi\n
    \n": "NOT_TO_EQUAL", - "[foo]: /url \"title\"\n\n[foo]\n": "TO_EQUAL", - " [foo]: \n /url \n 'the title' \n\n[foo]\n": "TO_EQUAL", - "[Foo*bar\\]]:my_(url) 'title (with parens)'\n\n[Foo*bar\\]]\n": "NOT_TO_EQUAL", - "[Foo bar]:\n\n'title'\n\n[Foo bar]\n": "TO_EQUAL", - "[foo]: /url '\ntitle\nline1\nline2\n'\n\n[foo]\n": "NOT_TO_EQUAL", - "[foo]: /url 'title\n\nwith blank line'\n\n[foo]\n": "TO_EQUAL", - "[foo]:\n/url\n\n[foo]\n": "TO_EQUAL", - "[foo]:\n\n[foo]\n": "TO_EQUAL", - "[foo]: /url\\bar\\*baz \"foo\\\"bar\\baz\"\n\n[foo]\n": "NOT_TO_EQUAL", - "[foo]\n\n[foo]: url\n": "TO_EQUAL", - "[foo]\n\n[foo]: first\n[foo]: second\n": "NOT_TO_EQUAL", - "[FOO]: /url\n\n[Foo]\n": "TO_EQUAL", - "[ΑΓΩ]: /φου\n\n[αγω]\n": "TO_EQUAL", - "[foo]: /url\n": "TO_ERROR", - "[\nfoo\n]: /url\nbar\n": "TO_EQUAL", - "[foo]: /url \"title\" ok\n": "NOT_TO_EQUAL", - "[foo]: /url\n\"title\" ok\n": "NOT_TO_EQUAL", - " [foo]: /url \"title\"\n\n[foo]\n": "NOT_TO_EQUAL", - "```\n[foo]: /url\n```\n\n[foo]\n": "TO_EQUAL", - "Foo\n[bar]: /baz\n\n[bar]\n": "TO_EQUAL", - "# [Foo]\n[foo]: /url\n> bar\n": "TO_EQUAL", - "[foo]: /foo-url \"foo\"\n[bar]: /bar-url\n \"bar\"\n[baz]: /baz-url\n\n[foo],\n[bar],\n[baz]\n": "TO_EQUAL", - "[foo]\n\n> [foo]: /url\n": "NOT_TO_EQUAL", - "aaa\n\nbbb\n": "TO_EQUAL", - "aaa\nbbb\n\nccc\nddd\n": "TO_EQUAL", - "aaa\n\n\nbbb\n": "TO_EQUAL", - " aaa\n bbb\n": "NOT_TO_EQUAL", - "aaa\n bbb\n ccc\n": "TO_EQUAL", - " aaa\nbbb\n": "NOT_TO_EQUAL", - " aaa\nbbb\n": "TO_EQUAL", - "aaa \nbbb \n": "NOT_TO_EQUAL", - " \n\naaa\n \n\n# aaa\n\n \n": "TO_EQUAL", - "> # Foo\n> bar\n> baz\n": "TO_EQUAL", - "># Foo\n>bar\n> baz\n": "TO_EQUAL", - " > # Foo\n > bar\n > baz\n": "TO_EQUAL", - " > # Foo\n > bar\n > baz\n": "NOT_TO_EQUAL", - "> # Foo\n> bar\nbaz\n": "TO_EQUAL", - "> bar\nbaz\n> foo\n": "TO_EQUAL", - "> foo\n---\n": "NOT_TO_EQUAL", - "> - foo\n- bar\n": "TO_EQUAL", - "> foo\n bar\n": "TO_EQUAL", - "> ```\nfoo\n```\n": "NOT_TO_EQUAL", - "> foo\n - bar\n": "NOT_TO_EQUAL", - ">\n": "TO_ERROR", - ">\n> \n> \n": "TO_ERROR", - ">\n> foo\n> \n": "TO_EQUAL", - "> foo\n\n> bar\n": "NOT_TO_EQUAL", - "> foo\n> bar\n": "TO_EQUAL", - "> foo\n>\n> bar\n": "TO_EQUAL", - "foo\n> bar\n": "TO_EQUAL", - "> aaa\n***\n> bbb\n": "NOT_TO_EQUAL", - "> bar\nbaz\n": "TO_EQUAL", - "> bar\n\nbaz\n": "TO_EQUAL", - "> bar\n>\nbaz\n": "NOT_TO_EQUAL", - "> > > foo\nbar\n": "TO_EQUAL", - ">>> foo\n> bar\n>>baz\n": "TO_EQUAL", - "> code\n\n> not code\n": "NOT_TO_EQUAL", - "A paragraph\nwith two lines.\n\n indented code\n\n> A block quote.\n": "TO_EQUAL", - "1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n": "TO_EQUAL", - "- one\n\n two\n": "NOT_TO_EQUAL", - "- one\n\n two\n": "NOT_TO_EQUAL", - " - one\n\n two\n": "NOT_TO_EQUAL", - " - one\n\n two\n": "NOT_TO_EQUAL", - " > > 1. one\n>>\n>> two\n": "NOT_TO_EQUAL", - ">>- one\n>>\n > > two\n": "TO_EQUAL", - "-one\n\n2.two\n": "TO_EQUAL", - "- foo\n\n\n bar\n": "TO_EQUAL", - "1. foo\n\n ```\n bar\n ```\n\n baz\n\n > bam\n": "TO_EQUAL", - "- Foo\n\n bar\n\n\n baz\n": "NOT_TO_EQUAL", - "123456789. ok\n": "TO_EQUAL", - "1234567890. not ok\n": "NOT_TO_EQUAL", - "0. ok\n": "NOT_TO_EQUAL", - "003. ok\n": "TO_EQUAL", - "-1. not ok\n": "TO_EQUAL", - "- foo\n\n bar\n": "TO_EQUAL", - " 10. foo\n\n bar\n": "TO_EQUAL", - " indented code\n\nparagraph\n\n more code\n": "TO_EQUAL", - "1. indented code\n\n paragraph\n\n more code\n": "TO_EQUAL", - "1. indented code\n\n paragraph\n\n more code\n": "TO_EQUAL", - " foo\n\nbar\n": "NOT_TO_EQUAL", - "- foo\n\n bar\n": "NOT_TO_EQUAL", - "- foo\n\n bar\n": "NOT_TO_EQUAL", - "-\n foo\n-\n ```\n bar\n ```\n-\n baz\n": "NOT_TO_EQUAL", - "- \n foo\n": "TO_ERROR", - "-\n\n foo\n": "NOT_TO_EQUAL", - "- foo\n-\n- bar\n": "TO_ERROR", - "- foo\n- \n- bar\n": "TO_ERROR", - "1. foo\n2.\n3. bar\n": "TO_ERROR", - "*\n": "NOT_TO_EQUAL", - "foo\n*\n\nfoo\n1.\n": "TO_EQUAL", - " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n": "TO_EQUAL", - " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n": "TO_EQUAL", - " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n": "TO_EQUAL", - " 1. A paragraph\n with two lines.\n\n indented code\n\n > A block quote.\n": "NOT_TO_EQUAL", - " 1. A paragraph\nwith two lines.\n\n indented code\n\n > A block quote.\n": "NOT_TO_EQUAL", - " 1. A paragraph\n with two lines.\n": "TO_EQUAL", - "> 1. > Blockquote\ncontinued here.\n": "TO_EQUAL", - "> 1. > Blockquote\n> continued here.\n": "TO_EQUAL", - "- foo\n - bar\n - baz\n - boo\n": "NOT_TO_EQUAL", - "- foo\n - bar\n - baz\n - boo\n": "TO_EQUAL", - "10) foo\n - bar\n": "NOT_TO_EQUAL", - "10) foo\n - bar\n": "TO_EQUAL", - "- - foo\n": "TO_EQUAL", - "1. - 2. foo\n": "TO_EQUAL", - "- # Foo\n- Bar\n ---\n baz\n": "NOT_TO_EQUAL", - "- foo\n- bar\n+ baz\n": "TO_EQUAL", - "1. foo\n2. bar\n3) baz\n": "TO_EQUAL", - "Foo\n- bar\n- baz\n": "TO_EQUAL", - "The number of windows in my house is\n14. The number of doors is 6.\n": "NOT_TO_EQUAL", - "The number of windows in my house is\n1. The number of doors is 6.\n": "TO_EQUAL", - "- foo\n\n- bar\n\n\n- baz\n": "NOT_TO_EQUAL", - "- foo\n - bar\n - baz\n\n\n bim\n": "NOT_TO_EQUAL", - "- foo\n- bar\n\n\n\n- baz\n- bim\n": "TO_EQUAL", - "- foo\n\n notcode\n\n- foo\n\n\n\n code\n": "NOT_TO_EQUAL", - "- a\n - b\n - c\n - d\n - e\n - f\n - g\n - h\n- i\n": "NOT_TO_EQUAL", - "1. a\n\n 2. b\n\n 3. c\n": "NOT_TO_EQUAL", - "- a\n- b\n\n- c\n": "NOT_TO_EQUAL", - "* a\n*\n\n* c\n": "TO_ERROR", - "- a\n- b\n\n c\n- d\n": "NOT_TO_EQUAL", - "- a\n- b\n\n [ref]: /url\n- d\n": "NOT_TO_EQUAL", - "- a\n- ```\n b\n\n\n ```\n- c\n": "NOT_TO_EQUAL", - "- a\n - b\n\n c\n- d\n": "NOT_TO_EQUAL", - "* a\n > b\n >\n* c\n": "NOT_TO_EQUAL", - "- a\n > b\n ```\n c\n ```\n- d\n": "NOT_TO_EQUAL", - "- a\n": "TO_EQUAL", - "- a\n - b\n": "NOT_TO_EQUAL", - "1. ```\n foo\n ```\n\n bar\n": "TO_EQUAL", - "* foo\n * bar\n\n baz\n": "NOT_TO_EQUAL", - "- a\n - b\n - c\n\n- d\n - e\n - f\n": "TO_EQUAL", - "`hi`lo`\n": "TO_EQUAL", - "\\!\\\"\\#\\$\\%\\&\\'\\(\\)\\*\\+\\,\\-\\.\\/\\:\\;\\<\\=\\>\\?\\@\\[\\\\\\]\\^\\_\\`\\{\\|\\}\\~\n": "NOT_TO_EQUAL", - "\\\t\\A\\a\\ \\3\\φ\\«\n": "TO_EQUAL", - "\\*not emphasized*\n\\
    not a tag\n\\[not a link](/foo)\n\\`not code`\n1\\. not a list\n\\* not a list\n\\# not a heading\n\\[foo]: /url \"not a reference\"\n": "NOT_TO_EQUAL", - "\\\\*emphasis*\n": "NOT_TO_EQUAL", - "foo\\\nbar\n": "NOT_TO_EQUAL", - "`` \\[\\` ``\n": "TO_EQUAL", - " \\[\\]\n": "TO_EQUAL", - "~~~\n\\[\\]\n~~~\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "
    \n": "TO_EQUAL", - "[foo](/bar\\* \"ti\\*tle\")\n": "TO_EQUAL", - "[foo]\n\n[foo]: /bar\\* \"ti\\*tle\"\n": "TO_EQUAL", - "``` foo\\+bar\nfoo\n```\n": "TO_EQUAL", - "  & © Æ Ď\n¾ ℋ ⅆ\n∲ ≧̸\n": "NOT_TO_EQUAL", - "# Ӓ Ϡ � �\n": "NOT_TO_EQUAL", - "" ആ ಫ\n": "NOT_TO_EQUAL", - "  &x; &#; &#x;\n&ThisIsNotDefined; &hi?;\n": "NOT_TO_EQUAL", - "©\n": "NOT_TO_EQUAL", - "&MadeUpEntity;\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "[foo](/föö \"föö\")\n": "TO_EQUAL", - "[foo]\n\n[foo]: /föö \"föö\"\n": "TO_EQUAL", - "``` föö\nfoo\n```\n": "TO_EQUAL", - "`föö`\n": "NOT_TO_EQUAL", - " föfö\n": "NOT_TO_EQUAL", - "`foo`\n": "TO_EQUAL", - "`` foo ` bar ``\n": "TO_EQUAL", - "` `` `\n": "TO_EQUAL", - "`foo bar\n baz`\n": "TO_EQUAL", - "`a b`\n": "NOT_TO_EQUAL", - "`foo `` bar`\n": "TO_EQUAL", - "`foo\\`bar`\n": "TO_EQUAL", - "*foo`*`\n": "NOT_TO_EQUAL", - "[not a `link](/foo`)\n": "NOT_TO_EQUAL", - "``\n": "NOT_TO_EQUAL", - "`\n": "TO_EQUAL", - "``\n": "NOT_TO_EQUAL", - "`\n": "TO_EQUAL", - "```foo``\n": "NOT_TO_EQUAL", - "`foo\n": "TO_EQUAL", - "`foo``bar``\n": "NOT_TO_EQUAL", - "*foo bar*\n": "TO_EQUAL", - "a * foo bar*\n": "NOT_TO_EQUAL", - "a*\"foo\"*\n": "NOT_TO_EQUAL", - "* a *\n": "NOT_TO_EQUAL", - "foo*bar*\n": "TO_EQUAL", - "5*6*78\n": "NOT_TO_EQUAL", - "_foo bar_\n": "TO_EQUAL", - "_ foo bar_\n": "NOT_TO_EQUAL", - "a_\"foo\"_\n": "NOT_TO_EQUAL", - "foo_bar_\n": "NOT_TO_EQUAL", - "5_6_78\n": "TO_EQUAL", - "пристаням_стремятся_\n": "NOT_TO_EQUAL", - "aa_\"bb\"_cc\n": "NOT_TO_EQUAL", - "foo-_(bar)_\n": "TO_EQUAL", - "_foo*\n": "TO_EQUAL", - "*foo bar *\n": "NOT_TO_EQUAL", - "*foo bar\n*\n": "NOT_TO_EQUAL", - "*(*foo)\n": "NOT_TO_EQUAL", - "*(*foo*)*\n": "NOT_TO_EQUAL", - "*foo*bar\n": "NOT_TO_EQUAL", - "_foo bar _\n": "NOT_TO_EQUAL", - "_(_foo)\n": "TO_EQUAL", - "_(_foo_)_\n": "NOT_TO_EQUAL", - "_foo_bar\n": "TO_EQUAL", - "_пристаням_стремятся\n": "NOT_TO_EQUAL", - "_foo_bar_baz_\n": "TO_EQUAL", - "_(bar)_.\n": "TO_EQUAL", - "**foo bar**\n": "TO_EQUAL", - "** foo bar**\n": "NOT_TO_EQUAL", - "a**\"foo\"**\n": "NOT_TO_EQUAL", - "foo**bar**\n": "TO_EQUAL", - "__foo bar__\n": "TO_EQUAL", - "__ foo bar__\n": "NOT_TO_EQUAL", - "__\nfoo bar__\n": "NOT_TO_EQUAL", - "a__\"foo\"__\n": "NOT_TO_EQUAL", - "foo__bar__\n": "NOT_TO_EQUAL", - "5__6__78\n": "NOT_TO_EQUAL", - "пристаням__стремятся__\n": "NOT_TO_EQUAL", - "__foo, __bar__, baz__\n": "NOT_TO_EQUAL", - "foo-__(bar)__\n": "TO_EQUAL", - "**foo bar **\n": "NOT_TO_EQUAL", - "**(**foo)\n": "NOT_TO_EQUAL", - "*(**foo**)*\n": "TO_EQUAL", - "**Gomphocarpus (*Gomphocarpus physocarpus*, syn.\n*Asclepias physocarpa*)**\n": "TO_EQUAL", - "**foo \"*bar*\" foo**\n": "NOT_TO_EQUAL", - "**foo**bar\n": "TO_EQUAL", - "__foo bar __\n": "NOT_TO_EQUAL", - "__(__foo)\n": "NOT_TO_EQUAL", - "_(__foo__)_\n": "TO_EQUAL", - "__foo__bar\n": "NOT_TO_EQUAL", - "__пристаням__стремятся\n": "NOT_TO_EQUAL", - "__foo__bar__baz__\n": "NOT_TO_EQUAL", - "__(bar)__.\n": "TO_EQUAL", - "*foo [bar](/url)*\n": "TO_EQUAL", - "*foo\nbar*\n": "TO_EQUAL", - "_foo __bar__ baz_\n": "TO_EQUAL", - "_foo _bar_ baz_\n": "NOT_TO_EQUAL", - "__foo_ bar_\n": "NOT_TO_EQUAL", - "*foo *bar**\n": "NOT_TO_EQUAL", - "*foo **bar** baz*\n": "TO_EQUAL", - "*foo**bar**baz*\n": "TO_EQUAL", - "***foo** bar*\n": "NOT_TO_EQUAL", - "*foo **bar***\n": "NOT_TO_EQUAL", - "*foo**bar***\n": "NOT_TO_EQUAL", - "*foo **bar *baz* bim** bop*\n": "NOT_TO_EQUAL", - "*foo [*bar*](/url)*\n": "NOT_TO_EQUAL", - "** is not an empty emphasis\n": "TO_EQUAL", - "**** is not an empty strong emphasis\n": "TO_EQUAL", - "**foo [bar](/url)**\n": "TO_EQUAL", - "**foo\nbar**\n": "TO_EQUAL", - "__foo _bar_ baz__\n": "TO_EQUAL", - "__foo __bar__ baz__\n": "NOT_TO_EQUAL", - "____foo__ bar__\n": "NOT_TO_EQUAL", - "**foo **bar****\n": "NOT_TO_EQUAL", - "**foo *bar* baz**\n": "TO_EQUAL", - "**foo*bar*baz**\n": "NOT_TO_EQUAL", - "***foo* bar**\n": "TO_EQUAL", - "**foo *bar***\n": "TO_EQUAL", - "**foo *bar **baz**\nbim* bop**\n": "NOT_TO_EQUAL", - "**foo [*bar*](/url)**\n": "TO_EQUAL", - "__ is not an empty emphasis\n": "TO_EQUAL", - "____ is not an empty strong emphasis\n": "TO_EQUAL", - "foo ***\n": "TO_EQUAL", - "foo *\\**\n": "NOT_TO_EQUAL", - "foo *_*\n": "NOT_TO_EQUAL", - "foo *****\n": "NOT_TO_EQUAL", - "foo **\\***\n": "TO_EQUAL", - "foo **_**\n": "TO_EQUAL", - "**foo*\n": "TO_EQUAL", - "*foo**\n": "NOT_TO_EQUAL", - "***foo**\n": "NOT_TO_EQUAL", - "****foo*\n": "NOT_TO_EQUAL", - "**foo***\n": "NOT_TO_EQUAL", - "*foo****\n": "NOT_TO_EQUAL", - "foo ___\n": "TO_EQUAL", - "foo _\\__\n": "NOT_TO_EQUAL", - "foo _*_\n": "TO_EQUAL", - "foo _____\n": "NOT_TO_EQUAL", - "foo __\\___\n": "TO_EQUAL", - "foo __*__\n": "TO_EQUAL", - "__foo_\n": "TO_EQUAL", - "_foo__\n": "NOT_TO_EQUAL", - "___foo__\n": "NOT_TO_EQUAL", - "____foo_\n": "NOT_TO_EQUAL", - "__foo___\n": "NOT_TO_EQUAL", - "_foo____\n": "NOT_TO_EQUAL", - "**foo**\n": "TO_EQUAL", - "*_foo_*\n": "NOT_TO_EQUAL", - "__foo__\n": "TO_EQUAL", - "_*foo*_\n": "NOT_TO_EQUAL", - "****foo****\n": "NOT_TO_EQUAL", - "____foo____\n": "NOT_TO_EQUAL", - "******foo******\n": "NOT_TO_EQUAL", - "***foo***\n": "TO_EQUAL", - "_____foo_____\n": "NOT_TO_EQUAL", - "*foo _bar* baz_\n": "TO_EQUAL", - "*foo __bar *baz bim__ bam*\n": "NOT_TO_EQUAL", - "**foo **bar baz**\n": "NOT_TO_EQUAL", - "*foo *bar baz*\n": "NOT_TO_EQUAL", - "*[bar*](/url)\n": "NOT_TO_EQUAL", - "_foo [bar_](/url)\n": "NOT_TO_EQUAL", - "*\n": "NOT_TO_EQUAL", - "**\n": "NOT_TO_EQUAL", - "__\n": "NOT_TO_EQUAL", - "*a `*`*\n": "NOT_TO_EQUAL", - "_a `_`_\n": "NOT_TO_EQUAL", - "**a\n": "NOT_TO_EQUAL", - "__a\n": "NOT_TO_EQUAL", - "[link](/uri \"title\")\n": "TO_EQUAL", - "[link](/uri)\n": "TO_EQUAL", - "[link]()\n": "TO_EQUAL", - "[link](<>)\n": "TO_EQUAL", - "[link](/my uri)\n": "TO_EQUAL", - "[link]()\n": "NOT_TO_EQUAL", - "[link](foo\nbar)\n": "TO_EQUAL", - "[link]()\n": "TO_EQUAL", - "[link](\\(foo\\))\n": "TO_EQUAL", - "[link](foo(and(bar)))\n": "TO_EQUAL", - "[link](foo\\(and\\(bar\\))\n": "TO_EQUAL", - "[link]()\n": "TO_EQUAL", - "[link](foo\\)\\:)\n": "TO_EQUAL", - "[link](#fragment)\n\n[link](http://example.com#fragment)\n\n[link](http://example.com?foo=3#frag)\n": "TO_EQUAL", - "[link](foo\\bar)\n": "TO_EQUAL", - "[link](foo%20bä)\n": "TO_EQUAL", - "[link](\"title\")\n": "TO_EQUAL", - "[link](/url \"title\")\n[link](/url 'title')\n[link](/url (title))\n": "TO_EQUAL", - "[link](/url \"title \\\""\")\n": "NOT_TO_EQUAL", - "[link](/url \"title\")\n": "NOT_TO_EQUAL", - "[link](/url \"title \"and\" title\")\n": "NOT_TO_EQUAL", - "[link](/url 'title \"and\" title')\n": "NOT_TO_EQUAL", - "[link]( /uri\n \"title\" )\n": "TO_EQUAL", - "[link] (/uri)\n": "NOT_TO_EQUAL", - "[link [foo [bar]]](/uri)\n": "NOT_TO_EQUAL", - "[link] bar](/uri)\n": "TO_EQUAL", - "[link [bar](/uri)\n": "TO_EQUAL", - "[link \\[bar](/uri)\n": "NOT_TO_EQUAL", - "[link *foo **bar** `#`*](/uri)\n": "TO_EQUAL", - "[![moon](moon.jpg)](/uri)\n": "NOT_TO_EQUAL", - "[foo [bar](/uri)](/uri)\n": "NOT_TO_EQUAL", - "[foo *[bar [baz](/uri)](/uri)*](/uri)\n": "NOT_TO_EQUAL", - "![[[foo](uri1)](uri2)](uri3)\n": "NOT_TO_EQUAL", - "*[foo*](/uri)\n": "NOT_TO_EQUAL", - "[foo *bar](baz*)\n": "TO_EQUAL", - "*foo [bar* baz]\n": "TO_EQUAL", - "[foo \n": "NOT_TO_EQUAL", - "[foo`](/uri)`\n": "NOT_TO_EQUAL", - "[foo\n": "NOT_TO_EQUAL", - "[foo][bar]\n\n[bar]: /url \"title\"\n": "TO_EQUAL", - "[link [foo [bar]]][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[link \\[bar][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[link *foo **bar** `#`*][ref]\n\n[ref]: /uri\n": "TO_EQUAL", - "[![moon](moon.jpg)][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo [bar](/uri)][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo *bar [baz][ref]*][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "*[foo*][ref]\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo *bar][ref]\n\n[ref]: /uri\n": "TO_EQUAL", - "[foo \n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo`][ref]`\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo\n\n[ref]: /uri\n": "NOT_TO_EQUAL", - "[foo][BaR]\n\n[bar]: /url \"title\"\n": "TO_EQUAL", - "[Толпой][Толпой] is a Russian word.\n\n[ТОЛПОЙ]: /url\n": "TO_EQUAL", - "[Foo\n bar]: /url\n\n[Baz][Foo bar]\n": "TO_EQUAL", - "[foo] [bar]\n\n[bar]: /url \"title\"\n": "NOT_TO_EQUAL", - "[foo]\n[bar]\n\n[bar]: /url \"title\"\n": "NOT_TO_EQUAL", - "[foo]: /url1\n\n[foo]: /url2\n\n[bar][foo]\n": "NOT_TO_EQUAL", - "[bar][foo\\!]\n\n[foo!]: /url\n": "NOT_TO_EQUAL", - "[foo][ref[]\n\n[ref[]: /uri\n": "NOT_TO_EQUAL", - "[foo][ref[bar]]\n\n[ref[bar]]: /uri\n": "NOT_TO_EQUAL", - "[[[foo]]]\n\n[[[foo]]]: /url\n": "TO_EQUAL", - "[foo][ref\\[]\n\n[ref\\[]: /uri\n": "TO_EQUAL", - "[bar\\\\]: /uri\n\n[bar\\\\]\n": "NOT_TO_EQUAL", - "[]\n\n[]: /uri\n": "TO_EQUAL", - "[\n ]\n\n[\n ]: /uri\n": "NOT_TO_EQUAL", - "[foo][]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "[*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n": "TO_EQUAL", - "[Foo][]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "[foo] \n[]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "[foo]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "[*foo* bar]\n\n[*foo* bar]: /url \"title\"\n": "TO_EQUAL", - "[[*foo* bar]]\n\n[*foo* bar]: /url \"title\"\n": "TO_EQUAL", - "[[bar [foo]\n\n[foo]: /url\n": "TO_EQUAL", - "[Foo]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "[foo] bar\n\n[foo]: /url\n": "TO_EQUAL", - "\\[foo]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "[foo*]: /url\n\n*[foo*]\n": "NOT_TO_EQUAL", - "[foo][bar]\n\n[foo]: /url1\n[bar]: /url2\n": "TO_EQUAL", - "[foo][]\n\n[foo]: /url1\n": "TO_EQUAL", - "[foo]()\n\n[foo]: /url1\n": "TO_EQUAL", - "[foo](not a link)\n\n[foo]: /url1\n": "TO_EQUAL", - "[foo][bar][baz]\n\n[baz]: /url\n": "NOT_TO_EQUAL", - "[foo][bar][baz]\n\n[baz]: /url1\n[bar]: /url2\n": "TO_EQUAL", - "[foo][bar][baz]\n\n[baz]: /url1\n[foo]: /url2\n": "NOT_TO_EQUAL", - "![foo](/url \"title\")\n": "NOT_TO_EQUAL", - "![foo *bar*]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n": "NOT_TO_EQUAL", - "![foo ![bar](/url)](/url2)\n": "NOT_TO_EQUAL", - "![foo [bar](/url)](/url2)\n": "NOT_TO_EQUAL", - "![foo *bar*][]\n\n[foo *bar*]: train.jpg \"train & tracks\"\n": "NOT_TO_EQUAL", - "![foo *bar*][foobar]\n\n[FOOBAR]: train.jpg \"train & tracks\"\n": "NOT_TO_EQUAL", - "![foo](train.jpg)\n": "NOT_TO_EQUAL", - "My ![foo bar](/path/to/train.jpg \"title\" )\n": "NOT_TO_EQUAL", - "![foo]()\n": "NOT_TO_EQUAL", - "![](/url)\n": "NOT_TO_EQUAL", - "![foo][bar]\n\n[bar]: /url\n": "NOT_TO_EQUAL", - "![foo][bar]\n\n[BAR]: /url\n": "NOT_TO_EQUAL", - "![foo][]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "![*foo* bar][]\n\n[*foo* bar]: /url \"title\"\n": "NOT_TO_EQUAL", - "![Foo][]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "![foo] \n[]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "![foo]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "![*foo* bar]\n\n[*foo* bar]: /url \"title\"\n": "NOT_TO_EQUAL", - "![[foo]]\n\n[[foo]]: /url \"title\"\n": "NOT_TO_EQUAL", - "![Foo]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "!\\[foo]\n\n[foo]: /url \"title\"\n": "TO_EQUAL", - "\\![foo]\n\n[foo]: /url \"title\"\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "<>\n": "NOT_TO_EQUAL", - "< http://foo.bar >\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "http://example.com\n": "TO_EQUAL", - "foo@bar.example.com\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "Foo \n": "TO_EQUAL", - "<33> <__>\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - " \n": "NOT_TO_EQUAL", - "< a><\nfoo>\n": "NOT_TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "foo \n": "TO_EQUAL", - "foo \n": "NOT_TO_EQUAL", - "foo foo -->\n\nfoo \n": "NOT_TO_EQUAL", - "foo \n": "TO_EQUAL", - "foo \n": "TO_EQUAL", - "foo &<]]>\n": "NOT_TO_EQUAL", - "foo \n": "TO_EQUAL", - "foo \n": "TO_EQUAL", - "\n": "NOT_TO_EQUAL", - "foo \nbaz\n": "NOT_TO_EQUAL", - "foo\\\nbaz\n": "NOT_TO_EQUAL", - "foo \nbaz\n": "NOT_TO_EQUAL", - "foo \n bar\n": "NOT_TO_EQUAL", - "foo\\\n bar\n": "NOT_TO_EQUAL", - "*foo \nbar*\n": "NOT_TO_EQUAL", - "*foo\\\nbar*\n": "NOT_TO_EQUAL", - "`code \nspan`\n": "TO_EQUAL", - "`code\\\nspan`\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "\n": "TO_EQUAL", - "foo\\\n": "TO_EQUAL", - "foo \n": "TO_EQUAL", - "### foo\\\n": "TO_EQUAL", - "### foo \n": "TO_EQUAL", - "foo\nbaz\n": "TO_EQUAL", - "foo \n baz\n": "TO_EQUAL", - "hello $.;'there\n": "TO_EQUAL", - "Foo χρῆν\n": "TO_EQUAL", - "Multiple spaces\n": "TO_EQUAL" -} \ No newline at end of file diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/duplicate_marks_github_issue_3280.md b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/duplicate_marks_github_issue_3280.md deleted file mode 100644 index 2d6cad7d..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/__fixtures__/duplicate_marks_github_issue_3280.md +++ /dev/null @@ -1 +0,0 @@ -Fill to_*this*_mark, and your charge is but a penny; to_*this*_a penny more; and so on to the full glass—the Cape Horn measure, which you may gulp down for a shilling.\n\nUpon entering the place I found a number of young seamen gathered about a table, examining by a dim light divers specimens of_*skrimshander*. \ No newline at end of file diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/commonmark.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/commonmark.spec.js deleted file mode 100644 index 59988210..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/commonmark.spec.js +++ /dev/null @@ -1,110 +0,0 @@ -import { flow } from 'lodash'; -import { tests as commonmarkSpec } from 'commonmark-spec'; -import * as commonmark from 'commonmark'; - -import { markdownToSlate, slateToMarkdown } from '../index.js'; - -const skips = [ - { - number: [456], - reason: 'Remark ¯\\_(ツ)_/¯', - }, - { - number: [416, 417, 424, 425, 426, 431, 457, 460, 462, 464, 467], - reason: 'Remark does not support infinite (redundant) nested marks', - }, - { - number: [455, 469, 470, 471], - reason: 'Remark parses the initial set of identical nested delimiters first', - }, - { - number: [473, 476, 478, 480], - reason: 'we convert underscores to asterisks for strong/emphasis', - }, - { number: 490, reason: 'Remark strips pointy enclosing pointy brackets from link url' }, - { number: 503, reason: 'Remark allows non-breaking space between link url and title' }, - { number: 507, reason: 'Remark allows a space between link alt and url' }, - { - number: [ - 511, 516, 525, 528, 529, 530, 532, 533, 534, 540, 541, 542, 543, 546, 548, 560, 565, 567, - ], - reason: 'we convert link references to standard links, but Remark also fails these', - }, - { - number: [569, 570, 571, 572, 573, 581, 585], - reason: 'Remark does not recognize or remove marks in image alt text', - }, - { number: 589, reason: 'Remark does not honor backslash escape of image exclamation point' }, - { number: 593, reason: 'Remark removes "mailto:" from autolink text' }, - { number: 599, reason: 'Remark does not escape all expected entities' }, - { number: 602, reason: 'Remark allows autolink emails to contain backslashes' }, -]; - -const onlys = [ - // just add the spec number, eg: - // 431, -]; - -/** - * Each test receives input markdown and output html as expected for Commonmark - * compliance. To test all of our handling in one go, we serialize the markdown - * into our Slate AST, then back to raw markdown, and finally to HTML. - */ -const reader = new commonmark.Parser(); -const writer = new commonmark.HtmlRenderer(); - -function parseWithCommonmark(markdown) { - const parsed = reader.parse(markdown); - return writer.render(parsed); -} - -const parse = flow([markdownToSlate, slateToMarkdown]); - -/** - * Passing this test suite requires 100% Commonmark compliance. There are 624 - * tests, of which we're passing about 300 as of introduction of this suite. To - * work on improving Commonmark support, update __fixtures__/commonmarkExpected.json - */ -describe.skip('Commonmark support', function () { - const specs = - onlys.length > 0 - ? commonmarkSpec.filter(({ number }) => onlys.includes(number)) - : commonmarkSpec; - specs.forEach(spec => { - const skip = skips.find(({ number }) => { - return Array.isArray(number) ? number.includes(spec.number) : number === spec.number; - }); - const specUrl = `https://spec.commonmark.org/0.29/#example-${spec.number}`; - const parsed = parse(spec.markdown); - const commonmarkParsedHtml = parseWithCommonmark(parsed); - const description = ` -${spec.section} -${specUrl} - -Spec: -${JSON.stringify(spec, null, 2)} - -Markdown input: -${spec.markdown} - -Markdown parsed through Slate/Remark and back to Markdown: -${parsed} - -HTML output: -${commonmarkParsedHtml} - -Expected HTML output: -${spec.html} - `; - if (skip) { - const showMessage = Array.isArray(skip.number) ? skip.number[0] === spec.number : true; - if (showMessage) { - //console.log(`skipping spec ${skip.number}\n${skip.reason}\n${specUrl}`); - } - } - const testFn = skip ? test.skip : test; - testFn(description, () => { - expect(commonmarkParsedHtml).toEqual(spec.html); - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/index.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/index.spec.js deleted file mode 100644 index 0605de95..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/index.spec.js +++ /dev/null @@ -1,65 +0,0 @@ -import path from 'path'; -import fs from 'fs'; - -import { markdownToSlate, htmlToSlate } from '../'; - -describe('markdownToSlate', () => { - it('should not add duplicate identical marks under the same node (GitHub Issue 3280)', () => { - const mdast = fs.readFileSync( - path.join(__dirname, '__fixtures__', 'duplicate_marks_github_issue_3280.md'), - ); - const slate = markdownToSlate(mdast); - - expect(slate).toEqual({ - object: 'block', - type: 'root', - nodes: [ - { - object: 'block', - type: 'paragraph', - nodes: [ - { - object: 'text', - text: 'Fill to', - }, - { - object: 'text', - text: 'this_mark, and your charge is but a penny; tothisa penny more; and so on to the full glass—the Cape Horn measure, which you may gulp down for a shilling.\\n\\nUpon entering the place I found a number of young seamen gathered about a table, examining by a dim light divers specimens ofskrimshander', - marks: [ - { - type: 'italic', - }, - ], - }, - { - object: 'text', - text: '.', - }, - ], - }, - ], - }); - }); -}); - -describe('htmlToSlate', () => { - it('should preserve spaces in rich html (GitHub Issue 3727)', () => { - const html = `Bold Text regular text `; - - const actual = htmlToSlate(html); - expect(actual).toEqual({ - object: 'block', - type: 'root', - nodes: [ - { - object: 'block', - type: 'paragraph', - nodes: [ - { object: 'text', text: 'Bold Text', marks: [{ type: 'bold' }] }, - { object: 'text', text: ' regular text' }, - ], - }, - ], - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAllowHtmlEntities.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAllowHtmlEntities.spec.js deleted file mode 100644 index 844137f0..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAllowHtmlEntities.spec.js +++ /dev/null @@ -1,25 +0,0 @@ -import unified from 'unified'; -import markdownToRemark from 'remark-parse'; - -import remarkAllowHtmlEntities from '../remarkAllowHtmlEntities'; - -function process(markdown) { - const mdast = unified().use(markdownToRemark).use(remarkAllowHtmlEntities).parse(markdown); - - /** - * The MDAST will look like: - * - * { type: 'root', children: [ - * { type: 'paragraph', children: [ - * // results here - * ]} - * ]} - */ - return mdast.children[0].children[0].value; -} - -describe('remarkAllowHtmlEntities', () => { - it('should not decode HTML entities', () => { - expect(process('<div>')).toEqual('<div>'); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAssertParents.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAssertParents.spec.js deleted file mode 100644 index e2dfa358..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkAssertParents.spec.js +++ /dev/null @@ -1,171 +0,0 @@ -import u from 'unist-builder'; - -import remarkAssertParents from '../remarkAssertParents'; - -const transform = remarkAssertParents(); - -describe('remarkAssertParents', () => { - it('should unnest invalidly nested blocks', () => { - const input = u('root', [ - u('paragraph', [ - u('paragraph', [u('text', 'Paragraph text.')]), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('code', 'someCode()'), - u('blockquote', [u('text', 'Quote text.')]), - u('list', [u('listItem', [u('text', 'A list item.')])]), - u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]), - u('thematicBreak'), - ]), - ]); - - const output = u('root', [ - u('paragraph', [u('text', 'Paragraph text.')]), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('code', 'someCode()'), - u('blockquote', [u('text', 'Quote text.')]), - u('list', [u('listItem', [u('text', 'A list item.')])]), - u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]), - u('thematicBreak'), - ]); - - expect(transform(input)).toEqual(output); - }); - - it('should unnest deeply nested blocks', () => { - const input = u('root', [ - u('paragraph', [ - u('paragraph', [ - u('paragraph', [ - u('paragraph', [u('text', 'Paragraph text.')]), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('code', 'someCode()'), - u('blockquote', [ - u('paragraph', [u('strong', [u('heading', [u('text', 'Quote text.')])])]), - ]), - u('list', [u('listItem', [u('text', 'A list item.')])]), - u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]), - u('thematicBreak'), - ]), - ]), - ]), - ]); - - const output = u('root', [ - u('paragraph', [u('text', 'Paragraph text.')]), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('code', 'someCode()'), - u('blockquote', [u('heading', [u('text', 'Quote text.')])]), - u('list', [u('listItem', [u('text', 'A list item.')])]), - u('table', [u('tableRow', [u('tableCell', [u('text', 'Text in a table cell.')])])]), - u('thematicBreak'), - ]); - - expect(transform(input)).toEqual(output); - }); - - it('should remove blocks that are emptied as a result of denesting', () => { - const input = u('root', [ - u('paragraph', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]), - ]); - - const output = u('root', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]); - - expect(transform(input)).toEqual(output); - }); - - it('should remove blocks that are emptied as a result of denesting', () => { - const input = u('root', [ - u('paragraph', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]), - ]); - - const output = u('root', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]); - - expect(transform(input)).toEqual(output); - }); - - it('should handle assymetrical splits', () => { - const input = u('root', [ - u('paragraph', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]), - ]); - - const output = u('root', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]); - - expect(transform(input)).toEqual(output); - }); - - it('should nest invalidly nested blocks in the nearest valid ancestor', () => { - const input = u('root', [ - u('paragraph', [ - u('blockquote', [u('strong', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])])]), - ]), - ]); - - const output = u('root', [ - u('blockquote', [u('heading', { depth: 1 }, [u('text', 'Heading text.')])]), - ]); - - expect(transform(input)).toEqual(output); - }); - - it('should preserve validly nested siblings of invalidly nested blocks', () => { - const input = u('root', [ - u('paragraph', [ - u('blockquote', [ - u('strong', [ - u('text', 'Deep validly nested text a.'), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('text', 'Deep validly nested text b.'), - ]), - ]), - u('text', 'Validly nested text.'), - ]), - ]); - - const output = u('root', [ - u('blockquote', [ - u('strong', [u('text', 'Deep validly nested text a.')]), - u('heading', { depth: 1 }, [u('text', 'Heading text.')]), - u('strong', [u('text', 'Deep validly nested text b.')]), - ]), - u('paragraph', [u('text', 'Validly nested text.')]), - ]); - - expect(transform(input)).toEqual(output); - }); - - it('should allow intermediate parents like list and table to contain required block children', () => { - const input = u('root', [ - u('blockquote', [ - u('list', [ - u('listItem', [ - u('table', [ - u('tableRow', [ - u('tableCell', [ - u('heading', { depth: 1 }, [u('text', 'Validly nested heading text.')]), - ]), - ]), - ]), - ]), - ]), - ]), - ]); - - const output = u('root', [ - u('blockquote', [ - u('list', [ - u('listItem', [ - u('table', [ - u('tableRow', [ - u('tableCell', [ - u('heading', { depth: 1 }, [u('text', 'Validly nested heading text.')]), - ]), - ]), - ]), - ]), - ]), - ]), - ]); - - expect(transform(input)).toEqual(output); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkEscapeMarkdownEntities.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkEscapeMarkdownEntities.spec.js deleted file mode 100644 index 37ff0a85..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkEscapeMarkdownEntities.spec.js +++ /dev/null @@ -1,84 +0,0 @@ -import unified from 'unified'; -import u from 'unist-builder'; - -import remarkEscapeMarkdownEntities from '../remarkEscapeMarkdownEntities'; - -function process(text) { - const tree = u('root', [u('text', text)]); - const escapedMdast = unified().use(remarkEscapeMarkdownEntities).runSync(tree); - - return escapedMdast.children[0].value; -} - -describe('remarkEscapeMarkdownEntities', () => { - it('should escape common markdown entities', () => { - expect(process('*a*')).toEqual('\\*a\\*'); - expect(process('**a**')).toEqual('\\*\\*a\\*\\*'); - expect(process('***a***')).toEqual('\\*\\*\\*a\\*\\*\\*'); - expect(process('_a_')).toEqual('\\_a\\_'); - expect(process('__a__')).toEqual('\\_\\_a\\_\\_'); - expect(process('~~a~~')).toEqual('\\~\\~a\\~\\~'); - expect(process('[]')).toEqual('\\[]'); - expect(process('[]()')).toEqual('\\[]()'); - expect(process('[a](b)')).toEqual('\\[a](b)'); - expect(process('[Test sentence.](https://www.example.com)')).toEqual( - '\\[Test sentence.](https://www.example.com)', - ); - expect(process('![a](b)')).toEqual('!\\[a](b)'); - }); - - it('should not escape inactive, single markdown entities', () => { - expect(process('a*b')).toEqual('a*b'); - expect(process('_')).toEqual('_'); - expect(process('~')).toEqual('~'); - expect(process('[')).toEqual('['); - }); - - it('should escape leading markdown entities', () => { - expect(process('#')).toEqual('\\#'); - expect(process('-')).toEqual('\\-'); - expect(process('*')).toEqual('\\*'); - expect(process('>')).toEqual('\\>'); - expect(process('=')).toEqual('\\='); - expect(process('|')).toEqual('\\|'); - expect(process('```')).toEqual('\\`\\``'); - expect(process(' ')).toEqual('\\ '); - }); - - it('should escape leading markdown entities preceded by whitespace', () => { - expect(process('\n #')).toEqual('\\#'); - expect(process(' \n-')).toEqual('\\-'); - }); - - it('should not escape leading markdown entities preceded by non-whitespace characters', () => { - expect(process('a# # b #')).toEqual('a# # b #'); - expect(process('a- - b -')).toEqual('a- - b -'); - }); - - it('should not escape html tags', () => { - expect(process('')).toEqual(''); - expect(process('a b e')).toEqual('a b e'); - }); - - it('should escape the contents of html blocks', () => { - expect(process('
    *a*
    ')).toEqual('
    \\*a\\*
    '); - }); - - it('should not escape the contents of preformatted html blocks', () => { - expect(process('
    *a*
    ')).toEqual('
    *a*
    '); - expect(process('')).toEqual(''); - expect(process('')).toEqual(''); - expect(process('
    \n*a*\n
    ')).toEqual('
    \n*a*\n
    '); - expect(process('a b
    *c*
    d e')).toEqual('a b
    *c*
    d e'); - }); - - it('should not escape footnote references', () => { - expect(process('[^a]')).toEqual('[^a]'); - expect(process('[^1]')).toEqual('[^1]'); - }); - - it('should not escape footnotes', () => { - expect(process('[^a]:')).toEqual('[^a]:'); - expect(process('[^1]:')).toEqual('[^1]:'); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPaddedLinks.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPaddedLinks.spec.js deleted file mode 100644 index 0d5cf4ab..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPaddedLinks.spec.js +++ /dev/null @@ -1,43 +0,0 @@ -import unified from 'unified'; -import markdownToRemark from 'remark-parse'; -import remarkToMarkdown from 'remark-stringify'; - -import remarkPaddedLinks from '../remarkPaddedLinks'; - -function input(markdown) { - return unified() - .use(markdownToRemark) - .use(remarkPaddedLinks) - .use(remarkToMarkdown) - .processSync(markdown).contents; -} - -function output(markdown) { - return unified().use(markdownToRemark).use(remarkToMarkdown).processSync(markdown).contents; -} - -describe('remarkPaddedLinks', () => { - it('should move leading and trailing spaces outside of a link', () => { - expect(input('[ a ](b)')).toEqual(output(' [a](b) ')); - }); - - it('should convert multiple leading or trailing spaces to a single space', () => { - expect(input('[ a ](b)')).toEqual(output(' [a](b) ')); - }); - - it('should work with only a leading space or only a trailing space', () => { - expect(input('[ a](b)[c ](d)')).toEqual(output(' [a](b)[c](d) ')); - }); - - it('should work for nested links', () => { - expect(input('* # a[ b ](c)d')).toEqual(output('* # a [b](c) d')); - }); - - it('should work for parents with multiple links that are not siblings', () => { - expect(input('# a[ b ](c)d **[ e ](f)**')).toEqual(output('# a [b](c) d ** [e](f) **')); - }); - - it('should work for links with arbitrarily nested children', () => { - expect(input('[ a __*b*__ _c_ ](d)')).toEqual(output(' [a __*b*__ _c_](d) ')); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPlugins.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPlugins.spec.js deleted file mode 100644 index 83ccf907..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkPlugins.spec.js +++ /dev/null @@ -1,299 +0,0 @@ -import visit from 'unist-util-visit'; - -import { markdownToRemark, remarkToMarkdown } from '..'; - -describe('registered remark plugins', () => { - function withNetlifyLinks() { - return function transformer(tree) { - visit(tree, 'link', function onLink(node) { - node.url = 'https://netlify.com'; - }); - }; - } - - it('should use remark transformer plugins when converting mdast to markdown', () => { - const plugins = [withNetlifyLinks]; - const result = remarkToMarkdown( - { - type: 'root', - children: [ - { - type: 'paragraph', - children: [ - { - type: 'text', - value: 'Some ', - }, - { - type: 'emphasis', - children: [ - { - type: 'text', - value: 'important', - }, - ], - }, - { - type: 'text', - value: ' text with ', - }, - { - type: 'link', - title: null, - url: 'https://this-value-should-be-replaced.com', - children: [ - { - type: 'text', - value: 'a link', - }, - ], - }, - { - type: 'text', - value: ' in it.', - }, - ], - }, - ], - }, - plugins, - ); - expect(result).toMatchInlineSnapshot( - `"Some *important* text with [a link](https://netlify.com) in it."`, - ); - }); - - it('should use remark transformer plugins when converting markdown to mdast', () => { - const plugins = [withNetlifyLinks]; - const result = markdownToRemark( - 'Some text with [a link](https://this-value-should-be-replaced.com) in it.', - plugins, - ); - expect(result).toMatchInlineSnapshot(` -Object { - "children": Array [ - Object { - "children": Array [ - Object { - "children": Array [], - "position": Position { - "end": Object { - "column": 16, - "line": 1, - "offset": 15, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "text", - "value": "Some text with ", - }, - Object { - "children": Array [ - Object { - "children": Array [], - "position": Position { - "end": Object { - "column": 23, - "line": 1, - "offset": 22, - }, - "indent": Array [], - "start": Object { - "column": 17, - "line": 1, - "offset": 16, - }, - }, - "type": "text", - "value": "a link", - }, - ], - "position": Position { - "end": Object { - "column": 67, - "line": 1, - "offset": 66, - }, - "indent": Array [], - "start": Object { - "column": 16, - "line": 1, - "offset": 15, - }, - }, - "title": null, - "type": "link", - "url": "https://netlify.com", - }, - Object { - "children": Array [], - "position": Position { - "end": Object { - "column": 74, - "line": 1, - "offset": 73, - }, - "indent": Array [], - "start": Object { - "column": 67, - "line": 1, - "offset": 66, - }, - }, - "type": "text", - "value": " in it.", - }, - ], - "position": Position { - "end": Object { - "column": 74, - "line": 1, - "offset": 73, - }, - "indent": Array [], - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "paragraph", - }, - ], - "position": Object { - "end": Object { - "column": 74, - "line": 1, - "offset": 73, - }, - "start": Object { - "column": 1, - "line": 1, - "offset": 0, - }, - }, - "type": "root", -} -`); - }); - - it('should use remark serializer plugins when converting mdast to markdown', () => { - function withEscapedLessThanChar() { - if (this.Compiler) { - this.Compiler.prototype.visitors.text = node => { - return node.value.replace(/ { - const settings = { - emphasis: '_', - bullet: '-', - }; - - const plugins = [{ settings }]; - const result = remarkToMarkdown( - { - type: 'root', - children: [ - { - type: 'paragraph', - children: [ - { - type: 'text', - value: 'Some ', - }, - { - type: 'emphasis', - children: [ - { - type: 'text', - value: 'important', - }, - ], - }, - { - type: 'text', - value: ' points:', - }, - ], - }, - { - type: 'list', - ordered: false, - start: null, - spread: false, - children: [ - { - type: 'listItem', - spread: false, - checked: null, - children: [ - { - type: 'paragraph', - children: [ - { - type: 'text', - value: 'One', - }, - ], - }, - ], - }, - { - type: 'listItem', - spread: false, - checked: null, - children: [ - { - type: 'paragraph', - children: [ - { - type: 'text', - value: 'Two', - }, - ], - }, - ], - }, - ], - }, - ], - }, - plugins, - ); - expect(result).toMatchInlineSnapshot(` -"Some _important_ points: - -- One -- Two" -`); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkShortcodes.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkShortcodes.spec.js deleted file mode 100644 index 53d4ea04..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkShortcodes.spec.js +++ /dev/null @@ -1,106 +0,0 @@ -import { Map, OrderedMap } from 'immutable'; - -import { remarkParseShortcodes, getLinesWithOffsets } from '../remarkShortcodes'; - -// Stub of Remark Parser -function process(value, plugins, processEat = () => {}) { - function eat() { - return processEat; - } - - function Parser() {} - Parser.prototype.blockTokenizers = {}; - Parser.prototype.blockMethods = []; - remarkParseShortcodes.call({ Parser }, { plugins }); - Parser.prototype.blockTokenizers.shortcode(eat, value); -} - -function EditorComponent({ id = 'foo', fromBlock = jest.fn(), pattern }) { - return { - id, - fromBlock, - pattern, - }; -} - -describe('remarkParseShortcodes', () => { - describe('pattern matching', () => { - it('should work', () => { - const editorComponent = EditorComponent({ pattern: /bar/ }); - process('foo bar', Map({ [editorComponent.id]: editorComponent })); - expect(editorComponent.fromBlock).toHaveBeenCalledWith(expect.arrayContaining(['bar'])); - }); - it('should match value surrounded in newlines', () => { - const editorComponent = EditorComponent({ pattern: /^bar$/ }); - process('foo\n\nbar\n', Map({ [editorComponent.id]: editorComponent })); - expect(editorComponent.fromBlock).toHaveBeenCalledWith(expect.arrayContaining(['bar'])); - }); - it('should match multiline shortcodes', () => { - const editorComponent = EditorComponent({ pattern: /^foo\nbar$/ }); - process('foo\nbar', Map({ [editorComponent.id]: editorComponent })); - expect(editorComponent.fromBlock).toHaveBeenCalledWith(expect.arrayContaining(['foo\nbar'])); - }); - it('should match multiline shortcodes with empty lines', () => { - const editorComponent = EditorComponent({ pattern: /^foo\n\nbar$/ }); - process('foo\n\nbar', Map({ [editorComponent.id]: editorComponent })); - expect(editorComponent.fromBlock).toHaveBeenCalledWith( - expect.arrayContaining(['foo\n\nbar']), - ); - }); - it('should match shortcodes based on order of occurrence in value', () => { - const fooEditorComponent = EditorComponent({ id: 'foo', pattern: /foo/ }); - const barEditorComponent = EditorComponent({ id: 'bar', pattern: /bar/ }); - process( - 'foo\n\nbar', - OrderedMap([ - [barEditorComponent.id, barEditorComponent], - [fooEditorComponent.id, fooEditorComponent], - ]), - ); - expect(fooEditorComponent.fromBlock).toHaveBeenCalledWith(expect.arrayContaining(['foo'])); - }); - it('should match shortcodes based on order of occurrence in value even when some use line anchors', () => { - const barEditorComponent = EditorComponent({ id: 'bar', pattern: /bar/ }); - const bazEditorComponent = EditorComponent({ id: 'baz', pattern: /^baz$/ }); - process( - 'foo\n\nbar\n\nbaz', - OrderedMap([ - [bazEditorComponent.id, bazEditorComponent], - [barEditorComponent.id, barEditorComponent], - ]), - ); - expect(barEditorComponent.fromBlock).toHaveBeenCalledWith(expect.arrayContaining(['bar'])); - }); - }); - describe('output', () => { - it('should be a remark shortcode node', () => { - const processEat = jest.fn(); - const shortcodeData = { bar: 'baz' }; - const expectedNode = { type: 'shortcode', data: { shortcode: 'foo', shortcodeData } }; - const editorComponent = EditorComponent({ pattern: /bar/, fromBlock: () => shortcodeData }); - process('foo bar', Map({ [editorComponent.id]: editorComponent }), processEat); - expect(processEat).toHaveBeenCalledWith(expectedNode); - }); - }); -}); - -describe('getLinesWithOffsets', () => { - test('should split into lines', () => { - const value = ' line1\n\nline2 \n\n line3 \n\n'; - - const lines = getLinesWithOffsets(value); - expect(lines).toEqual([ - { line: ' line1', start: 0 }, - { line: 'line2', start: 8 }, - { line: ' line3', start: 16 }, - { line: '', start: 30 }, - ]); - }); - - test('should return single item on no match', () => { - const value = ' line1 '; - - const lines = getLinesWithOffsets(value); - expect(lines).toEqual([{ line: ' line1', start: 0 }]); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkSlate.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkSlate.spec.js deleted file mode 100644 index 9c952f25..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkSlate.spec.js +++ /dev/null @@ -1,145 +0,0 @@ -import { wrapInlinesWithTexts, mergeAdjacentTexts } from '../remarkSlate'; -describe('remarkSlate', () => { - describe('wrapInlinesWithTexts', () => { - it('should handle empty array', () => { - const children = []; - expect(wrapInlinesWithTexts(children)).toBe(children); - }); - - it('should wrap single inline node with texts', () => { - expect(wrapInlinesWithTexts([{ object: 'inline' }])).toEqual([ - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - ]); - }); - - it('should insert text before inline', () => { - expect(wrapInlinesWithTexts([{ object: 'inline' }, { object: 'text', text: '' }])).toEqual([ - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - ]); - }); - - it('should insert text after inline', () => { - expect(wrapInlinesWithTexts([{ object: 'text', text: '' }, { object: 'inline' }])).toEqual([ - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - ]); - }); - - it('should not modify valid children array', () => { - const children = [ - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - ]; - expect(wrapInlinesWithTexts(children)).toBe(children); - }); - - it('should wrap inlines with text nodes', () => { - expect( - wrapInlinesWithTexts([ - { object: 'inline' }, - { object: 'other' }, - { object: 'inline' }, - { object: 'inline' }, - { object: 'other' }, - { object: 'text', text: 'hello' }, - { object: 'inline' }, - { object: 'inline' }, - { object: 'text', text: 'world' }, - { object: 'inline' }, - ]), - ).toEqual([ - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - { object: 'other' }, - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: '' }, - { object: 'other' }, - { object: 'text', text: 'hello' }, - { object: 'inline' }, - { object: 'text', text: '' }, - { object: 'inline' }, - { object: 'text', text: 'world' }, - { object: 'inline' }, - { object: 'text', text: '' }, - ]); - }); - }); - - describe('mergeAdjacentTexts', () => { - it('should handle empty array', () => { - const children = []; - expect(mergeAdjacentTexts(children)).toBe(children); - }); - - it('should merge adjacent texts with same marks', () => { - const children = [ - { object: 'text', text: '
    ', marks: [] }, - { object: 'text', text: 'Netlify', marks: [] }, - { object: 'text', text: '', marks: [] }, - ]; - - expect(mergeAdjacentTexts(children)).toEqual([ - { - object: 'text', - text: 'Netlify', - marks: [], - }, - ]); - }); - - it('should not merge adjacent texts with different marks', () => { - const children = [ - { object: 'text', text: '', marks: [] }, - { object: 'text', text: 'Netlify', marks: ['b'] }, - { object: 'text', text: '', marks: [] }, - ]; - - expect(mergeAdjacentTexts(children)).toEqual(children); - }); - - it('should handle mixed children array', () => { - const children = [ - { object: 'inline' }, - { object: 'text', text: '', marks: [] }, - { object: 'text', text: 'Netlify', marks: [] }, - { object: 'text', text: '', marks: [] }, - { object: 'inline' }, - { object: 'text', text: '', marks: [] }, - { object: 'text', text: 'Netlify', marks: ['b'] }, - { object: 'text', text: '', marks: [] }, - { object: 'text', text: '', marks: [] }, - { object: 'inline' }, - { object: 'text', text: '', marks: [] }, - ]; - - expect(mergeAdjacentTexts(children)).toEqual([ - { object: 'inline' }, - { - object: 'text', - text: 'Netlify', - marks: [], - }, - { object: 'inline' }, - { object: 'text', text: '', marks: [] }, - { object: 'text', text: 'Netlify', marks: ['b'] }, - { - object: 'text', - text: '', - marks: [], - }, - { object: 'inline' }, - { object: 'text', text: '', marks: [] }, - ]); - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkStripTrailingBreaks.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkStripTrailingBreaks.spec.js deleted file mode 100644 index 67ff12b9..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/remarkStripTrailingBreaks.spec.js +++ /dev/null @@ -1,23 +0,0 @@ -import unified from 'unified'; -import u from 'unist-builder'; - -import remarkStripTrailingBreaks from '../remarkStripTrailingBreaks'; - -function process(children) { - const tree = u('root', children); - const strippedMdast = unified().use(remarkStripTrailingBreaks).runSync(tree); - - return strippedMdast.children; -} - -describe('remarkStripTrailingBreaks', () => { - it('should remove trailing breaks at the end of a block', () => { - expect(process([u('break')])).toEqual([]); - expect(process([u('break'), u('text', '\n \n')])).toEqual([u('text', '\n \n')]); - expect(process([u('text', 'a'), u('break')])).toEqual([u('text', 'a')]); - }); - - it('should not remove trailing breaks that are not at the end of a block', () => { - expect(process([u('break'), u('text', 'a')])).toEqual([u('break'), u('text', 'a')]); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/slate.spec.js b/packages/netlify-cms-widget-markdown/src/serializers/__tests__/slate.spec.js deleted file mode 100644 index 87c66455..00000000 --- a/packages/netlify-cms-widget-markdown/src/serializers/__tests__/slate.spec.js +++ /dev/null @@ -1,295 +0,0 @@ -/** @jsx h */ - -import { flow } from 'lodash'; - -import h from '../../../test-helpers/h'; -import { markdownToSlate, slateToMarkdown } from '../index'; - -const process = flow([markdownToSlate, slateToMarkdown]); - -describe('slate', () => { - it('should not decode encoded html entities in inline code', () => { - expect(process('<div>')).toEqual('<div>'); - }); - - it('should parse non-text children of mark nodes', () => { - expect(process('**a[b](c)d**')).toEqual('**a[b](c)d**'); - expect(process('**[a](b)**')).toEqual('**[a](b)**'); - expect(process('**![a](b)**')).toEqual('**![a](b)**'); - expect(process('_`a`_')).toEqual('*`a`*'); - }); - - it('should handle unstyled code nodes adjacent to styled code nodes', () => { - expect(process('`foo`***`bar`***')).toEqual('`foo`***`bar`***'); - }); - - it('should handle styled code nodes adjacent to non-code text', () => { - expect(process('_`a`b_')).toEqual('*`a`b*'); - expect(process('_`a`**b**_')).toEqual('*`a`**b***'); - }); - - it('should condense adjacent, identically styled text and inline nodes', () => { - expect(process('**a ~~b~~~~c~~**')).toEqual('**a ~~bc~~**'); - expect(process('**a ~~b~~~~[c](d)~~**')).toEqual('**a ~~b[c](d)~~**'); - }); - - it('should handle nested markdown entities', () => { - expect(process('**a**b**c**')).toEqual('**a**b**c**'); - expect(process('**a _b_ c**')).toEqual('**a *b* c**'); - expect(process('*`a`*')).toEqual('*`a`*'); - }); - - it('should parse inline images as images', () => { - expect(process('a ![b](c)')).toEqual('a ![b](c)'); - }); - - it('should not escape markdown entities in html', () => { - expect(process('*')).toEqual('*'); - }); - - it('should wrap break tags in surrounding marks', () => { - expect(process('*a \nb*')).toEqual('*a\\\nb*'); - }); - - it('should not output empty headers in markdown', () => { - // prettier-ignore - const slateAst = ( - - - foo - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"foo"`); - }); - - it('should not output empty marks in markdown', () => { - // prettier-ignore - const slateAst = ( - - - - foobar - baz - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"foobarbaz"`); - }); - - it('should not produce invalid markdown when a styled block has trailing whitespace', () => { - // prettier-ignore - const slateAst = ( - - - foo bar bim bam - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"**foo** bar **bim *bam***"`); - }); - - it('should not produce invalid markdown when a styled block has leading whitespace', () => { - // prettier-ignore - const slateAst = ( - - - foo bar - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"foo **bar**"`); - }); - - it('should group adjacent marks into a single mark when possible', () => { - // prettier-ignore - const slateAst = ( - - - shared mark - - link - - {' '} - not shared mark - - another - link - - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot( - `"**shared mark*[link](link)*** **not shared mark***[another **link**](link)*"`, - ); - }); - - describe('links', () => { - it('should handle inline code in link content', () => { - // prettier-ignore - const slateAst = ( - - - - foo - - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"[\`foo\`](link)"`); - }); - }); - - describe('code marks', () => { - it('can contain other marks', () => { - // prettier-ignore - const slateAst = ( - - - foo - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"***\`foo\`***"`); - }); - - it('can be condensed when no other marks are present', () => { - // prettier-ignore - const slateAst = ( - - - foo - bar - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"\`foo\`"`); - }); - }); - - describe('with nested styles within a single word', () => { - it('should not produce invalid markdown when a bold word has italics applied to a smaller part', () => { - // prettier-ignore - const slateAst = ( - - - h - e - y - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"**h*e*y**"`); - }); - - it('should not produce invalid markdown when an italic word has bold applied to a smaller part', () => { - // prettier-ignore - const slateAst = ( - - - h - e - y - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"*h**e**y*"`); - }); - - it('should handle italics inside bold inside strikethrough', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"~~h**e*l*l**o~~"`); - }); - - it('should handle bold inside italics inside strikethrough', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"~~h*e**l**l*o~~"`); - }); - - it('should handle strikethrough inside italics inside bold', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"**h*e~~l~~l*o**"`); - }); - - it('should handle italics inside strikethrough inside bold', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"**h~~e*l*l~~o**"`); - }); - - it('should handle strikethrough inside bold inside italics', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"*h**e~~l~~l**o*"`); - }); - - it('should handle bold inside strikethrough inside italics', () => { - // prettier-ignore - const slateAst = ( - - - h - e - l - l - o - - - ); - expect(slateToMarkdown(slateAst.toJSON())).toMatchInlineSnapshot(`"*h~~e**l**l~~o*"`); - }); - }); -}); diff --git a/packages/netlify-cms-widget-markdown/test-helpers/h.js b/packages/netlify-cms-widget-markdown/test-helpers/h.js deleted file mode 100644 index f9bf9cd3..00000000 --- a/packages/netlify-cms-widget-markdown/test-helpers/h.js +++ /dev/null @@ -1,32 +0,0 @@ -import { createHyperscript } from 'slate-hyperscript'; - -const h = createHyperscript({ - blocks: { - paragraph: 'paragraph', - 'heading-one': 'heading-one', - 'heading-two': 'heading-two', - 'heading-three': 'heading-three', - 'heading-four': 'heading-four', - 'heading-five': 'heading-five', - 'heading-six': 'heading-six', - quote: 'quote', - 'code-block': 'code-block', - 'bulleted-list': 'bulleted-list', - 'numbered-list': 'numbered-list', - 'thematic-break': 'thematic-break', - table: 'table', - }, - inlines: { - link: 'link', - break: 'break', - image: 'image', - }, - marks: { - b: 'bold', - i: 'italic', - s: 'strikethrough', - code: 'code', - }, -}); - -export default h; diff --git a/packages/netlify-cms-widget-markdown/webpack.config.js b/packages/netlify-cms-widget-markdown/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-markdown/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-number/CHANGELOG.md b/packages/netlify-cms-widget-number/CHANGELOG.md deleted file mode 100644 index 982bc06e..00000000 --- a/packages/netlify-cms-widget-number/CHANGELOG.md +++ /dev/null @@ -1,287 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.4.7...netlify-cms-widget-number@2.5.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.4.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.4.6...netlify-cms-widget-number@2.4.7) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.4.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.4.5...netlify-cms-widget-number@2.4.6) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.4.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.4.4...netlify-cms-widget-number@2.4.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## 2.4.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.4.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.4.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.4.0...netlify-cms-widget-number@2.4.1) (2020-07-01) - - -### Bug Fixes - -* **widget-number:** use number instead of integer in schema ([#3931](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/3931)) ([3a53873](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/3a5387346925cb7a579ef199c261d7c7de4a3423)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.5...netlify-cms-widget-number@2.4.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -## [2.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.4...netlify-cms-widget-number@2.3.5) (2019-11-07) - - -### Bug Fixes - -* don't enforce min max when number value is empty ([#2792](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2792)) ([6b11367](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/6b113673130389aba1ee00fd614501668fad7596)) - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.3...netlify-cms-widget-number@2.3.4) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.3-beta.0...netlify-cms-widget-number@2.3.3) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.3.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.2...netlify-cms-widget-number@2.3.3-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.1...netlify-cms-widget-number@2.3.2) (2019-04-02) - - -### Bug Fixes - -* **widget-number:** allow zero as value ([#2261](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2261)) ([800c3ee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/800c3ee)) - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.1-beta.2...netlify-cms-widget-number@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.1-beta.1...netlify-cms-widget-number@2.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.1-beta.0...netlify-cms-widget-number@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.3.0...netlify-cms-widget-number@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.2.0...netlify-cms-widget-number@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.2.0-beta.0...netlify-cms-widget-number@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-number - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.1.2-beta.0...netlify-cms-widget-number@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/82cc794)) - - - - - -## [2.1.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.1.1...netlify-cms-widget-number@2.1.2-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/ccef446)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.1.0...netlify-cms-widget-number@2.1.1) (2019-02-12) - - -### Bug Fixes - -* **widget-number:** fix empty value handling for number input ([#2077](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2077)) ([be15015](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/be15015)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.0.5...netlify-cms-widget-number@2.1.0) (2019-02-08) - - -### Features - -* **widget-number:** add range validation ([#2049](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/issues/2049)) ([dc44cac](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/commit/dc44cac)) - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.0.4...netlify-cms-widget-number@2.0.5) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms-widget-number - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.0.3...netlify-cms-widget-number@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-number - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.0.2...netlify-cms-widget-number@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-number - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number/compare/netlify-cms-widget-number@2.0.1...netlify-cms-widget-number@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-number - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-number diff --git a/packages/netlify-cms-widget-number/README.md b/packages/netlify-cms-widget-number/README.md deleted file mode 100644 index ed616301..00000000 --- a/packages/netlify-cms-widget-number/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-number/README.md)! diff --git a/packages/netlify-cms-widget-number/package.json b/packages/netlify-cms-widget-number/package.json deleted file mode 100644 index a40febea..00000000 --- a/packages/netlify-cms-widget-number/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "netlify-cms-widget-number", - "description": "Widget for editing numberic values in Netlify CMS.", - "version": "2.5.0", - "homepage": "https://www.netlifycms.org/docs/widgets/#number", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-number", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-number.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "number" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-number/src/__tests__/number.spec.js b/packages/netlify-cms-widget-number/src/__tests__/number.spec.js deleted file mode 100644 index 1823d02b..00000000 --- a/packages/netlify-cms-widget-number/src/__tests__/number.spec.js +++ /dev/null @@ -1,214 +0,0 @@ -import React from 'react'; -import { fromJS } from 'immutable'; -import { render, fireEvent } from '@testing-library/react'; - -import { NetlifyCmsWidgetNumber } from '../'; -import { validateMinMax } from '../NumberControl'; - -const NumberControl = NetlifyCmsWidgetNumber.controlComponent; - -const fieldSettings = { - min: -20, - max: 20, - step: 1, - value_type: 'int', -}; - -class NumberController extends React.Component { - state = { - value: this.props.defaultValue, - }; - - handleOnChange = jest.fn(value => { - this.setState({ value }); - }); - - componentDidUpdate() { - this.props.onStateChange(this.state); - } - - render() { - return this.props.children({ - value: this.state.value, - handleOnChange: this.handleOnChange, - }); - } -} - -function setup({ field, defaultValue }) { - let renderArgs; - const stateChangeSpy = jest.fn(); - const setActiveSpy = jest.fn(); - const setInactiveSpy = jest.fn(); - - const helpers = render( - - {({ value, handleOnChange }) => { - renderArgs = { value, onChangeSpy: handleOnChange }; - return ( - - ); - }} - , - ); - - const input = helpers.container.querySelector('input'); - - return { - ...helpers, - ...renderArgs, - stateChangeSpy, - setActiveSpy, - setInactiveSpy, - input, - }; -} - -describe('Number widget', () => { - it('should call onChange when input changes', () => { - const field = fromJS(fieldSettings); - const testValue = Math.floor(Math.random() * (20 - -20 + 1)) + -20; - const { input, onChangeSpy } = setup({ field }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: String(testValue) } }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(testValue); - }); - - it('should call onChange with empty string when no value is set', () => { - const field = fromJS(fieldSettings); - const { input, onChangeSpy } = setup({ field, defaultValue: 20 }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: '' } }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(''); - }); - - it('should call onChange with empty string when a non numeric value is set', () => { - const field = fromJS(fieldSettings); - const { input, onChangeSpy } = setup({ field, defaultValue: 20 }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: 'invalid' } }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(''); - }); - - it('should parse float numbers as integers', () => { - const field = fromJS(fieldSettings); - const testValue = (Math.random() * (20 - -20 + 1) + -20).toFixed(2); - const { input, onChangeSpy } = setup({ field }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: String(testValue) } }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(parseInt(testValue, 10)); - }); - - it('should parse float numbers as float', () => { - const field = fromJS({ ...fieldSettings, value_type: 'float' }); - const testValue = (Math.random() * (20 - -20 + 1) + -20).toFixed(2); - const { input, onChangeSpy } = setup({ field }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: String(testValue) } }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(parseFloat(testValue)); - }); - - it('should allow 0 as a value', () => { - const field = fromJS(fieldSettings); - const testValue = 0; - const { input } = setup({ field }); - - fireEvent.focus(input); - fireEvent.change(input, { target: { value: String(testValue) } }); - - expect(input.value).toBe('0'); - }); - - describe('validateMinMax', () => { - const field = { get: jest.fn() }; - field.get.mockReturnValue('label'); - const t = jest.fn(); - t.mockImplementation((_, params) => params); - - beforeEach(() => { - jest.clearAllMocks(); - }); - - it('should return error when min max are defined and value is out of range', () => { - const error = validateMinMax(5, 0, 1, field, t); - const expectedMessage = { - fieldLabel: 'label', - minValue: 0, - maxValue: 1, - }; - expect(error).not.toBeNull(); - expect(error).toEqual({ - type: 'RANGE', - message: expectedMessage, - }); - expect(t).toHaveBeenCalledTimes(1); - expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.range', expectedMessage); - }); - - it('should return error when min is defined and value is out of range', () => { - const error = validateMinMax(5, 6, false, field, t); - const expectedMessage = { - fieldLabel: 'label', - minValue: 6, - }; - expect(error).not.toBeNull(); - expect(error).toEqual({ - type: 'RANGE', - message: expectedMessage, - }); - expect(t).toHaveBeenCalledTimes(1); - expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.min', expectedMessage); - }); - - it('should return error when max is defined and value is out of range', () => { - const error = validateMinMax(5, false, 3, field, t); - const expectedMessage = { - fieldLabel: 'label', - maxValue: 3, - }; - expect(error).not.toBeNull(); - expect(error).toEqual({ - type: 'RANGE', - message: expectedMessage, - }); - expect(t).toHaveBeenCalledTimes(1); - expect(t).toHaveBeenCalledWith('editor.editorControlPane.widget.max', expectedMessage); - }); - - it('should not return error when min max are defined and value is empty', () => { - const error = validateMinMax('', 0, 1, field, t); - - expect(error).toBeNull(); - }); - - it('should not return error when min max are defined and value is in range', () => { - const error = validateMinMax(0, -1, 1, field, t); - - expect(error).toBeNull(); - }); - }); -}); diff --git a/packages/netlify-cms-widget-number/src/index.js b/packages/netlify-cms-widget-number/src/index.js deleted file mode 100644 index 3df5e75e..00000000 --- a/packages/netlify-cms-widget-number/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import controlComponent from './NumberControl'; -import previewComponent from './NumberPreview'; -import schema from './schema'; - -function Widget(opts = {}) { - return { - name: 'number', - controlComponent, - previewComponent, - schema, - ...opts, - }; -} - -export const NetlifyCmsWidgetNumber = { Widget, controlComponent, previewComponent }; -export default NetlifyCmsWidgetNumber; diff --git a/packages/netlify-cms-widget-number/webpack.config.js b/packages/netlify-cms-widget-number/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-number/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-object/CHANGELOG.md b/packages/netlify-cms-widget-object/CHANGELOG.md deleted file mode 100644 index ed07ef2f..00000000 --- a/packages/netlify-cms-widget-object/CHANGELOG.md +++ /dev/null @@ -1,369 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.7.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-object@2.7.3...netlify-cms-widget-object@2.7.4) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.7.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-object@2.7.2...netlify-cms-widget-object@2.7.3) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-object@2.7.1...netlify-cms-widget-object@2.7.2) (2022-04-13) - - -### Bug Fixes - -* **relation-widget:** i18n options ([#6299](https://github.com/netlify/netlify-cms/issues/6299)) ([4bf6464](https://github.com/netlify/netlify-cms/commit/4bf64642e4c0be4adce81af1d407bdbd5770a727)) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-object@2.7.0...netlify-cms-widget-object@2.7.1) (2021-08-04) - - -### Bug Fixes - -* **widget-list:** add missing translations in widget list top bar ([#5471](https://github.com/netlify/netlify-cms/issues/5471)) ([#5679](https://github.com/netlify/netlify-cms/issues/5679)) ([db560cc](https://github.com/netlify/netlify-cms/commit/db560cc082fcc0a9842919e28f715e44a6e4625a)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.6.2...netlify-cms-widget-object@2.7.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.6.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.6.1...netlify-cms-widget-object@2.6.2) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.6.0...netlify-cms-widget-object@2.6.1) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.5.6...netlify-cms-widget-object@2.6.0) (2020-10-20) - - -### Features - -* **widget-object:** add "summary" [#4291](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/4291) ([#4398](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/4398)) ([963e775](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/963e775897cd1e9357e0af79812b430fa6fd2cdb)) - - - - - -## [2.5.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.5.5...netlify-cms-widget-object@2.5.6) (2020-09-20) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.5.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.5.4...netlify-cms-widget-object@2.5.5) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## 2.5.4 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.5.3 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.5.2 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.5.0...netlify-cms-widget-object@2.5.1) (2020-07-16) - - -### Bug Fixes - -* **prop-types:** check for react components via PropTypes.elementType ([#4025](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/4025)) ([d3831b1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/d3831b1ed44fcff51a63f6645a5aa68332467dab)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.4.2...netlify-cms-widget-object@2.5.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.4.1...netlify-cms-widget-object@2.4.2) (2020-06-01) - - -### Bug Fixes - -* Error UI improvements for nested lists/objects ([#3726](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/3726)) ([3978578](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/397857855b2c8514c2f7ce83756af6b6698abc3d)) - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.4.0...netlify-cms-widget-object@2.4.1) (2020-04-20) - - -### Bug Fixes - -* list widget item collapse toggle ([#3623](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/3623)) ([3a666e2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/3a666e26b507f16767d0dafb82cd8a030424eec3)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.3.1...netlify-cms-widget-object@2.4.0) (2020-04-16) - - -### Features - -* **widget-object:** add collapsed option to collapse object by default ([#3606](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/3606)) ([9f17363](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/9f17363beee718ac6102cecfa965d631e4675090)) - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.3.0...netlify-cms-widget-object@2.3.1) (2020-01-07) - - -### Bug Fixes - -* **widget-object:** allow nested widgets to overflow ([#3026](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/3026)) ([8e980bc](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/8e980bc1abb516f8af889a81f0a52a1cd9456afb)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.3...netlify-cms-widget-object@2.3.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.2...netlify-cms-widget-object@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.2-beta.0...netlify-cms-widget-object@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.1...netlify-cms-widget-object@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.1-beta.2...netlify-cms-widget-object@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.1-beta.1...netlify-cms-widget-object@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.1-beta.0...netlify-cms-widget-object@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.2.0...netlify-cms-widget-object@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.1.0...netlify-cms-widget-object@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.1.0-beta.0...netlify-cms-widget-object@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-object - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.7-beta.0...netlify-cms-widget-object@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/82cc794)) - - - - - -## [2.0.7-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.6...netlify-cms-widget-object@2.0.7-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/ccef446)) - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.5...netlify-cms-widget-object@2.0.6) (2019-02-08) - - -### Bug Fixes - -* **netlify-cms-core:** fix fields metadata for objects and lists ([#2011](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/2011)) ([2d1d1c1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/2d1d1c1)) -* **netlify-cms-core:** validate nested fields ([#1873](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/1873)) ([627e600](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/627e600)) - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.4...netlify-cms-widget-object@2.0.5) (2018-08-24) - - -### Bug Fixes - -* **list-widget:** fix single field usage in list widget ([#1395](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/issues/1395)) ([06d3650](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/commit/06d3650)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.3...netlify-cms-widget-object@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-object - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.2...netlify-cms-widget-object@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-object - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object/compare/netlify-cms-widget-object@2.0.1...netlify-cms-widget-object@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-object - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-object diff --git a/packages/netlify-cms-widget-object/README.md b/packages/netlify-cms-widget-object/README.md deleted file mode 100644 index fd4d5d2e..00000000 --- a/packages/netlify-cms-widget-object/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-object/README.md)! diff --git a/packages/netlify-cms-widget-object/package.json b/packages/netlify-cms-widget-object/package.json deleted file mode 100644 index 48b54c18..00000000 --- a/packages/netlify-cms-widget-object/package.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "name": "netlify-cms-widget-object", - "description": "Widget for displaying an object of fields for Netlify CMS.", - "version": "2.7.4", - "homepage": "https://www.netlifycms.org/docs/widgets/#object", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-object", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-object.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "fields", - "object", - "nested" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - } -} diff --git a/packages/netlify-cms-widget-object/webpack.config.js b/packages/netlify-cms-widget-object/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-object/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-relation/CHANGELOG.md b/packages/netlify-cms-widget-relation/CHANGELOG.md deleted file mode 100644 index 45297a0b..00000000 --- a/packages/netlify-cms-widget-relation/CHANGELOG.md +++ /dev/null @@ -1,514 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.11.3](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-relation@2.11.2...netlify-cms-widget-relation@2.11.3) (2022-09-22) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.11.2](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-relation@2.11.1...netlify-cms-widget-relation@2.11.2) (2022-09-21) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.11.1](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-relation@2.11.0...netlify-cms-widget-relation@2.11.1) (2022-04-13) - - -### Bug Fixes - -* **relation-widget:** i18n options ([#6299](https://github.com/netlify/netlify-cms/issues/6299)) ([4bf6464](https://github.com/netlify/netlify-cms/commit/4bf64642e4c0be4adce81af1d407bdbd5770a727)) - - - - - -# [2.11.0](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-relation@2.10.4...netlify-cms-widget-relation@2.11.0) (2021-10-21) - - -### Features - -* **relation-widget:** enable reordering for relation controls ([#5873](https://github.com/netlify/netlify-cms/issues/5873)) ([a77a355](https://github.com/netlify/netlify-cms/commit/a77a355bac376758a6c9f9948e258bd32ccd4302)) - - - - - -## [2.10.4](https://github.com/netlify/netlify-cms/compare/netlify-cms-widget-relation@2.10.3...netlify-cms-widget-relation@2.10.4) (2021-09-13) - - -### Bug Fixes - -* **widget-relation:** don't invoke onChange if component is not mounted ([#5804](https://github.com/netlify/netlify-cms/issues/5804)) ([bd35474](https://github.com/netlify/netlify-cms/commit/bd35474b928642af3fa3be434928709fd6e9e844)) - - - - - -## [2.10.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.10.2...netlify-cms-widget-relation@2.10.3) (2021-05-23) - - -### Bug Fixes - -* **deps:** update dependency react-select to v4 ([#5417](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/5417)) ([03362ef](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/03362ef5ab87c6fe5c964da5c5a18099b73a3fc6)) - - - - - -## [2.10.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.10.1...netlify-cms-widget-relation@2.10.2) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.10.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.10.0...netlify-cms-widget-relation@2.10.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update react-select to v3 ([#5394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/5394)) ([03be13c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/03be13c1e87b318fd10ae6f6ab54cd2634fb9662)) - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.9.0...netlify-cms-widget-relation@2.10.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.10...netlify-cms-widget-relation@2.9.0) (2021-04-13) - - -### Features - -* add min and max fields to relation widget (resolves [#5026](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/5026)) ([#5238](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/5238)) ([fe117e4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/fe117e472e18079e4f65ca2dfa5c258040cf93f9)) - - - - - -## [2.8.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.9...netlify-cms-widget-relation@2.8.10) (2021-04-07) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.8.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.8...netlify-cms-widget-relation@2.8.9) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.8.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.7...netlify-cms-widget-relation@2.8.8) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.8.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.6...netlify-cms-widget-relation@2.8.7) (2020-09-20) - - -### Bug Fixes - -* **widget-relation:** set initial metadata value ([#4326](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/4326)) ([5a4b365](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/5a4b36527e21e87f401b15501418fd739c672d85)) - - - - - -## [2.8.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.5...netlify-cms-widget-relation@2.8.6) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## 2.8.5 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.8.4 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.8.3 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.8.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.1...netlify-cms-widget-relation@2.8.2) (2020-07-16) - - -### Bug Fixes - -* **widget-relation:** append initial value search to options ([#4026](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/4026)) ([12c388e](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/12c388eff3795bf1f4475b1d7c3b61f8569c3b31)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.8.0...netlify-cms-widget-relation@2.8.1) (2020-07-14) - - -### Bug Fixes - -* relation widget performance ([#3975](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3975)) ([c7e0fe8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/c7e0fe8492d09a3d151c608f50da844f421362ed)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.7.0...netlify-cms-widget-relation@2.8.0) (2020-06-18) - - -### Bug Fixes - -* **widget-relation:** keep referenced field type when not using template ([#3850](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3850)) ([1419ba1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/1419ba1d09ba1671f964f797479e1da5073a608d)) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.6.0...netlify-cms-widget-relation@2.7.0) (2020-05-19) - - -### Bug Fixes - -* **widget-relation:** fix displayFields default ([#3783](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3783)) ([24d96a7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/24d96a760a26f043468cd3e7af28ad3adc6c283a)) - - -### Features - -* **widget-relation:** target file collections ([#3754](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3754)) ([2f435f8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/2f435f875bc139af345080eb8cca6146d27c10f6)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.5.2...netlify-cms-widget-relation@2.6.0) (2020-05-04) - - -### Features - -* **widget-relation:** string templates support ([#3659](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3659)) ([213ae86](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/213ae86b54d02f5fc79fe11113507587ed062ff2)) - - - - - -## [2.5.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.5.1...netlify-cms-widget-relation@2.5.2) (2020-02-14) - - -### Bug Fixes - -* dispatch QUERY_FAILURE on query failure ([#3243](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3243)) ([2447f9c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/2447f9c311db3c5db35ce6501c0380d304709d50)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.5.0...netlify-cms-widget-relation@2.5.1) (2020-02-13) - - -### Bug Fixes - -* change getAsset to not return a promise ([#3232](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/3232)) ([ab685e8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/ab685e85943d1ac48142f157683bc2126fd6af16)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.4.2...netlify-cms-widget-relation@2.5.0) (2019-11-18) - - -### Bug Fixes - -* **bundle-size:** don't import react-select twice ([#2875](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2875)) ([665afed](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/665afed3c20f1d74ba4b2ef65d0eb5130e558433)) - - -### Features - -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.4.1...netlify-cms-widget-relation@2.4.2) (2019-09-26) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.4.0...netlify-cms-widget-relation@2.4.1) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.3...netlify-cms-widget-relation@2.4.0) (2019-06-26) - - -### Features - -* **widget-relation:** support nested field references in relation widget ([#2391](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2391)) ([d6964b5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/d6964b5)) - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.3-beta.0...netlify-cms-widget-relation@2.3.3) (2019-06-14) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.3.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.2...netlify-cms-widget-relation@2.3.3-beta.0) (2019-05-15) - - -### Bug Fixes - -* **widget-relation:** clear button ([#2285](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2285)) ([9318aa0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/9318aa0)) - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.2-beta.0...netlify-cms-widget-relation@2.3.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.3.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.1...netlify-cms-widget-relation@2.3.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.1-beta.2...netlify-cms-widget-relation@2.3.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.3.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.1-beta.1...netlify-cms-widget-relation@2.3.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -## [2.3.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.1-beta.0...netlify-cms-widget-relation@2.3.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/6ffd13b)) - - - - - -## [2.3.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.3.0...netlify-cms-widget-relation@2.3.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/7987091)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.2.0...netlify-cms-widget-relation@2.3.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/d142b32)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.2.0-beta.0...netlify-cms-widget-relation@2.2.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -# [2.2.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.1.3-beta.0...netlify-cms-widget-relation@2.2.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/82cc794)) - - - - - -## [2.1.3-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.1.2...netlify-cms-widget-relation@2.1.3-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/ccef446)) - - - - - -## [2.1.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.1.1...netlify-cms-widget-relation@2.1.2) (2019-03-11) - - -### Bug Fixes - -* **relation-widget:** accept string in searchFields config ([#2137](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2137)) ([9fed79b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/9fed79b)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.1.0...netlify-cms-widget-relation@2.1.1) (2019-03-08) - -**Note:** Version bump only for package netlify-cms-widget-relation - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.6...netlify-cms-widget-relation@2.1.0) (2019-02-26) - - -### Features - -* **netlify-cms-widget-relation:** use react-select and add support for multiple entries ([#1936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/1936)) ([518f6fb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/518f6fb)) - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.5...netlify-cms-widget-relation@2.0.6) (2019-02-08) - - -### Bug Fixes - -* **netlify-cms-core:** fix fields metadata for objects and lists ([#2011](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/2011)) ([2d1d1c1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/2d1d1c1)) - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.4...netlify-cms-widget-relation@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-relation - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.3...netlify-cms-widget-relation@2.0.4) (2018-08-07) - - -### Bug Fixes - -* **relation:** fix relation widget selection bug ([#1572](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/issues/1572)) ([77fbc04](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/commit/77fbc04)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.2...netlify-cms-widget-relation@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-relation - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation/compare/netlify-cms-widget-relation@2.0.1...netlify-cms-widget-relation@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-relation - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-relation diff --git a/packages/netlify-cms-widget-relation/README.md b/packages/netlify-cms-widget-relation/README.md deleted file mode 100644 index 95a2de90..00000000 --- a/packages/netlify-cms-widget-relation/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-relation/README.md)! diff --git a/packages/netlify-cms-widget-relation/package.json b/packages/netlify-cms-widget-relation/package.json deleted file mode 100644 index e0861585..00000000 --- a/packages/netlify-cms-widget-relation/package.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "name": "netlify-cms-widget-relation", - "description": "Widget for linking related entries in Netlify CMS.", - "version": "2.11.3", - "homepage": "https://www.netlifycms.org/docs/widgets/#relation", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-relation", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-relation.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "relation", - "link" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-select": "^4.0.0", - "react-sortable-hoc": "^2.0.0", - "react-window": "^1.8.5" - }, - "peerDependencies": { - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "immutable": "^3.7.6", - "lodash": "^4.17.11", - "netlify-cms-lib-widgets": "^1.6.1", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "uuid": "^3.3.2" - } -} diff --git a/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js b/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js deleted file mode 100644 index 40cc5cf8..00000000 --- a/packages/netlify-cms-widget-relation/src/__tests__/relation.spec.js +++ /dev/null @@ -1,480 +0,0 @@ -import React from 'react'; -import { fromJS } from 'immutable'; -import { render, fireEvent, waitFor } from '@testing-library/react'; - -import { NetlifyCmsWidgetRelation } from '../'; - -jest.mock('react-window', () => { - function FixedSizeList(props) { - return props.itemData.options; - } - - return { - FixedSizeList, - }; -}); - -const RelationControl = NetlifyCmsWidgetRelation.controlComponent; - -const fieldConfig = { - name: 'post', - collection: 'posts', - display_fields: ['title', 'slug'], - search_fields: ['title', 'body'], - value_field: 'title', -}; - -const customizedOptionsLengthConfig = { - name: 'post', - collection: 'posts', - display_fields: ['title', 'slug'], - search_fields: ['title', 'body'], - value_field: 'title', - options_length: 10, -}; - -const deeplyNestedFieldConfig = { - name: 'post', - collection: 'posts', - display_fields: ['title', 'slug', 'deeply.nested.post.field'], - search_fields: ['deeply.nested.post.field'], - value_field: 'title', -}; - -const nestedFieldConfig = { - name: 'post', - collection: 'posts', - display_fields: ['title', 'slug', 'nested.field_1'], - search_fields: ['nested.field_1', 'nested.field_2'], - value_field: 'title', -}; - -function generateHits(length) { - const hits = Array.from({ length }, (val, idx) => { - const title = `Post # ${idx + 1}`; - const slug = `post-number-${idx + 1}`; - const path = `posts/${slug}.md`; - return { collection: 'posts', data: { title, slug }, slug, path }; - }); - - return [ - ...hits, - { - collection: 'posts', - data: { - title: 'Deeply nested post', - slug: 'post-deeply-nested', - deeply: { - nested: { - post: { - field: 'Deeply nested field', - }, - }, - }, - }, - }, - { - collection: 'posts', - data: { - title: 'Nested post', - slug: 'post-nested', - nested: { - field_1: 'Nested field 1', - field_2: 'Nested field 2', - }, - }, - }, - { - collection: 'posts', - data: { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' }, - }, - { - collection: 'posts', - data: { title: 'JSON post', slug: 'post-json', body: 'Body json' }, - }, - ]; -} - -const simpleFileCollectionHits = [{ data: { categories: ['category 1', 'category 2'] } }]; - -const nestedFileCollectionHits = [ - { - data: { - nested: { - categories: [ - { - name: 'category 1', - id: 'cat1', - }, - { - name: 'category 2', - id: 'cat2', - }, - ], - }, - }, - }, -]; - -const numberFieldsHits = [ - { - collection: 'posts', - data: { - title: 'post # 1', - slug: 'post-1', - index: 1, - }, - }, - { - collection: 'posts', - data: { - title: 'post # 2', - slug: 'post-2', - index: 2, - }, - }, -]; -class RelationController extends React.Component { - state = { - value: this.props.value, - queryHits: [], - }; - - mounted = false; - - componentDidMount() { - this.mounted = true; - } - - componentWillUnmount() { - this.mounted = false; - } - - handleOnChange = jest.fn(value => { - this.setState({ ...this.state, value }); - }); - - setQueryHits = jest.fn(queryHits => { - if (this.mounted) { - this.setState({ ...this.state, queryHits }); - } - }); - - query = jest.fn((...args) => { - const queryHits = generateHits(25); - - const [, collection, , term, file, optionsLength] = args; - let hits = queryHits; - if (collection === 'numbers_collection') { - hits = numberFieldsHits; - } else if (file === 'nested_file') { - hits = nestedFileCollectionHits; - } else if (file === 'simple_file') { - hits = simpleFileCollectionHits; - } else if (term === 'JSON post') { - hits = [queryHits[queryHits.length - 1]]; - } else if (term === 'YAML' || term === 'YAML post') { - hits = [queryHits[queryHits.length - 2]]; - } else if (term === 'Nested') { - hits = [queryHits[queryHits.length - 3]]; - } else if (term === 'Deeply nested') { - hits = [queryHits[queryHits.length - 4]]; - } - - hits = hits.slice(0, optionsLength); - - this.setQueryHits(hits); - - return Promise.resolve({ payload: { hits } }); - }); - - render() { - return this.props.children({ - value: this.state.value, - handleOnChange: this.handleOnChange, - query: this.query, - queryHits: this.state.queryHits, - setQueryHits: this.setQueryHits, - }); - } -} - -function setup({ field, value }) { - let renderArgs; - const setActiveSpy = jest.fn(); - const setInactiveSpy = jest.fn(); - - const helpers = render( - - {({ handleOnChange, value, query, queryHits, setQueryHits }) => { - renderArgs = { value, onChangeSpy: handleOnChange, setQueryHitsSpy: setQueryHits }; - return ( - - ); - }} - , - ); - - const input = helpers.container.querySelector('input'); - - return { - ...helpers, - ...renderArgs, - setActiveSpy, - setInactiveSpy, - input, - }; -} - -describe('Relation widget', () => { - it('should list the first 20 option hits on initial load', async () => { - const field = fromJS(fieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toHaveLength(20); - }); - }); - - it('should list the first 10 option hits on initial load', async () => { - const field = fromJS(customizedOptionsLengthConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/^Post # (\d{1,2}) post-number-\1$/)).toHaveLength(10); - }); - }); - - it('should update option list based on search term', async () => { - const field = fromJS(fieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.change(input, { target: { value: 'YAML' } }); - - await waitFor(() => { - expect(getAllByText('YAML post post-yaml')).toHaveLength(1); - }); - }); - - it('should call onChange with correct selectedItem value and metadata', async () => { - const field = fromJS(fieldConfig); - const { getByText, input, onChangeSpy } = setup({ field }); - const value = 'Post # 1'; - const label = 'Post # 1 post-number-1'; - const metadata = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - fireEvent.click(getByText(label)); - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - - it('should update metadata for initial preview', async () => { - const field = fromJS(fieldConfig); - const value = 'Post # 1'; - const { getByText, onChangeSpy, setQueryHitsSpy } = setup({ field, value }); - const label = 'Post # 1 post-number-1'; - const metadata = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - - setQueryHitsSpy(generateHits(1)); - - await waitFor(() => { - expect(getByText(label)).toBeInTheDocument(); - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - - it('should update option list based on nested search term', async () => { - const field = fromJS(nestedFieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.change(input, { target: { value: 'Nested' } }); - - await waitFor(() => { - expect(getAllByText('Nested post post-nested Nested field 1')).toHaveLength(1); - }); - }); - - it('should update option list based on deeply nested search term', async () => { - const field = fromJS(deeplyNestedFieldConfig); - const { getAllByText, input } = setup({ field }); - fireEvent.change(input, { target: { value: 'Deeply nested' } }); - - await waitFor(() => { - expect( - getAllByText('Deeply nested post post-deeply-nested Deeply nested field'), - ).toHaveLength(1); - }); - }); - - it('should handle string templates', async () => { - const stringTemplateConfig = { - name: 'post', - collection: 'posts', - display_fields: ['{{slug}}', '{{filename}}', '{{extension}}'], - search_fields: ['slug'], - value_field: '{{slug}}', - }; - - const field = fromJS(stringTemplateConfig); - const { getByText, input, onChangeSpy } = setup({ field }); - const value = 'post-number-1'; - const label = 'post-number-1 post-number-1 md'; - const metadata = { - post: { posts: { 'post-number-1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - await waitFor(() => { - fireEvent.click(getByText(label)); - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - - it('should default display_fields to value_field', async () => { - const field = fromJS(fieldConfig).delete('display_fields'); - const { getAllByText, input } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/^Post # (\d{1,2})$/)).toHaveLength(20); - }); - }); - it('should keep number type of referenced field', async () => { - const fieldConfig = { - name: 'numbers', - collection: 'numbers_collection', - value_field: 'index', - search_fields: ['index'], - display_fields: ['title'], - }; - - const field = fromJS(fieldConfig); - const { getByText, getAllByText, input, onChangeSpy } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/^post # \d$/)).toHaveLength(2); - }); - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('post # 1')); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('post # 2')); - - expect(onChangeSpy).toHaveBeenCalledTimes(2); - expect(onChangeSpy).toHaveBeenCalledWith(1, { - numbers: { numbers_collection: { 1: { index: 1, slug: 'post-1', title: 'post # 1' } } }, - }); - expect(onChangeSpy).toHaveBeenCalledWith(2, { - numbers: { numbers_collection: { 2: { index: 2, slug: 'post-2', title: 'post # 2' } } }, - }); - }); - - describe('with multiple', () => { - it('should call onChange with correct selectedItem value and metadata', async () => { - const field = fromJS({ ...fieldConfig, multiple: true }); - const { getByText, input, onChangeSpy } = setup({ field }); - const metadata1 = { - post: { posts: { 'Post # 1': { title: 'Post # 1', slug: 'post-number-1' } } }, - }; - const metadata2 = { - post: { posts: { 'Post # 2': { title: 'Post # 2', slug: 'post-number-2' } } }, - }; - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - await waitFor(() => { - fireEvent.click(getByText('Post # 1 post-number-1')); - }); - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - await waitFor(() => { - fireEvent.click(getByText('Post # 2 post-number-2')); - }); - - expect(onChangeSpy).toHaveBeenCalledTimes(2); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1']), metadata1); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS(['Post # 1', 'Post # 2']), metadata2); - }); - - it('should update metadata for initial preview', async () => { - const field = fromJS({ ...fieldConfig, multiple: true }); - const value = fromJS(['YAML post', 'JSON post']); - const { getByText, onChangeSpy } = setup({ field, value }); - const metadata = { - post: { - posts: { - 'YAML post': { title: 'YAML post', slug: 'post-yaml', body: 'Body yaml' }, - 'JSON post': { title: 'JSON post', slug: 'post-json', body: 'Body json' }, - }, - }, - }; - - await waitFor(() => { - expect(getByText('YAML post post-yaml')).toBeInTheDocument(); - expect(getByText('JSON post post-json')).toBeInTheDocument(); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(value, metadata); - }); - }); - }); - - describe('with file collection', () => { - const fileFieldConfig = { - name: 'categories', - collection: 'file', - file: 'simple_file', - value_field: 'categories.*', - display_fields: ['categories.*'], - }; - - it('should handle simple list', async () => { - const field = fromJS(fileFieldConfig); - const { getAllByText, input, getByText } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/category/)).toHaveLength(2); - expect(getByText('category 1')).toBeInTheDocument(); - expect(getByText('category 2')).toBeInTheDocument(); - }); - }); - - it('should handle nested list', async () => { - const field = fromJS({ - ...fileFieldConfig, - file: 'nested_file', - value_field: 'nested.categories.*.id', - display_fields: ['nested.categories.*.name'], - }); - const { getAllByText, input, getByText } = setup({ field }); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - - await waitFor(() => { - expect(getAllByText(/category/)).toHaveLength(2); - expect(getByText('category 1')).toBeInTheDocument(); - expect(getByText('category 2')).toBeInTheDocument(); - }); - }); - }); -}); diff --git a/packages/netlify-cms-widget-relation/src/index.js b/packages/netlify-cms-widget-relation/src/index.js deleted file mode 100644 index 12f7f946..00000000 --- a/packages/netlify-cms-widget-relation/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import controlComponent from './RelationControl'; -import previewComponent from './RelationPreview'; -import schema from './schema'; - -function Widget(opts = {}) { - return { - name: 'relation', - controlComponent, - previewComponent, - schema, - ...opts, - }; -} - -export const NetlifyCmsWidgetRelation = { Widget, controlComponent, previewComponent }; -export default NetlifyCmsWidgetRelation; diff --git a/packages/netlify-cms-widget-relation/webpack.config.js b/packages/netlify-cms-widget-relation/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-relation/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-select/CHANGELOG.md b/packages/netlify-cms-widget-select/CHANGELOG.md deleted file mode 100644 index 7be01b43..00000000 --- a/packages/netlify-cms-widget-select/CHANGELOG.md +++ /dev/null @@ -1,344 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.8.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.8.1...netlify-cms-widget-select@2.8.2) (2021-05-23) - - -### Bug Fixes - -* **deps:** update dependency react-select to v4 ([#5417](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/5417)) ([03362ef](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/03362ef5ab87c6fe5c964da5c5a18099b73a3fc6)) - - - - - -## [2.8.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.8.0...netlify-cms-widget-select@2.8.1) (2021-05-19) - - -### Bug Fixes - -* **deps:** update react-select to v3 ([#5394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/5394)) ([03be13c](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/03be13c1e87b318fd10ae6f6ab54cd2634fb9662)) - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.7.4...netlify-cms-widget-select@2.8.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.7.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.7.3...netlify-cms-widget-select@2.7.4) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.7.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.7.2...netlify-cms-widget-select@2.7.3) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.7.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.7.1...netlify-cms-widget-select@2.7.2) (2020-11-26) - - -### Bug Fixes - -* **widget-select:** allow number value type ([#4599](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/4599)) ([9741a79](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/9741a79e4922553b69e1536d4e53f5fde45d30e1)) - - - - - -## [2.7.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.7.0...netlify-cms-widget-select@2.7.1) (2020-11-08) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.6.4...netlify-cms-widget-select@2.7.0) (2020-10-20) - - -### Features - -* **widget-list:** add min max configuration ([#4394](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/4394)) ([5fdfe40](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/5fdfe40dd29e9e22c9ae7d6219bc057f7ea7280b)) - - - - - -## [2.6.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.6.3...netlify-cms-widget-select@2.6.4) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## 2.6.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.6.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.6.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.5.1...netlify-cms-widget-select@2.6.0) (2020-06-18) - - -### Features - -* add widgets schema validation ([#3841](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/3841)) ([2b46608](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/2b46608f86d22c8ad34f75e396be7c34462d9e99)) - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.5.0...netlify-cms-widget-select@2.5.1) (2020-02-06) - - -### Bug Fixes - -* **widget-select:** fix exactCount error message ([#3177](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/3177)) ([46f7763](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/46f7763ccd1445b758006770252cc911b12de15d)) - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.3...netlify-cms-widget-select@2.5.0) (2020-02-01) - - -### Bug Fixes - -* **widget-select:** allow optional field to use min/max ([#3175](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/3175)) ([fc524e6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/fc524e6c0fc0174294b42cd90d9eb23e96d15d53)) - - -### Features - -* **select-widget:** add min/max validation ([#3171](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/3171)) ([fd9e2c8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/fd9e2c89f23d73aa08dbfa4412c4c0bae318125b)) -* commit media with post ([#2851](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2851)) ([6515dee](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/6515dee8715d8571ea19484a7dfab7cfd0cc40be)) - - - - - -## [2.4.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.2...netlify-cms-widget-select@2.4.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.2-beta.0...netlify-cms-widget-select@2.4.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.4.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.1...netlify-cms-widget-select@2.4.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.1-beta.2...netlify-cms-widget-select@2.4.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.4.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.1-beta.1...netlify-cms-widget-select@2.4.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -## [2.4.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.1-beta.0...netlify-cms-widget-select@2.4.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/6ffd13b)) - - - - - -## [2.4.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.4.0...netlify-cms-widget-select@2.4.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/7987091)) - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.3.0...netlify-cms-widget-select@2.4.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/d142b32)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.3.0-beta.0...netlify-cms-widget-select@2.3.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -# [2.3.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.2.1-beta.0...netlify-cms-widget-select@2.3.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/82cc794)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.2.0...netlify-cms-widget-select@2.2.1-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/ccef446)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.1.1...netlify-cms-widget-select@2.2.0) (2019-02-26) - - -### Features - -* **netlify-cms-widget-relation:** use react-select and add support for multiple entries ([#1936](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/1936)) ([518f6fb](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/518f6fb)) - - - - - -## [2.1.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.1.0...netlify-cms-widget-select@2.1.1) (2019-02-08) - -**Note:** Version bump only for package netlify-cms-widget-select - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.0.5...netlify-cms-widget-select@2.1.0) (2018-12-04) - - -### Features - -* **netlify-cms-widget-select:** add support for multiple selection ([#1901](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/1901)) ([88bf287](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/88bf287)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.0.4...netlify-cms-widget-select@2.0.5) (2018-11-29) - - -### Bug Fixes - -* **a11y:** correct label "for" references to fields ([#1904](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/issues/1904)) ([955f94f](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/commit/955f94f)) - - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.0.3...netlify-cms-widget-select@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-select - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.0.2...netlify-cms-widget-select@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-select - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select/compare/netlify-cms-widget-select@2.0.1...netlify-cms-widget-select@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-select - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-select diff --git a/packages/netlify-cms-widget-select/README.md b/packages/netlify-cms-widget-select/README.md deleted file mode 100644 index 77dfc958..00000000 --- a/packages/netlify-cms-widget-select/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-select/README.md)! diff --git a/packages/netlify-cms-widget-select/package.json b/packages/netlify-cms-widget-select/package.json deleted file mode 100644 index e600d2d3..00000000 --- a/packages/netlify-cms-widget-select/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "netlify-cms-widget-select", - "description": "Selectable values widget for Netlify CMS.", - "version": "2.8.2", - "homepage": "https://www.netlifycms.org/docs/widgets/#select", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-select", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-select.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "select", - "values", - "list" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "immutable": "^3.7.6", - "netlify-cms-lib-widgets": "^1.6.1", - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0", - "react-immutable-proptypes": "^2.1.0" - }, - "dependencies": { - "react-select": "^4.0.0" - } -} diff --git a/packages/netlify-cms-widget-select/src/__tests__/select.spec.js b/packages/netlify-cms-widget-select/src/__tests__/select.spec.js deleted file mode 100644 index da990152..00000000 --- a/packages/netlify-cms-widget-select/src/__tests__/select.spec.js +++ /dev/null @@ -1,345 +0,0 @@ -import React from 'react'; -import { fromJS, List } from 'immutable'; -import { render, fireEvent } from '@testing-library/react'; - -import { NetlifyCmsWidgetSelect } from '../'; - -const SelectControl = NetlifyCmsWidgetSelect.controlComponent; - -const options = [ - { value: 'foo', label: 'Foo' }, - { value: 'bar', label: 'Bar' }, - { value: 'baz', label: 'Baz' }, -]; -const stringOptions = ['foo', 'bar', 'baz']; - -class SelectController extends React.Component { - state = { - value: this.props.defaultValue, - }; - - handleOnChange = jest.fn(value => { - this.setState({ value }); - }); - - componentDidUpdate() { - this.props.onStateChange(this.state); - } - - render() { - return this.props.children({ - value: this.state.value, - handleOnChange: this.handleOnChange, - }); - } -} - -function setup({ field, defaultValue }) { - let renderArgs, ref; - const stateChangeSpy = jest.fn(); - const setActiveSpy = jest.fn(); - const setInactiveSpy = jest.fn(); - - const helpers = render( - - {({ value, handleOnChange }) => { - renderArgs = { value, onChangeSpy: handleOnChange }; - return ( - (ref = widgetRef)} - t={msg => msg} - /> - ); - }} - , - ); - - const input = helpers.container.querySelector('input'); - - return { - ...helpers, - ...renderArgs, - stateChangeSpy, - setActiveSpy, - setInactiveSpy, - ref, - input, - }; -} - -function clickClearButton(container) { - const allSvgs = container.querySelectorAll('svg'); - const clear = allSvgs[allSvgs.length - 2]; - - fireEvent.mouseDown(clear, { - button: 0, - }); -} - -describe('Select widget', () => { - it('should call onChange with correct selectedItem', () => { - const field = fromJS({ options }); - const { getByText, input, onChangeSpy } = setup({ field }); - - fireEvent.focus(input); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('Foo')); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(options[0].value); - }); - - it('should call onChange with null when no item is selected', () => { - const field = fromJS({ options, required: false }); - const { input, onChangeSpy } = setup({ field, defaultValue: options[0].value }); - - fireEvent.focus(input); - fireEvent.keyDown(input, { key: 'Delete' }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(null); - }); - - it('should call onChange with null when selection is cleared', () => { - const field = fromJS({ options, required: false }); - const { onChangeSpy, container } = setup({ field, defaultValue: options[0].value }); - - clickClearButton(container); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(null); - }); - - it('should respect default value', () => { - const field = fromJS({ options }); - const { getByText } = setup({ field, defaultValue: options[2].value }); - - expect(getByText('Baz')).toBeInTheDocument(); - }); - - it('should respect default value when options are string only', () => { - const field = fromJS({ options: stringOptions }); - const { getByText } = setup({ - field, - defaultValue: stringOptions[2], - }); - - expect(getByText('baz')).toBeInTheDocument(); - }); - - describe('with multiple', () => { - it('should call onChange with correct selectedItem', () => { - const field = fromJS({ options, multiple: true }); - const { getByText, input, onChangeSpy } = setup({ field }); - - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('Foo')); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('Baz')); - - expect(onChangeSpy).toHaveBeenCalledTimes(2); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS([options[0].value])); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS([options[0].value, options[2].value])); - }); - - it('should call onChange with correct selectedItem when item is removed', () => { - const field = fromJS({ options, multiple: true }); - const { container, onChangeSpy } = setup({ - field, - defaultValue: fromJS([options[1].value, options[2].value]), - }); - - fireEvent.click(container.querySelector('svg'), { button: 0 }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS([options[2].value])); - }); - - it('should call onChange with empty list on mount when required is true', () => { - const field = fromJS({ options, multiple: true, required: true }); - const { onChangeSpy } = setup({ - field, - }); - expect(onChangeSpy).toHaveBeenCalledWith(List()); - }); - - it('should not call onChange with empty list on mount when required is false', () => { - const field = fromJS({ options, multiple: true }); - const { onChangeSpy } = setup({ - field, - }); - expect(onChangeSpy).not.toHaveBeenCalled(); - }); - - it('should call onChange with empty list when no item is selected and required is true', () => { - const field = fromJS({ options, multiple: true }); - const { input, onChangeSpy } = setup({ - field, - defaultValue: fromJS([options[1].value]), - }); - - fireEvent.focus(input); - fireEvent.keyDown(input, { key: 'Delete' }); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(null); - }); - - it('should call onChange with value in list on mount when value is not a list and required is true', () => { - const field = fromJS({ options, multiple: true, required: true }); - const { onChangeSpy } = setup({ - field, - defaultValue: options[1].value, - }); - expect(onChangeSpy).toHaveBeenCalledWith(fromJS([options[1].value])); - }); - - it('should call onChange with empty list when selection is cleared and required is true', () => { - const field = fromJS({ options, multiple: true, required: true }); - const { container, onChangeSpy } = setup({ - field, - defaultValue: fromJS([options[1].value]), - }); - - clickClearButton(container); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(List()); - }); - - it('should call onChange with null when selection is cleared and required is false', () => { - const field = fromJS({ options, multiple: true, required: false }); - const { container, onChangeSpy } = setup({ - field, - defaultValue: fromJS([options[1].value]), - }); - - clickClearButton(container); - - expect(onChangeSpy).toHaveBeenCalledTimes(1); - expect(onChangeSpy).toHaveBeenCalledWith(null); - }); - - it('should respect default value', () => { - const field = fromJS({ options, multiple: true }); - const { getByText } = setup({ - field, - defaultValue: fromJS([options[1].value, options[2].value]), - }); - - expect(getByText('Bar')).toBeInTheDocument(); - expect(getByText('Baz')).toBeInTheDocument(); - }); - - it('should respect default value when options are string only', () => { - const field = fromJS({ options: stringOptions, multiple: true }); - const { getByText } = setup({ - field, - defaultValue: fromJS([stringOptions[1], stringOptions[2]]), - }); - - expect(getByText('bar')).toBeInTheDocument(); - expect(getByText('baz')).toBeInTheDocument(); - }); - }); - describe('validation', () => { - function validate(setupOpts) { - const { ref } = setup(setupOpts); - const { error } = ref.isValid(); - return error?.message; - } - it('should fail with less items than min allows', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2 }), - defaultValue: fromJS([stringOptions[0]]), - }; - expect(validate(opts)).toMatchInlineSnapshot(`"editor.editorControlPane.widget.rangeMin"`); - }); - it('should fail with more items than max allows', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, max: 1 }), - defaultValue: fromJS([stringOptions[0], stringOptions[1]]), - }; - expect(validate(opts)).toMatchInlineSnapshot(`"editor.editorControlPane.widget.rangeMax"`); - }); - it('should enforce min when both min and max are set', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2, max: 3 }), - defaultValue: fromJS([stringOptions[0]]), - }; - expect(validate(opts)).toMatchInlineSnapshot(`"editor.editorControlPane.widget.rangeCount"`); - }); - it('should enforce max when both min and max are set', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 1, max: 2 }), - defaultValue: fromJS([stringOptions[0], stringOptions[1], stringOptions[2]]), - }; - expect(validate(opts)).toMatchInlineSnapshot(`"editor.editorControlPane.widget.rangeCount"`); - }); - it('should enforce min and max when they are the same value', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2, max: 2 }), - defaultValue: fromJS([stringOptions[0], stringOptions[1], stringOptions[2]]), - }; - expect(validate(opts)).toMatchInlineSnapshot( - `"editor.editorControlPane.widget.rangeCountExact"`, - ); - }); - it('should pass when min is met', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 1 }), - defaultValue: fromJS([stringOptions[0]]), - }; - expect(validate(opts)).toBeUndefined(); - }); - it('should pass when max is met', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, max: 1 }), - defaultValue: fromJS([stringOptions[0]]), - }; - expect(validate(opts)).toBeUndefined(); - }); - it('should pass when both min and max are met', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2, max: 3 }), - defaultValue: fromJS([stringOptions[0], stringOptions[1]]), - }; - expect(validate(opts)).toBeUndefined(); - }); - it('should pass when both min and max are met, and are the same value', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2, max: 2 }), - defaultValue: fromJS([stringOptions[0], stringOptions[1]]), - }; - expect(validate(opts)).toBeUndefined(); - }); - it('should not fail on min/max if multiple is not true', () => { - const opts = { - field: fromJS({ options: stringOptions, min: 2, max: 2 }), - defaultValue: fromJS([stringOptions[0]]), - }; - expect(validate(opts)).toBeUndefined(); - }); - it('should not fail for empty field (should work for optional field)', () => { - const opts = { - field: fromJS({ options: stringOptions, multiple: true, min: 2 }), - }; - const { ref, input, getByText, container } = setup(opts); - expect(ref.isValid().error?.message).toBeUndefined(); - fireEvent.keyDown(input, { key: 'ArrowDown' }); - fireEvent.click(getByText('foo')); - expect(ref.isValid().error?.message).toMatchInlineSnapshot( - `"editor.editorControlPane.widget.rangeMin"`, - ); - clickClearButton(container); - expect(ref.isValid().error?.message).toBeUndefined(); - }); - }); -}); diff --git a/packages/netlify-cms-widget-select/src/index.js b/packages/netlify-cms-widget-select/src/index.js deleted file mode 100644 index 481490aa..00000000 --- a/packages/netlify-cms-widget-select/src/index.js +++ /dev/null @@ -1,16 +0,0 @@ -import controlComponent from './SelectControl'; -import previewComponent from './SelectPreview'; -import schema from './schema'; - -function Widget(opts = {}) { - return { - name: 'select', - controlComponent, - previewComponent, - schema, - ...opts, - }; -} - -export const NetlifyCmsWidgetSelect = { Widget, controlComponent, previewComponent }; -export default NetlifyCmsWidgetSelect; diff --git a/packages/netlify-cms-widget-select/webpack.config.js b/packages/netlify-cms-widget-select/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-select/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-string/CHANGELOG.md b/packages/netlify-cms-widget-string/CHANGELOG.md deleted file mode 100644 index 29876577..00000000 --- a/packages/netlify-cms-widget-string/CHANGELOG.md +++ /dev/null @@ -1,223 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.10...netlify-cms-widget-string@2.3.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.2.10](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.9...netlify-cms-widget-string@2.2.10) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.9](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.8...netlify-cms-widget-string@2.2.9) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.8](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.7...netlify-cms-widget-string@2.2.8) (2020-11-30) - - -### Bug Fixes - -* **widget-string:** fix cursor jumping to end of line ([#4607](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/4607)) ([1413d04](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/1413d04d7dc51156d975f9b2f604749cfbc32a73)) - - - - - -## [2.2.7](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.6...netlify-cms-widget-string@2.2.7) (2020-09-15) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## 2.2.6 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.2.5 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.2.4 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.2...netlify-cms-widget-string@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.2-beta.0...netlify-cms-widget-string@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.1...netlify-cms-widget-string@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.1-beta.2...netlify-cms-widget-string@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.1-beta.1...netlify-cms-widget-string@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.1-beta.0...netlify-cms-widget-string@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.2.0...netlify-cms-widget-string@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.1.0...netlify-cms-widget-string@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.1.0-beta.0...netlify-cms-widget-string@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-string - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.0.5-beta.0...netlify-cms-widget-string@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/82cc794)) - - - - - -## [2.0.5-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.0.4...netlify-cms-widget-string@2.0.5-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/commit/ccef446)) - - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.0.3...netlify-cms-widget-string@2.0.4) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-string - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.0.2...netlify-cms-widget-string@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-string - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string/compare/netlify-cms-widget-string@2.0.1...netlify-cms-widget-string@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-string - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-string diff --git a/packages/netlify-cms-widget-string/README.md b/packages/netlify-cms-widget-string/README.md deleted file mode 100644 index c4f6f5ae..00000000 --- a/packages/netlify-cms-widget-string/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-string/README.md)! diff --git a/packages/netlify-cms-widget-string/package.json b/packages/netlify-cms-widget-string/package.json deleted file mode 100644 index f64fbf0a..00000000 --- a/packages/netlify-cms-widget-string/package.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "netlify-cms-widget-string", - "description": "Widget for editing plain string values in Netlify CMS.", - "version": "2.3.0", - "homepage": "https://www.netlifycms.org/docs/widgets/#string", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-string", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-string.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "string" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "peerDependencies": { - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-string/src/StringControl.js b/packages/netlify-cms-widget-string/src/StringControl.js deleted file mode 100644 index 16694027..00000000 --- a/packages/netlify-cms-widget-string/src/StringControl.js +++ /dev/null @@ -1,61 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; - -export default class StringControl extends React.Component { - static propTypes = { - onChange: PropTypes.func.isRequired, - forID: PropTypes.string, - value: PropTypes.node, - classNameWrapper: PropTypes.string.isRequired, - setActiveStyle: PropTypes.func.isRequired, - setInactiveStyle: PropTypes.func.isRequired, - }; - - static defaultProps = { - value: '', - }; - - // The selection to maintain for the input element - _sel = 0; - - // The input element ref - _el = null; - - // NOTE: This prevents the cursor from jumping to the end of the text for - // nested inputs. In other words, this is not an issue on top-level text - // fields such as the `title` of a collection post. However, it becomes an - // issue on fields nested within other components, namely widgets nested - // within a `markdown` widget. For example, the alt text on a block image - // within markdown. - // SEE: https://github.com/netlify/netlify-cms/issues/4539 - // SEE: https://github.com/netlify/netlify-cms/issues/3578 - componentDidUpdate() { - if (this._el && this._el.selectionStart !== this._sel) { - this._el.setSelectionRange(this._sel, this._sel); - } - } - - handleChange = e => { - this._sel = e.target.selectionStart; - this.props.onChange(e.target.value); - }; - - render() { - const { forID, value, classNameWrapper, setActiveStyle, setInactiveStyle } = this.props; - - return ( - { - this._el = el; - }} - type="text" - id={forID} - className={classNameWrapper} - value={value || ''} - onChange={this.handleChange} - onFocus={setActiveStyle} - onBlur={setInactiveStyle} - /> - ); - } -} diff --git a/packages/netlify-cms-widget-string/src/StringPreview.js b/packages/netlify-cms-widget-string/src/StringPreview.js deleted file mode 100644 index 4e591b05..00000000 --- a/packages/netlify-cms-widget-string/src/StringPreview.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { WidgetPreviewContainer } from 'netlify-cms-ui-default'; - -function StringPreview({ value }) { - return {value}; -} - -StringPreview.propTypes = { - value: PropTypes.node, -}; - -export default StringPreview; diff --git a/packages/netlify-cms-widget-string/webpack.config.js b/packages/netlify-cms-widget-string/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-string/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms-widget-text/CHANGELOG.md b/packages/netlify-cms-widget-text/CHANGELOG.md deleted file mode 100644 index abaa7a5a..00000000 --- a/packages/netlify-cms-widget-text/CHANGELOG.md +++ /dev/null @@ -1,253 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.4.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.4.0...netlify-cms-widget-text@2.4.1) (2021-05-19) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.3.6...netlify-cms-widget-text@2.4.0) (2021-05-04) - - -### Features - -* added react 17 as peer dependency in packages ([#5316](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/5316)) ([9e42380](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/9e423805707321396eec137f5b732a5b07a0dd3f)) - - - - - -## [2.3.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.3.5...netlify-cms-widget-text@2.3.6) (2021-02-23) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.3.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.3.4...netlify-cms-widget-text@2.3.5) (2021-02-10) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.3.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.3.3...netlify-cms-widget-text@2.3.4) (2020-09-15) - - -### Bug Fixes - -* **deps:** update dependency react-textarea-autosize to v8 ([#4312](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/4312)) ([1071e0b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/1071e0b222e1535f168a3928754ce56b48752f49)) - - - - - -## 2.3.3 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.3.2 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.3.1 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.3...netlify-cms-widget-text@2.3.0) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -## [2.2.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.2...netlify-cms-widget-text@2.2.3) (2019-07-24) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.2.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.2-beta.0...netlify-cms-widget-text@2.2.2) (2019-04-10) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.2.2-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.1...netlify-cms-widget-text@2.2.2-beta.0) (2019-04-05) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.1-beta.2...netlify-cms-widget-text@2.2.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.2.1-beta.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.1-beta.1...netlify-cms-widget-text@2.2.1-beta.2) (2019-03-28) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -## [2.2.1-beta.1](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.1-beta.0...netlify-cms-widget-text@2.2.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/6ffd13b)) - - - - - -## [2.2.1-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.2.0...netlify-cms-widget-text@2.2.1-beta.0) (2019-03-25) - - -### Bug Fixes - -* update peer dep versions ([#2234](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2234)) ([7987091](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/7987091)) - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.1.0...netlify-cms-widget-text@2.2.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/d142b32)) - - - - - -# [2.1.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.1.0-beta.0...netlify-cms-widget-text@2.1.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms-widget-text - - - - - -# [2.1.0-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.7-beta.0...netlify-cms-widget-text@2.1.0-beta.0) (2019-03-21) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/82cc794)) - - - - - -## [2.0.7-beta.0](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.6...netlify-cms-widget-text@2.0.7-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/ccef446)) - - - - - -## [2.0.6](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.5...netlify-cms-widget-text@2.0.6) (2018-11-29) - - -### Bug Fixes - -* **netlify-cms-widget-text:** set correct font family ([#1916](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/issues/1916)) ([a2e9401](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/commit/a2e9401)) - - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.4...netlify-cms-widget-text@2.0.5) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms-widget-text - - -## [2.0.4](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.3...netlify-cms-widget-text@2.0.4) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms-widget-text - - -## [2.0.3](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.2...netlify-cms-widget-text@2.0.3) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms-widget-text - - -## [2.0.2](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text/compare/netlify-cms-widget-text@2.0.1...netlify-cms-widget-text@2.0.2) (2018-07-28) - - - - -**Note:** Version bump only for package netlify-cms-widget-text - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms-widget-text diff --git a/packages/netlify-cms-widget-text/README.md b/packages/netlify-cms-widget-text/README.md deleted file mode 100644 index ad2d6cc8..00000000 --- a/packages/netlify-cms-widget-text/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# Docs coming soon! - -Netlify CMS was recently converted from a single npm package to a "monorepo" of over 20 packages. -That's over 20 Readme's! We haven't created one for this package yet, but we will soon. - -In the meantime, you can: - -1. Check out the [main readme](https://github.com/netlify/netlify-cms/#readme) or the [documentation - site](https://www.netlifycms.org) for more info. -2. Reach out to the [community chat](https://netlifycms.org/chat/) if you need help. -3. Help out and [write the readme yourself](https://github.com/netlify/netlify-cms/edit/master/packages/netlify-cms-widget-text/README.md)! diff --git a/packages/netlify-cms-widget-text/package.json b/packages/netlify-cms-widget-text/package.json deleted file mode 100644 index a8a3fa3b..00000000 --- a/packages/netlify-cms-widget-text/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "netlify-cms-widget-text", - "description": "Widget for editing multiline plain string values in Netlify CMS.", - "version": "2.4.1", - "homepage": "https://www.netlifycms.org/docs/widgets/#text", - "repository": "https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-widget-text", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "module": "dist/esm/index.js", - "main": "dist/netlify-cms-widget-text.js", - "license": "MIT", - "keywords": [ - "netlify", - "netlify-cms", - "widget", - "string", - "text", - "textarea", - "mulitiline" - ], - "sideEffects": false, - "scripts": { - "develop": "yarn build:esm --watch", - "build": "cross-env NODE_ENV=production webpack", - "build:esm": "cross-env NODE_ENV=esm babel src --out-dir dist/esm --ignore \"**/__tests__\" --root-mode upward" - }, - "dependencies": { - "react-textarea-autosize": "^8.0.0" - }, - "peerDependencies": { - "netlify-cms-ui-default": "^2.12.1", - "prop-types": "^15.7.2", - "react": "^16.8.4 || ^17.0.0" - } -} diff --git a/packages/netlify-cms-widget-text/webpack.config.js b/packages/netlify-cms-widget-text/webpack.config.js deleted file mode 100644 index 42edd361..00000000 --- a/packages/netlify-cms-widget-text/webpack.config.js +++ /dev/null @@ -1,3 +0,0 @@ -const { getConfig } = require('../../scripts/webpack.js'); - -module.exports = getConfig(); diff --git a/packages/netlify-cms/CHANGELOG.md b/packages/netlify-cms/CHANGELOG.md deleted file mode 100644 index 994e0604..00000000 --- a/packages/netlify-cms/CHANGELOG.md +++ /dev/null @@ -1,2387 +0,0 @@ -# Change Log - -All notable changes to this project will be documented in this file. -See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. - -## [2.10.222](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.221...netlify-cms@2.10.222) (2022-09-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.221](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.220...netlify-cms@2.10.221) (2022-09-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.220](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.219...netlify-cms@2.10.220) (2022-09-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.219](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.218...netlify-cms@2.10.219) (2022-09-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.218](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.217...netlify-cms@2.10.218) (2022-09-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.217](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.216...netlify-cms@2.10.217) (2022-09-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.216](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.215...netlify-cms@2.10.216) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.215](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.214...netlify-cms@2.10.215) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.214](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.213...netlify-cms@2.10.214) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.213](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.212...netlify-cms@2.10.213) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.212](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.211...netlify-cms@2.10.212) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.211](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.210...netlify-cms@2.10.211) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.210](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.209...netlify-cms@2.10.210) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.209](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.208...netlify-cms@2.10.209) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.208](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.207...netlify-cms@2.10.208) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.207](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.206...netlify-cms@2.10.207) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.206](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.205...netlify-cms@2.10.206) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.205](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.204...netlify-cms@2.10.205) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.204](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.203...netlify-cms@2.10.204) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.203](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.202...netlify-cms@2.10.203) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.202](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.201...netlify-cms@2.10.202) (2022-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.201](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.200...netlify-cms@2.10.201) (2022-09-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.200](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.199...netlify-cms@2.10.200) (2022-09-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.199](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.198...netlify-cms@2.10.199) (2022-09-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.198](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.197...netlify-cms@2.10.198) (2022-09-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.197](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.196...netlify-cms@2.10.197) (2022-09-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.196](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.195...netlify-cms@2.10.196) (2022-09-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.195](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.192...netlify-cms@2.10.195) (2022-09-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.194](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.192...netlify-cms@2.10.194) (2022-09-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.193](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.192...netlify-cms@2.10.193) (2022-09-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.192](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.191...netlify-cms@2.10.192) (2022-04-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.191](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.190...netlify-cms@2.10.191) (2022-04-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.190](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.189...netlify-cms@2.10.190) (2022-03-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.189](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.188...netlify-cms@2.10.189) (2022-03-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.188](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.187...netlify-cms@2.10.188) (2022-03-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.187](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.186...netlify-cms@2.10.187) (2022-02-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.186](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.185...netlify-cms@2.10.186) (2022-02-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.185](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.184...netlify-cms@2.10.185) (2022-01-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.184](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.183...netlify-cms@2.10.184) (2022-01-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.183](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.182...netlify-cms@2.10.183) (2021-12-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.182](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.181...netlify-cms@2.10.182) (2021-12-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.181](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.180...netlify-cms@2.10.181) (2021-12-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.180](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.179...netlify-cms@2.10.180) (2021-12-03) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.179](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.178...netlify-cms@2.10.179) (2021-11-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.178](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.177...netlify-cms@2.10.178) (2021-11-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.177](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.176...netlify-cms@2.10.177) (2021-10-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.176](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.175...netlify-cms@2.10.176) (2021-10-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.175](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.174...netlify-cms@2.10.175) (2021-10-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.174](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.173...netlify-cms@2.10.174) (2021-10-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.173](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.172...netlify-cms@2.10.173) (2021-10-18) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.172](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.171...netlify-cms@2.10.172) (2021-10-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.171](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.170...netlify-cms@2.10.171) (2021-10-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.170](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.169...netlify-cms@2.10.170) (2021-10-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.169](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.168...netlify-cms@2.10.169) (2021-10-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.168](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.167...netlify-cms@2.10.168) (2021-10-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.167](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.166...netlify-cms@2.10.167) (2021-10-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.166](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.165...netlify-cms@2.10.166) (2021-09-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.165](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.164...netlify-cms@2.10.165) (2021-09-29) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.164](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.163...netlify-cms@2.10.164) (2021-09-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.163](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.162...netlify-cms@2.10.163) (2021-09-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.162](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.161...netlify-cms@2.10.162) (2021-09-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.161](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.160...netlify-cms@2.10.161) (2021-09-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.160](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.159...netlify-cms@2.10.160) (2021-08-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.159](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.158...netlify-cms@2.10.159) (2021-08-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.158](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.157...netlify-cms@2.10.158) (2021-08-17) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.157](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.156...netlify-cms@2.10.157) (2021-08-17) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.156](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.155...netlify-cms@2.10.156) (2021-08-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.155](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.154...netlify-cms@2.10.155) (2021-08-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.154](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.153...netlify-cms@2.10.154) (2021-08-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.153](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.152...netlify-cms@2.10.153) (2021-08-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.152](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.151...netlify-cms@2.10.152) (2021-08-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.151](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.150...netlify-cms@2.10.151) (2021-08-03) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.150](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.149...netlify-cms@2.10.150) (2021-07-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.149](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.148...netlify-cms@2.10.149) (2021-07-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.148](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.147...netlify-cms@2.10.148) (2021-07-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.147](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.146...netlify-cms@2.10.147) (2021-07-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.146](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.145...netlify-cms@2.10.146) (2021-07-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.145](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.144...netlify-cms@2.10.145) (2021-07-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.144](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.143...netlify-cms@2.10.144) (2021-07-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.143](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.142...netlify-cms@2.10.143) (2021-07-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.142](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.141...netlify-cms@2.10.142) (2021-07-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.141](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.140...netlify-cms@2.10.141) (2021-07-05) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.140](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.139...netlify-cms@2.10.140) (2021-06-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.139](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.138...netlify-cms@2.10.139) (2021-06-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.138](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.137...netlify-cms@2.10.138) (2021-06-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.137](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.136...netlify-cms@2.10.137) (2021-06-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.136](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.135...netlify-cms@2.10.136) (2021-05-31) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.135](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.134...netlify-cms@2.10.135) (2021-05-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.134](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.133...netlify-cms@2.10.134) (2021-05-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.133](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.132...netlify-cms@2.10.133) (2021-05-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.132](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.131...netlify-cms@2.10.132) (2021-05-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.131](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.130...netlify-cms@2.10.131) (2021-05-23) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.130](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.129...netlify-cms@2.10.130) (2021-05-23) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.129](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.128...netlify-cms@2.10.129) (2021-05-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.128](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.127...netlify-cms@2.10.128) (2021-05-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.127](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.126...netlify-cms@2.10.127) (2021-05-19) - - -### Bug Fixes - -* **deps:** update dependency react-datetime to v3 ([#5383](https://github.com/netlify/netlify-cms/issues/5383)) ([a2735b5](https://github.com/netlify/netlify-cms/commit/a2735b5fd68470821841f608ce2123e8ce74c4e0)) - - - - - -## [2.10.126](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.125...netlify-cms@2.10.126) (2021-05-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.125](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.124...netlify-cms@2.10.125) (2021-05-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.124](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.123...netlify-cms@2.10.124) (2021-05-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.123](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.122...netlify-cms@2.10.123) (2021-05-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.122](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.121...netlify-cms@2.10.122) (2021-05-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.121](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.120...netlify-cms@2.10.121) (2021-05-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.120](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.119...netlify-cms@2.10.120) (2021-05-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.119](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.118...netlify-cms@2.10.119) (2021-05-03) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.118](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.117...netlify-cms@2.10.118) (2021-04-29) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.117](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.116...netlify-cms@2.10.117) (2021-04-18) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.116](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.115...netlify-cms@2.10.116) (2021-04-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.115](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.114...netlify-cms@2.10.115) (2021-04-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.114](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.113...netlify-cms@2.10.114) (2021-04-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.113](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.112...netlify-cms@2.10.113) (2021-04-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.112](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.111...netlify-cms@2.10.112) (2021-04-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.111](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.110...netlify-cms@2.10.111) (2021-04-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.110](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.109...netlify-cms@2.10.110) (2021-04-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.109](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.108...netlify-cms@2.10.109) (2021-04-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.108](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.107...netlify-cms@2.10.108) (2021-04-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.107](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.106...netlify-cms@2.10.107) (2021-04-04) - - -### Bug Fixes - -* **netlify-cms-package:** remove module field ([#5207](https://github.com/netlify/netlify-cms/issues/5207)) ([c7c3928](https://github.com/netlify/netlify-cms/commit/c7c39287ba66e3896ef57d7c3dc4934030d49c68)) - - - - - -## [2.10.106](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.105...netlify-cms@2.10.106) (2021-04-04) - - -### Bug Fixes - -* generate esm correctly ([#5087](https://github.com/netlify/netlify-cms/issues/5087)) ([9b1546f](https://github.com/netlify/netlify-cms/commit/9b1546f131772185b3d39d18b6e57dc41ff5c7ca)) - - - - - -## [2.10.105](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.104...netlify-cms@2.10.105) (2021-04-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.104](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.103...netlify-cms@2.10.104) (2021-03-31) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.103](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.102...netlify-cms@2.10.103) (2021-03-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.102](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.101...netlify-cms@2.10.102) (2021-03-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.101](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.100...netlify-cms@2.10.101) (2021-03-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.100](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.99...netlify-cms@2.10.100) (2021-03-18) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.99](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.98...netlify-cms@2.10.99) (2021-03-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.98](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.97...netlify-cms@2.10.98) (2021-03-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.97](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.96...netlify-cms@2.10.97) (2021-03-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.96](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.95...netlify-cms@2.10.96) (2021-02-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.95](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.94...netlify-cms@2.10.95) (2021-02-23) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.94](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.93...netlify-cms@2.10.94) (2021-02-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.93](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.92...netlify-cms@2.10.93) (2021-02-16) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.92](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.91...netlify-cms@2.10.92) (2021-02-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.91](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.90...netlify-cms@2.10.91) (2021-02-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.90](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.89...netlify-cms@2.10.90) (2021-02-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.89](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.88...netlify-cms@2.10.89) (2021-02-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.88](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.87...netlify-cms@2.10.88) (2021-02-03) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.87](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.86...netlify-cms@2.10.87) (2021-02-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.86](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.85...netlify-cms@2.10.86) (2021-02-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.85](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.84...netlify-cms@2.10.85) (2021-02-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.84](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.83...netlify-cms@2.10.84) (2021-01-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.83](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.82...netlify-cms@2.10.83) (2021-01-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.82](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.81...netlify-cms@2.10.82) (2021-01-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.81](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.80...netlify-cms@2.10.81) (2021-01-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.80](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.79...netlify-cms@2.10.80) (2021-01-05) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.79](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.78...netlify-cms@2.10.79) (2021-01-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.78](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.77...netlify-cms@2.10.78) (2020-12-23) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.77](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.76...netlify-cms@2.10.77) (2020-12-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.76](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.75...netlify-cms@2.10.76) (2020-12-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.75](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.74...netlify-cms@2.10.75) (2020-12-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.74](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.73...netlify-cms@2.10.74) (2020-12-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.73](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.72...netlify-cms@2.10.73) (2020-11-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.72](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.71...netlify-cms@2.10.72) (2020-11-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.71](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.70...netlify-cms@2.10.71) (2020-11-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.70](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.69...netlify-cms@2.10.70) (2020-11-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.69](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.68...netlify-cms@2.10.69) (2020-11-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.68](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.67...netlify-cms@2.10.68) (2020-11-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.67](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.66...netlify-cms@2.10.67) (2020-11-02) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.66](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.65...netlify-cms@2.10.66) (2020-10-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.65](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.64...netlify-cms@2.10.65) (2020-10-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.64](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.63...netlify-cms@2.10.64) (2020-10-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.63](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.62...netlify-cms@2.10.63) (2020-10-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.62](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.61...netlify-cms@2.10.62) (2020-10-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.61](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.60...netlify-cms@2.10.61) (2020-09-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.60](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.59...netlify-cms@2.10.60) (2020-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.59](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.58...netlify-cms@2.10.59) (2020-09-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.58](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.57...netlify-cms@2.10.58) (2020-09-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## 2.10.57 (2020-09-08) - - -### Reverts - -* Revert "chore(release): publish" ([828bb16](https://github.com/netlify/netlify-cms/commit/828bb16415b8c22a34caa19c50c38b24ffe9ceae)) - - - - - -## 2.10.56 (2020-08-20) - - -### Reverts - -* Revert "chore(release): publish" ([8262487](https://github.com/netlify/netlify-cms/commit/82624879ccbcb16610090041db28f00714d924c8)) - - - - - -## 2.10.55 (2020-07-27) - - -### Reverts - -* Revert "chore(release): publish" ([118d50a](https://github.com/netlify/netlify-cms/commit/118d50a7a70295f25073e564b5161aa2b9883056)) - - - - - -## [2.10.54](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.53...netlify-cms@2.10.54) (2020-07-16) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.53](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.52...netlify-cms@2.10.53) (2020-07-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.52](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.51...netlify-cms@2.10.52) (2020-07-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.51](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.50...netlify-cms@2.10.51) (2020-06-18) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.50](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.49...netlify-cms@2.10.50) (2020-06-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.49](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.48...netlify-cms@2.10.49) (2020-05-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.48](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.47...netlify-cms@2.10.48) (2020-05-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.47](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.46...netlify-cms@2.10.47) (2020-04-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.46](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.45...netlify-cms@2.10.46) (2020-04-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.45](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.44...netlify-cms@2.10.45) (2020-04-16) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.44](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.43...netlify-cms@2.10.44) (2020-04-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.43](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.42...netlify-cms@2.10.43) (2020-04-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.42](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.41...netlify-cms@2.10.42) (2020-04-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.41](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.40...netlify-cms@2.10.41) (2020-04-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.40](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.39...netlify-cms@2.10.40) (2020-04-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.39](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.38...netlify-cms@2.10.39) (2020-04-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.38](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.37...netlify-cms@2.10.38) (2020-04-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.37](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.36...netlify-cms@2.10.37) (2020-04-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.36](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.35...netlify-cms@2.10.36) (2020-03-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.35](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.34...netlify-cms@2.10.35) (2020-03-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.34](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.33...netlify-cms@2.10.34) (2020-03-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.33](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.32...netlify-cms@2.10.33) (2020-03-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.32](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.31...netlify-cms@2.10.32) (2020-03-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.31](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.30...netlify-cms@2.10.31) (2020-03-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.30](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.29...netlify-cms@2.10.30) (2020-03-03) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.29](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.28...netlify-cms@2.10.29) (2020-02-27) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.28](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.27...netlify-cms@2.10.28) (2020-02-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.27](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.26...netlify-cms@2.10.27) (2020-02-25) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.26](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.25...netlify-cms@2.10.26) (2020-02-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.25](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.24...netlify-cms@2.10.25) (2020-02-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.24](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.23...netlify-cms@2.10.24) (2020-02-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.23](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.22...netlify-cms@2.10.23) (2020-02-17) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.22](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.21...netlify-cms@2.10.22) (2020-02-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.21](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.20...netlify-cms@2.10.21) (2020-02-13) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.20](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.19...netlify-cms@2.10.20) (2020-02-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.19](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.18...netlify-cms@2.10.19) (2020-02-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.18](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.17...netlify-cms@2.10.18) (2020-02-10) - - -### Reverts - -* Revert "chore(release): publish" ([a015d1d](https://github.com/netlify/netlify-cms/commit/a015d1d92a4b1c0130c44fcef1c9ecdb157a0f07)) - - - - - -## [2.10.17](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.16...netlify-cms@2.10.17) (2020-02-06) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.16](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.15...netlify-cms@2.10.16) (2020-02-01) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.15](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.14...netlify-cms@2.10.15) (2020-01-30) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.14](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.13...netlify-cms@2.10.14) (2020-01-29) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.13](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.12...netlify-cms@2.10.13) (2020-01-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.12](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.11...netlify-cms@2.10.12) (2020-01-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.11](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.10...netlify-cms@2.10.11) (2020-01-23) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.10](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.9...netlify-cms@2.10.10) (2020-01-22) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.9](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.8...netlify-cms@2.10.9) (2020-01-21) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.8](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.7...netlify-cms@2.10.8) (2020-01-16) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.7](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.6...netlify-cms@2.10.7) (2020-01-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.6](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.5...netlify-cms@2.10.6) (2020-01-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.5](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.4...netlify-cms@2.10.5) (2020-01-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.4](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.3...netlify-cms@2.10.4) (2020-01-09) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.3-beta.0...netlify-cms@2.10.3) (2020-01-07) - - -### Bug Fixes - -* move code widget and locales to netlify-cms-app ([#3025](https://github.com/netlify/netlify-cms/issues/3025)) ([74ecc21](https://github.com/netlify/netlify-cms/commit/74ecc21879e984e0104e5bb81c30f661162f6758)) - - - - - -## [2.10.3-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.2-beta.0...netlify-cms@2.10.3-beta.0) (2019-12-20) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.2-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.1-beta.0...netlify-cms@2.10.2-beta.0) (2019-12-19) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.10.1-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0...netlify-cms@2.10.1-beta.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.5...netlify-cms@2.10.0) (2019-12-18) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0-beta.5](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.4...netlify-cms@2.10.0-beta.5) (2019-12-16) - - -### Features - -* Code Widget + Markdown Widget Internal Overhaul ([#2828](https://github.com/netlify/netlify-cms/issues/2828)) ([18c579d](https://github.com/netlify/netlify-cms/commit/18c579d0e9f0ff71ed8c52f5c66f2309259af054)) - - - - - -# [2.10.0-beta.4](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.3...netlify-cms@2.10.0-beta.4) (2019-12-11) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0-beta.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.2...netlify-cms@2.10.0-beta.3) (2019-12-02) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0-beta.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.1...netlify-cms@2.10.0-beta.2) (2019-11-26) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.10.0-beta.0...netlify-cms@2.10.0-beta.1) (2019-11-18) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.10.0-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.5...netlify-cms@2.10.0-beta.0) (2019-11-18) - - -### Features - -* add translation support ([#2870](https://github.com/netlify/netlify-cms/issues/2870)) ([096b067](https://github.com/netlify/netlify-cms/commit/096b067d4542c723630ded631fc9a4ba950732f3)), closes [#2877](https://github.com/netlify/netlify-cms/issues/2877) - - - - - -## [2.9.8-beta.5](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.4...netlify-cms@2.9.8-beta.5) (2019-11-07) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.8-beta.4](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.3...netlify-cms@2.9.8-beta.4) (2019-09-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.8-beta.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.2...netlify-cms@2.9.8-beta.3) (2019-09-04) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.8-beta.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.1...netlify-cms@2.9.8-beta.2) (2019-08-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.8-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.8-beta.0...netlify-cms@2.9.8-beta.1) (2019-08-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.8-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.7...netlify-cms@2.9.8-beta.0) (2019-07-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.7](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.6...netlify-cms@2.9.7) (2019-07-24) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.6](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.5...netlify-cms@2.9.6) (2019-07-11) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.5](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.4...netlify-cms@2.9.5) (2019-06-28) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.4](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.3...netlify-cms@2.9.4) (2019-06-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.2...netlify-cms@2.9.3) (2019-06-18) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.2-beta.2...netlify-cms@2.9.2) (2019-06-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.2-beta.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.2-beta.1...netlify-cms@2.9.2-beta.2) (2019-06-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.2-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.2-beta.0...netlify-cms@2.9.2-beta.1) (2019-05-15) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.2-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.1...netlify-cms@2.9.2-beta.0) (2019-04-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.1-beta.2...netlify-cms@2.9.1) (2019-04-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.1-beta.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.1-beta.1...netlify-cms@2.9.1-beta.2) (2019-04-05) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.1-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.1-beta.0...netlify-cms@2.9.1-beta.1) (2019-04-02) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.9.1-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.0...netlify-cms@2.9.1-beta.0) (2019-03-29) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.9.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.0-beta.1...netlify-cms@2.9.0) (2019-03-29) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.9.0-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.9.0-beta.0...netlify-cms@2.9.0-beta.1) (2019-03-29) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.9.0-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.8.1-beta.1...netlify-cms@2.9.0-beta.0) (2019-03-28) - - -### Features - -* add byo react package netlify-cms-app ([#2252](https://github.com/netlify/netlify-cms/issues/2252)) ([ff4ffd7](https://github.com/netlify/netlify-cms/commit/ff4ffd7)) - - - - - -## [2.8.1-beta.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.8.1-beta.0...netlify-cms@2.8.1-beta.1) (2019-03-26) - - -### Bug Fixes - -* export on netlify-cms and maps on esm ([#2244](https://github.com/netlify/netlify-cms/issues/2244)) ([6ffd13b](https://github.com/netlify/netlify-cms/commit/6ffd13b)) - - - - - -## [2.8.1-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.8.0...netlify-cms@2.8.1-beta.0) (2019-03-25) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.8.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.7.1-beta.0...netlify-cms@2.8.0) (2019-03-22) - - -### Features - -* add ES module builds ([#2215](https://github.com/netlify/netlify-cms/issues/2215)) ([d142b32](https://github.com/netlify/netlify-cms/commit/d142b32)) - - - - - -## [2.7.1-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.7.0...netlify-cms@2.7.1-beta.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.7.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.7.0-beta.0...netlify-cms@2.7.0) (2019-03-22) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.7.0-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.6.2-beta.0...netlify-cms@2.7.0-beta.0) (2019-03-21) - - -### Bug Fixes - -* fix umd builds ([#2214](https://github.com/netlify/netlify-cms/issues/2214)) ([e04f6be](https://github.com/netlify/netlify-cms/commit/e04f6be)) - - -### Features - -* provide usable UMD builds for all packages ([#2141](https://github.com/netlify/netlify-cms/issues/2141)) ([82cc794](https://github.com/netlify/netlify-cms/commit/82cc794)) - - - - - -## [2.6.2-beta.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.6.2-alpha.0...netlify-cms@2.6.2-beta.0) (2019-03-15) - - -### Features - -* upgrade to Emotion 10 ([#2166](https://github.com/netlify/netlify-cms/issues/2166)) ([ccef446](https://github.com/netlify/netlify-cms/commit/ccef446)) - - - - - -## [2.6.2-alpha.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.6.1...netlify-cms@2.6.2-alpha.0) (2019-03-14) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.6.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.6.0...netlify-cms@2.6.1) (2019-03-11) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.6.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.5.1...netlify-cms@2.6.0) (2019-03-08) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.5.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.5.0...netlify-cms@2.5.1) (2019-02-28) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.5.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.4.2...netlify-cms@2.5.0) (2019-02-26) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.4.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.4.1...netlify-cms@2.4.2) (2019-02-12) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.4.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.4.0...netlify-cms@2.4.1) (2019-02-09) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.4.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.3.3...netlify-cms@2.4.0) (2019-02-08) - - -### Features - -* **netlify-cms-widget-map:** add map widget ([#2051](https://github.com/netlify/netlify-cms/issues/2051)) ([18f34d2](https://github.com/netlify/netlify-cms/commit/18f34d2)) - - - - - -## [2.3.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.3.2...netlify-cms@2.3.3) (2019-01-10) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.3.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.3.1...netlify-cms@2.3.2) (2018-12-27) - -**Note:** Version bump only for package netlify-cms - - - - - -## [2.3.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.3.0...netlify-cms@2.3.1) (2018-12-11) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.3.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.2.1...netlify-cms@2.3.0) (2018-12-04) - - -### Features - -* add cloudinary support ([#1932](https://github.com/netlify/netlify-cms/issues/1932)) ([1fc2f50](https://github.com/netlify/netlify-cms/commit/1fc2f50)) - - - - - -## [2.2.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.2.0...netlify-cms@2.2.1) (2018-11-29) - -**Note:** Version bump only for package netlify-cms - - - - - -# [2.2.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.1.3...netlify-cms@2.2.0) (2018-11-12) - -**Note:** Version bump only for package netlify-cms - - - - - - -## [2.1.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.1.2...netlify-cms@2.1.3) (2018-10-09) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.1.2](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.1.1...netlify-cms@2.1.2) (2018-09-17) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.1.1](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.1.0...netlify-cms@2.1.1) (2018-09-06) - - - - -**Note:** Version bump only for package netlify-cms - - -# [2.1.0](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.11...netlify-cms@2.1.0) (2018-09-06) - - -### Features - -* **media:** add external media library support, Uploadcare integration ([#1602](https://github.com/netlify/netlify-cms/issues/1602)) ([0596904](https://github.com/netlify/netlify-cms/commit/0596904)) - - - - - -## [2.0.11](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.10...netlify-cms@2.0.11) (2018-08-27) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.0.10](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.9...netlify-cms@2.0.10) (2018-08-24) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.0.9](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.8...netlify-cms@2.0.9) (2018-08-07) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.0.8](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.7...netlify-cms@2.0.8) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.0.7](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.6...netlify-cms@2.0.7) (2018-08-01) - - - - -**Note:** Version bump only for package netlify-cms - - -## [2.0.6](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.5...netlify-cms@2.0.6) (2018-07-28) - - -### Bug Fixes - -* register bitbucket backend in netlify-cms ([#1537](https://github.com/netlify/netlify-cms/issues/1537)) ([99d4b2b](https://github.com/netlify/netlify-cms/commit/99d4b2b)) - - - - - -## [2.0.5](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.4...netlify-cms@2.0.5) (2018-07-27) - - -### Bug Fixes - -* fix netlify-cms webpack plugins ([5af0586](https://github.com/netlify/netlify-cms/commit/5af0586)) -* log accurate version by distribution ([#1531](https://github.com/netlify/netlify-cms/issues/1531)) ([95a76ad](https://github.com/netlify/netlify-cms/commit/95a76ad)) - - - - - -## [2.0.4](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.3...netlify-cms@2.0.4) (2018-07-27) - - -### Bug Fixes - -* fix netlify-cms exports ([d0dabc4](https://github.com/netlify/netlify-cms/commit/d0dabc4)) - - - - - -## [2.0.3](https://github.com/netlify/netlify-cms/compare/netlify-cms@2.0.2...netlify-cms@2.0.3) (2018-07-27) - - -### Bug Fixes - -* pass netlify-cms-core exports through netlify-cms ([#1530](https://github.com/netlify/netlify-cms/issues/1530)) ([f0af6e8](https://github.com/netlify/netlify-cms/commit/f0af6e8)) - - - - - -## 2.0.2 (2018-07-27) - - -### Bug Fixes - -* **build:** output aliased cms.js w/ deprecation ([#1526](https://github.com/netlify/netlify-cms/issues/1526)) ([34c8c2a](https://github.com/netlify/netlify-cms/commit/34c8c2a)) - - - - -## 2.0.1 (2018-07-26) - - - - -# 2.0.0 (2018-07-26) - - - - -**Note:** Version bump only for package netlify-cms diff --git a/packages/netlify-cms/README.md b/packages/netlify-cms/README.md deleted file mode 100644 index adcb3aeb..00000000 --- a/packages/netlify-cms/README.md +++ /dev/null @@ -1,59 +0,0 @@ -# Netlify CMS -A CMS for static site generators. Give users a simple way to edit -and add content to any site built with a static site generator. - -## Community Chat - - - Join us on Slack - - -## How it works - -Netlify CMS is a single-page app that you pull into the `/admin` part of your site. - -It presents a clean UI for editing content stored in a Git repository. - -You setup a YAML config to describe the content model of your site, and typically -tweak the main layout of the CMS a bit to fit your own site. - -When a user navigates to `/admin/` they'll be prompted to login, and once authenticated -they'll be able to create new content or edit existing content. - -Read more about Netlify CMS [Core Concepts](https://www.netlifycms.org/docs/intro/). - -# Installation and Configuration - -The Netlify CMS can be used in two different ways. - -* A Quick and easy install, that just requires you to create a single HTML file and a configuration file. All the CMS Javascript and CSS are loaded from a CDN. - To learn more about this installation method, refer to the [Quick Start Guide](https://www.netlifycms.org/docs/quick-start/) -* A complete, more complex install, that gives you more flexibility but requires that you use a static site builder with a build system that supports npm packages. - -# Contributing - -New contributors are always welcome! Check out [CONTRIBUTING.md](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md) to get involved. - -# Change Log - -This project adheres to [Semantic Versioning](http://semver.org/). -Every release is documented on the Github [Releases](https://github.com/netlify/netlify-cms/releases) page. - -# License - -Netlify CMS is released under the [MIT License](LICENSE). -Please make sure you understand its [implications and guarantees](https://writing.kemitchell.com/2016/09/21/MIT-License-Line-by-Line.html). - -# Thanks - -## Services -These services support Netlify CMS development by providing free infrastructure. -

    - - - - - - - -

    diff --git a/packages/netlify-cms/package.json b/packages/netlify-cms/package.json deleted file mode 100644 index 38c870ff..00000000 --- a/packages/netlify-cms/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "netlify-cms", - "description": "An extensible, open source, Git-based, React CMS for static sites.", - "version": "2.10.222", - "homepage": "https://www.netlifycms.org", - "repository": "https://github.com/netlify/netlify-cms", - "bugs": "https://github.com/netlify/netlify-cms/issues", - "main": "dist/netlify-cms.js", - "scripts": { - "webpack": "node --max_old_space_size=4096 ../../node_modules/webpack/bin/webpack.js", - "build": "cross-env NODE_ENV=production run-s webpack", - "build-preview": "cross-env NODE_ENV=production webpack serve --open", - "develop": "webpack serve --hot" - }, - "keywords": [ - "netlify", - "cms", - "content editing", - "static site generators", - "jamstack" - ], - "license": "MIT", - "dependencies": { - "codemirror": "^5.46.0", - "create-react-class": "^15.7.0", - "netlify-cms-app": "^2.15.108", - "netlify-cms-media-library-cloudinary": "^1.3.10", - "netlify-cms-media-library-uploadcare": "^0.5.10", - "react": "^16.8.4", - "react-dom": "^16.8.4" - }, - "devDependencies": { - "react-hot-loader": "4.13.0" - }, - "incrementToForceBump": 2 -} diff --git a/packages/netlify-cms/shims/cms.css b/packages/netlify-cms/shims/cms.css deleted file mode 100644 index beecb271..00000000 --- a/packages/netlify-cms/shims/cms.css +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Netlify CMS 2.0 moved from static CSS to CSS-in-JS. Some site builds are configured to look - * for `cms.css`, and will break when it's missing, so we're putting out this blank file to help. - * We'll eventually remove it, so please update your build to not require it. - */ diff --git a/packages/netlify-cms/shims/deprecate-old-dist.js b/packages/netlify-cms/shims/deprecate-old-dist.js deleted file mode 100644 index ed130bca..00000000 --- a/packages/netlify-cms/shims/deprecate-old-dist.js +++ /dev/null @@ -1,3 +0,0 @@ -console.warn( - 'You seem to be loading Netlify CMS by fetching `dist/cms.js` from a CDN. That file is deprecated and will be removed in the next major release. Please use `dist/netlify-cms.js` instead.', -); diff --git a/packages/netlify-cms/src/extensions.js b/packages/netlify-cms/src/extensions.js deleted file mode 100644 index d11f0b75..00000000 --- a/packages/netlify-cms/src/extensions.js +++ /dev/null @@ -1,7 +0,0 @@ -import { NetlifyCmsApp as CMS } from 'netlify-cms-app/dist/esm'; -// Media libraries -import uploadcare from 'netlify-cms-media-library-uploadcare'; -import cloudinary from 'netlify-cms-media-library-cloudinary'; - -CMS.registerMediaLibrary(uploadcare); -CMS.registerMediaLibrary(cloudinary); diff --git a/packages/netlify-cms/src/index.js b/packages/netlify-cms/src/index.js deleted file mode 100644 index f74f7493..00000000 --- a/packages/netlify-cms/src/index.js +++ /dev/null @@ -1,34 +0,0 @@ -import createReactClass from 'create-react-class'; -import React from 'react'; -import { NetlifyCmsApp as CMS } from 'netlify-cms-app/dist/esm'; -import './extensions'; - -/** - * Load Netlify CMS automatically if `window.CMS_MANUAL_INIT` is set. - */ -if (!window.CMS_MANUAL_INIT) { - CMS.init(); -} else { - console.log('`window.CMS_MANUAL_INIT` flag set, skipping automatic initialization.'); -} - -/** - * Add extension hooks to global scope. - */ -if (typeof window !== 'undefined') { - window.CMS = CMS; - window.initCMS = CMS.init; - window.createClass = window.createClass || createReactClass; - window.h = window.h || React.createElement; - /** - * Log the version number. - */ - if (typeof NETLIFY_CMS_VERSION === 'string') { - console.log(`netlify-cms ${NETLIFY_CMS_VERSION}`); - } -} - -export const NetlifyCms = { - ...CMS, -}; -export default CMS; diff --git a/packages/netlify-cms/webpack.config.js b/packages/netlify-cms/webpack.config.js deleted file mode 100644 index 1b2415d9..00000000 --- a/packages/netlify-cms/webpack.config.js +++ /dev/null @@ -1,61 +0,0 @@ -const path = require('path'); -require('dotenv').config({ path: path.join(__dirname, '..', '..', '.env') }); -const webpack = require('webpack'); -const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); -const CopyWebpackPlugin = require('copy-webpack-plugin'); - -const pkg = require('./package.json'); -const { getConfig, plugins } = require('../../scripts/webpack'); -const baseWebpackConfig = getConfig({ baseOnly: true }); - -const isProduction = process.env.NODE_ENV === 'production'; -console.log(`${pkg.version}${isProduction ? '' : '-dev'}`); - -const devServerPort = parseInt(process.env.NETLIFY_CMS_DEV_SERVER_PORT || `${8080}`); - -const baseConfig = { - ...baseWebpackConfig, - plugins: [ - ...Object.entries(plugins) - .filter(([key]) => key !== 'friendlyErrors') - .map(([, plugin]) => plugin()), - new webpack.DefinePlugin({ - NETLIFY_CMS_VERSION: JSON.stringify(`${pkg.version}${isProduction ? '' : '-dev'}`), - }), - new FriendlyErrorsWebpackPlugin({ - compilationSuccessInfo: { - messages: [`Netlify CMS is now running at http://localhost:${devServerPort}`], - }, - }), - new CopyWebpackPlugin({ patterns: [{ from: './shims/cms.css', to: './' }] }), - ], - devServer: { - contentBase: '../../dev-test', - watchContentBase: true, - publicPath: '/dist/', - quiet: true, - host: '0.0.0.0', - port: devServerPort, - }, -}; - -if (isProduction) { - module.exports = [ - baseConfig, - - /** - * Output the same script a second time, but named `cms.js`, and with a - * deprecation notice. - */ - { - ...baseConfig, - entry: ['./shims/deprecate-old-dist.js', baseConfig.entry], - output: { - ...baseConfig.output, - filename: 'cms.js', - }, - }, - ]; -} else { - module.exports = baseConfig; -} diff --git a/scripts/externals.js b/scripts/externals.js index 53c6d471..f1f73618 100644 --- a/scripts/externals.js +++ b/scripts/externals.js @@ -33,84 +33,4 @@ packages.map(name => { module.exports = { toGlobalName, - externals: { - ...packageExports, - lodash: { - root: ['NetlifyCmsDefaultExports', 'Lodash'], - commonjs2: 'lodash', - commonjs: 'lodash', - amd: 'lodash', - umd: 'lodash', - }, - '@emotion/react': { - root: ['NetlifyCmsDefaultExports', 'EmotionCore'], - commonjs2: '@emotion/react', - commonjs: '@emotion/react', - amd: '@emotion/react', - umd: '@emotion/react', - }, - '@emotion/styled': { - root: ['NetlifyCmsDefaultExports', 'EmotionStyled'], - commonjs2: '@emotion/styled', - commonjs: '@emotion/styled', - amd: '@emotion/styled', - umd: '@emotion/styled', - }, - codemirror: { - root: 'CodeMirror', - commonjs2: 'codemirror', - commonjs: 'codemirror', - amd: 'codemirror', - umd: 'codemirror', - }, - immutable: { - root: ['NetlifyCmsDefaultExports', 'Immutable'], - commonjs2: 'immutable', - commonjs: 'immutable', - amd: 'immutable', - umd: 'immutable', - }, - moment: { - root: ['NetlifyCmsDefaultExports', 'Moment'], - commonjs2: 'moment', - commonjs: 'moment', - amd: 'moment', - umd: 'moment', - }, - 'prop-types': { - root: ['NetlifyCmsDefaultExports', 'PropTypes'], - commonjs2: 'prop-types', - commonjs: 'prop-types', - amd: 'prop-types', - umd: 'prop-types', - }, - 'react-immutable-proptypes': { - root: ['NetlifyCmsDefaultExports', 'ImmutablePropTypes'], - commonjs2: 'react-immutable-proptypes', - commonjs: 'react-immutable-proptypes', - amd: 'react-immutable-proptypes', - umd: 'react-immutable-proptypes', - }, - react: { - root: 'React', - commonjs2: 'react', - commonjs: 'react', - amd: 'react', - umd: 'react', - }, - 'react-dom': { - root: 'ReactDOM', - commonjs2: 'react-dom', - commonjs: 'react-dom', - amd: 'react-dom', - umd: 'react-dom', - }, - uuid: { - root: ['NetlifyCmsDefaultExports', 'UUId'], - commonjs2: 'uuid', - commonjs: 'uuid', - amd: 'uuid', - umd: 'uuid', - }, - }, }; diff --git a/scripts/webpack.js b/scripts/webpack.js index b2acfed8..d11b6ab0 100644 --- a/scripts/webpack.js +++ b/scripts/webpack.js @@ -3,7 +3,7 @@ const webpack = require('webpack'); const FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin'); const { flatMap } = require('lodash'); -const { toGlobalName, externals } = require('./externals'); +const { toGlobalName } = require('./externals'); const pkg = require(path.join(process.cwd(), 'package.json')); const isProduction = process.env.NODE_ENV === 'production'; @@ -28,16 +28,27 @@ function rules() { css: () => [ { test: /\.css$/, - include: ['ol', 'redux-notifications', 'react-datetime', 'codemirror'].map( - moduleNameToPath, - ), + include: ['ol', 'react-datetime', 'codemirror'].map(moduleNameToPath), use: ['to-string-loader', 'css-loader'], }, ], svg: () => ({ test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, exclude: [/node_modules/], - use: 'svg-inline-loader', + use: [ + { + loader: 'babel-loader', + options: { + rootMode: 'upward', + }, + }, + { + loader: 'react-svg-loader', + options: { + jsx: true, // true outputs JSX tags + }, + }, + ], }), }; } @@ -75,7 +86,7 @@ const umdDirPath = path.resolve(process.cwd(), 'dist/umd'); const cjsPath = path.resolve(process.cwd(), 'dist/cjs'); function targetOutputs() { - console.log(`Building [${pkg.name}, library: ${toGlobalName(pkg.name)}]`); + console.info(`Building [${pkg.name}, library: ${toGlobalName(pkg.name)}]`); return { umd: { path: umdPath, @@ -104,12 +115,6 @@ function targetOutputs() { }; } -const umdExternals = Object.keys(pkg.peerDependencies || {}).reduce((previous, key) => { - if (!externals[key]) throw `Missing external [${key}]`; - previous[key] = externals[key] || null; - return previous; -}, {}); - /** * Use [getConfig({ target:'umd' }), getConfig({ target:'cjs' })] for * getting multiple configs and add the new output in targetOutputs if needed. @@ -125,30 +130,15 @@ function baseConfig({ target = isProduction ? 'umd' : 'umddir' } = {}) { rules: flatMap(Object.values(rules()), rule => rule()), }, resolve: { - extensions: ['.ts', '.tsx', '.js', '.json'], + extensions: ['.ts', '.tsx', '.js', '.jsx', '.json'], alias: { moment$: 'moment/moment.js', + 'react-dom': '@hot-loader/react-dom', }, }, plugins: Object.values(plugins()).map(plugin => plugin()), devtool: isTest ? '' : 'source-map', target: 'web', - - /** - * Exclude peer dependencies from package bundles. - */ - externals: - target.slice(0, 3) === 'umd' - ? umdExternals - : (context, request, cb) => { - const externals = Object.keys(pkg.peerDependencies || {}); - - function isPeerDep(dep) { - return new RegExp(`^${dep}($|/)`).test(request); - } - - return externals.some(isPeerDep) ? cb(null, request) : cb(); - }, stats: stats(), }; } diff --git a/tsconfig.json b/tsconfig.json index dfd00ad2..f54b973a 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -16,13 +16,9 @@ "noUnusedParameters": true, "baseUrl": "./", "paths": { - "netlify-cms-backend-github": ["packages/netlify-cms-backend-github/src"], - "netlify-cms-backend-gitlab": ["packages/netlify-cms-backend-gitlab/src"], - "netlify-cms-backend-bitbucket": ["packages/netlify-cms-backend-bitbucket/src"], - "netlify-cms-lib-util": ["packages/netlify-cms-lib-util/src"], - "netlify-cms-lib-widgets": ["packages/netlify-cms-lib-widgets/src"] + "netlify-cms-core": ["./packages/netlify-cms-core/src"] } }, - "include": ["**/src/**/*"], + "include": ["**/src/**/*", "dev-test/index.js"], "exclude": ["node_modules", "**/*.spec.ts"] } diff --git a/website/.babelrc b/website/.babelrc deleted file mode 100644 index 131352d3..00000000 --- a/website/.babelrc +++ /dev/null @@ -1,14 +0,0 @@ -{ - "presets": ["babel-preset-gatsby"], - "plugins": [ - [ - "prismjs", - { - "languages": ["javascript", "css", "markup", "yaml", "json"], - "plugins": ["line-numbers"], - "theme": "tomorrow", - "css": true - } - ] - ] -} diff --git a/website/.gitignore b/website/.gitignore deleted file mode 100644 index 0174e7b8..00000000 --- a/website/.gitignore +++ /dev/null @@ -1,3 +0,0 @@ -.cache -public -dist diff --git a/website/.markdownlint.json b/website/.markdownlint.json deleted file mode 100644 index 77811aa6..00000000 --- a/website/.markdownlint.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "default": false, - "MD032": true -} diff --git a/website/.nvmrc b/website/.nvmrc deleted file mode 100644 index cbe86a23..00000000 --- a/website/.nvmrc +++ /dev/null @@ -1 +0,0 @@ ---lts diff --git a/website/README.md b/website/README.md deleted file mode 100755 index e3e89443..00000000 --- a/website/README.md +++ /dev/null @@ -1,19 +0,0 @@ -# Netlify CMS Website & Docs - -This directory builds netlifycms.org. If you'd like to propose changes to the site or docs, you'll find the source files in here. - -## Local development - -The site is built with [GatsbyJS](https://gatsbyjs.org/). - -To run the site locally, you'll need to have [Node](https://nodejs.org) and [Yarn](https://yarnpkg.com/en/) installed on your computer. - -From your terminal window, `cd` into the `website` directory of the repo, and run - -```bash -yarn -yarn start -``` - -Then visit http://localhost:8000/ - Gatsby will automatically reload CSS or -refresh the page when stylesheets or content changes. diff --git a/website/content/.keep b/website/content/.keep deleted file mode 100755 index e69de29b..00000000 diff --git a/website/content/blog/deploy-preview-links.md b/website/content/blog/deploy-preview-links.md deleted file mode 100644 index 8c46718d..00000000 --- a/website/content/blog/deploy-preview-links.md +++ /dev/null @@ -1,66 +0,0 @@ ---- -title: Deploy Preview Links -author: Shawn Erquhart -description: >- - Deploy preview links from your GitHub repository are now surfaced in Netlify - CMS for previewing builds of unpublished content. -twitter_image: /img/preview-link-unpublished.png -date: 2019-02-08T19:30:00.000Z ---- -Netlify CMS 2.4.0 brings deploy preview links! - -![Deploy preview link for unpublished content](/img/preview-link-unpublished.png) - -## Seeing is believing - -The editorial workflow allows editors to create draft content in Netlify CMS, and Netlify can -provide deploy previews of draft content, but there hasn't been a way to access links to these -preview builds from within Netlify CMS. The preview pane in the editor is a good tool for seeing how -content will look on the site, but in the words of Marvin Gaye, "ain't nothing like the real thing!" -As Mr. Gaye bemoaned the absence of his beloved, so content creators long for the warm embrace of an -actual production build. Their words, not ours. - -## Solution: GitHub Statuses - -![GitHub statuses](/img/github-statuses-deploy-previews.png) - -For sites using the GitHub (or Git Gateway with GitHub) backend, we now have deploy preview links in -the CMS using the [GitHub Statuses -API](https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref). -Many static sites already have continuous deployment and deploy previews configured on their repo, -and they often use statuses to provide a link to a deployment directly from a commit or pull -request. To retrieve a commit status that provides a deploy preview URL, we check for a status whose -"context" contains one of a list of keywords commonly associated with deploy previews. - -If a status is not found, nothing happens in the UI. If a status is found, but the deploy preview -isn't ready, we provide a "Check for Preview" link, allowing the content editor to manually check -back until the preview is ready: - -![Deploy preview link for unpublished content](/img/preview-link-check.png) - -When the preview is ready, the "Check for Preview" button is replaced with a link to the content: - -![Deploy preview link for unpublished content](/img/preview-link-unpublished.png) - -## Deep links -Deploy preview links generally direct to the root of a site, but Netlify CMS can also link straight -to the piece of content being edited. By [providing a string template](/docs/deploy-preview-links) -for each collection, you can get links that go right where editors expect them to. More complex -URL's can be constructed [using date -information](/docs/deploy-preview-links/#dates-in-preview-paths) from your content files. - -## Unpublished vs. published -If you're not using the editorial workflow, you may not feel you need this very much. Whenever you -save content, it's immediatlely published, so you can navigate to your live site to see the changes. -That said, it's at least convenient to have a link direct to your content from the CMS, so deploy -preview links can also work for CMS installs that do not use the editorial workflow. Instead of -retrieving a URL from a commit status, this functionality requires setting a `site_url` in your -config, and that URL is used in place of the deploy preview URL. - -## GitLab and Bitbucket -Support is coming soon for these two awesome backends! Stay tuned. - -## Try it out! -Deploy preview links are live in Netlify CMS 2.4.0. Please give them a try and let us know if you -have any problems by [opening an issue](https://github.com/netlify/netlify-cms/issues/new) or -reaching out in our [community chat](https://netlifycms.org/chat)! diff --git a/website/content/blog/implementing-a-jekyll-cms-in-3-days.md b/website/content/blog/implementing-a-jekyll-cms-in-3-days.md deleted file mode 100644 index 9ed1d004..00000000 --- a/website/content/blog/implementing-a-jekyll-cms-in-3-days.md +++ /dev/null @@ -1,453 +0,0 @@ ---- -title: Implementing a Jekyll CMS in 3 Days -author: Shea Daniels -description: >- - Monetery, Dwolla's annual tech summit, needed flexibility after building a new - website. Using Netlify CMS they added content management to a Jekyll site in - three days. -twitter_image: /img/netlify-cms.png -date: 2019-06-06T12:00:00.000Z -canonical_url: https://www.dwolla.com/updates/implementing-netlify-cms/ ---- - -*This guest post was written by Shea Daniels, Lead Software Engineer at [Dwolla](https://www.dwolla.com) and user of Netlify CMS. It was originally published on the [Dwolla blog](https://www.dwolla.com/updates/implementing-netlify-cms/).* - ---- -
    - -[![Screenshot of the Monetery Conference website](https://cdn.dwolla.com/com/prod/20190606103416/Screen-Shot-2019-06-06-at-10.33.31-AM.png)](https://monetery.com) - -
    - -Let’s say you’re building the next great startup or putting together a spectacular event—the first question anybody asks you is “What’s the website?” - -A beautiful and usable online presence is simply table stakes in 2019 for businesses, nonprofits or even prospective employees—and it was no different for [Monetery](https://monetery.com/), the inclusive tech summit Dwolla puts on each spring. We needed to get a great site up and running fast, so we initially landed on a reliable and proven solution that we’ve used before: [GitHub Pages](https://pages.github.com/). - -This worked well early on as we launched the Monetery homepage, but it became clear that we needed a more complete solution. Because of our robust controls process, engineering was quickly becoming a roadblock. We needed to do a better job of enabling our content editors to move fast and make necessary changes quickly. - -So we took a look at our options: -1. Implement a traditional Content Management System (CMS) like WordPress -2. Find a Headless CMS to integrate into a Static Site Generator (SSG) - -The landscape of potential products for both of these options is monumental. We were familiar with traditional options, so we scoured [headlesscms.org](https://headlesscms.org/) and [staticgen.com](https://www.staticgen.com) to see what else was out there. Dwolla affords its engineering staff with dedicated time for professional development each week, which gave us an opportunity to test drive potential solutions. - -One of the most interesting solutions we tried came from a company called [Netlify](https://www.netlify.com/), and their project [Netlify CMS](https://www.netlifycms.org/). - -We thought Netlify CMS might benefit us for the following reasons: -- It’s built for use with Static Site Generators so we get to keep the speed, security and scalability benefits that drew us to SSGs in the first place -- It’s SSG agnostic, so it would work with our existing [Jekyll](https://jekyllrb.com/) site but not prevent us from changing our mind down the road (hi there, [GatsbyJS](https://www.gatsbyjs.org/)!) -- There is no database backend since content changes are stored as Git commits - which makes [InfoSec](https://www.dwolla.com/security/) folks happy -- It provides a simple and usable editor experience -- It’s open source, so there is no vendor lock-in, and we can contribute features that are important to us back to the community - -With buy-in from our stakeholders, we decided to move forward. We’ll talk about the decisions we had to make and show you how to integrate Netlify CMS with Jekyll on your own site. - -## Should you move from GitHub Pages to Netlify Hosting? - -This was the first choice we needed to make. Switching seemed like it would add additional time and complexity to our project, and thus initially our decision was “no.” Using Netlify CMS with your existing hosting provider is a perfectly valid choice. - -So why did we change our mind and move to Netlify hosting? The answer is that we found two features very compelling: [Git Gateway](https://www.netlify.com/docs/git-gateway/) and [branch deploys](https://www.netlify.com/docs/continuous-deployment/#branches-deploys). - -Git Gateway works as an intermediary between the CMS and your Git repository. In concrete terms, this means you can do things like have your users log into the CMS admin with Google instead of requiring them to each have a GitHub account. Netlify then makes commits on your behalf using a GitHub account that granted access to a repo via OAuth. Although the Git Gateway is [open source](https://github.com/netlify/git-gateway) software as well, it was clear that learning to host that ourselves was going to involve a considerable learning curve. - -Branch deploys give you the ability to have more than one version of your site live at a time. In comparison, GitHub Pages has a serious limitation in that only a single branch (usually master or gh-pages) can be deployed. This may not sound particularly exciting, but it enables a wonderful feature that we’ll get back to in a bit. - -## Migrating from GitHub Pages to Netlify - -In general, publishing your site from Netlify is as easy as creating a Netlify account, signing in to your Git provider (GitHub, GitLab or Bitbucket) and selecting a repo. As soon as you provide a build command, Netlify can start deploying your site. Tasks like setting up SSL are explained by the [Netlify Docs](https://www.netlify.com/docs/) so we won’t cover that here. - -If you were using the built-in Jekyll gems and build process that GitHub provided, you’ll need a few additional things to get the build working. You’ll need a Gemfile for your dependencies, and it’s also a good idea to check your build command into source control as well: - -
    -
    Gemfile
    - - ```bash - source "https://rubygems.org" - gem 'github-pages' - ``` -
    - -
    -
    netlify.toml
    - - ```bash - [build] - publish = "_site/" - command = "jekyll build" - ``` -
    - -Once you’re satisfied that everything looks good and is deploying correctly from Netlify, you can proceed to claim your domain name on Netlify and migrate DNS over to Netlify’s name servers. After your DNS is fully cut over, you can safely turn off the GitHub Pages site from your repo. - -## Adding Netlify CMS to an Existing Site - -Netlify CMS itself consists of a [Single Page Application](https://en.wikipedia.org/wiki/Single-page_application) built with [React](https://reactjs.org/) that lives in an admin folder on your site. For Jekyll, it goes right at the root of your project. It will contain two files: - -```bash -admin - ├ index.html - └ config.yml -``` - -The [Netlify CMS Docs](https://www.netlifycms.org/docs/add-to-your-site/) explain this better than we can: - -> The first file, `admin/index.html`, is the entry point for the Netlify CMS admin interface. This means that users navigate to `yoursite.com/admin/` to access it. On the code side, it's a basic HTML starter page that loads the Netlify CMS JavaScript file. In this example, we pull the file from a public CDN: - -
    -
    admin/index.html
    - - ```html - - - - - - Content Manager - - - - - - - - - ``` -
    - -> The second file, `admin/config.yml`, is the heart of your Netlify CMS installation, and a bit more complex. The [Configuration](https://www.netlifycms.org/docs/add-to-your-site/#configuration) section covers the details. - -To start with, the config file might look something like this: - -
    -
    admin/config.yml
    - - ```yaml - backend: - name: git-gateway - branch: master - identity_url: "https://yoursite.com/.netlify/identity" - gateway_url: "https://yoursite.com/.netlify/git" - squash_merges: true - - publish_mode: editorial_workflow - media_folder: "assets/img/uploads" - - site_url: https://yoursite.com - logo_url: https://yoursite.com/assets/img/logo.svg - - collections: - ``` -
    - -The `backend` section covers the basics like which branch to update and sets up the Git Gateway connection that we talked about earlier. The `publish_mode` property sets up our workflow to use the [editorial](https://www.netlifycms.org/docs/add-to-your-site/#editorial-workflow) mode. In short, this means that we have the ability to save page drafts as pull requests in Git before we decide to publish them. Combined with the branch deploys feature of Netlify, this is going to give us live previews of unpublished content from a static site generator! - -*Note: as of May 2019, the editorial workflow is only supported when you use GitHub as a provider* - -Now we just need to drop in the Netlify Identity Widget on the main site. This is needed because after a user logs in they’ll be redirected to the homepage of the site. We need to redirect them back to the CMS admin, so add the following script before the closing body tag: - -```js - -``` - -With this in place, and the appropriate authentication and Git Gateway configuration on netlify.com, you should be able to log into the Netlify CMS admin for your site at `https://yourdomain.com/admin`. - -### What are Collections? - -Although at this point you can log in, you can’t do much yet! There is no data structure set up for the CMS fields you’ll need to edit your site. You may have noticed the empty `collections` field in the config file, and this is where the magic happens. All fields for data that you want to save need to be part of a collection. - -There are two [types of collections](https://www.netlifycms.org/docs/collection-types/), folder collections and file collections. To understand the difference, let’s figure out what Netlify CMS actually does when you make a content edit: the data has to be stored somewhere and we know that it uses Git as a back end. That means the data you save must end up inside of a file in your project. So when we configure a collection, we are telling Netlify CMS about the structure and naming convention of the files we want to create. It’s then up to your static site generator to determine how to interpret these files and pull the data into templates. In this blog post, we’ll cover how that works for Jekyll. - -Knowing this, can you guess why there are two types of collections? In the case of defined options, we can tell the CMS to put that field in a specific file in our project. In the case of repeating content, like blog posts or pages built out of modular components, we want to set up Netlify CMS so that it can generate many files based on a pattern that we define. We can generate a number of different file formats too - it supports YAML, JSON, markdown with [front matter](https://jekyllrb.com/docs/front-matter/), and a few others. - -### Setting Up a File Collection for Global Options - -A file collection is the perfect place to define data fields for things that are valid across your entire site, such as global navigation, footers, and defaults. Let’s look at a file collection from a real config file: - -
    -
    admin/config.yml
    - - ```yaml - collections: - - label: "Sitewide Options" - name: options - editor: - preview: false - files: - - label: "Navigation Menu" - name: nav - file: "_data/nav.yml" - fields: - - label: "Nav Items" - label_singular: "Nav Item" - name: topLevelItems - widget: list - fields: - - {label: "Display Text", name: displayText, widget: string} - - {label: URL, name: url, widget: string} - - label: "Item Type" - name: itemType - widget: select - options: ["Link", "Button"] - ``` -
    - -This will define a new collection that shows up on left side of the CMS admin UI, and it will make a “Navigation Menu” page underneath that collection. Inside are fields that define some site navigation items that each include a name, URL, etc. We define the data type and editor interface of the fields using [widgets](https://www.netlifycms.org/docs/widgets/). When a change is made, it will be saved to the file located at `_data/nav.yml` in your project. - -![Screenshot of a page in the Netlify CMS admin interface](https://cdn.dwolla.com/com/prod/20190529161537/Screen-Shot-2019-05-29-at-4.14.23-PM.png) - -Here’s an example of what the data file might look like: - -
    -
    _data/nav.yml
    - - ```yaml - topLevelItems: - - displayText: 'A Page' - itemType: Link - url: /a-page/ - - displayText: 'External Link' - itemType: Link - url: '/https://google.com' - ``` -
    - -### How to Use a File Collection in Jekyll - -Let’s figure out how to pull this data into a template in Jekyll. Here’s a simple liquid template that uses our nav data: - -```liquid -
      - {% for item in site.data.nav.topLevelItems %} -
    • - {% if item.itemType == 'Link' %} - {{ item.displayText }} - {% else %} - ... - {% endif %} -
    • - {% endfor %} -
    -``` - -In Jekyll, everything in the `_data` folder is available using the `site.data.{file}.{field}` syntax. You can loop and get fields as you would expect. - -### Setting Up a Folder Collection for Pages - -A folder collection is used any time we need a number of files to be generated according to a pattern, but we don’t know how many. For example, if you’re building a blog, this is what you need for your posts. In this example, we’ll use it with a cool Jekyll feature to let content editors create the pages of our site on the fly and at any path they want. - -Let’s look at the bones of a folder collection from a real config file to see how this works: - -
    -
    admin/config.yml
    - - ```yaml - collections: - - label: "Pages" - label_singular: "Page" - name: pages - folder: "_pages" - create: true - slug: "{{slug}}" - preview_path: "{{permalink}}" - editor: - preview: false - fields: - - {label: "Title", name: title, widget: string} - - {label: "Permalink", name: permalink, widget: string} - - label: "Layout Template" - name: "layout" - widget: "select" - default: "blocks" - options: - - { label: "Default", value: "blocks" } - - { label: "Home Page", value: "home" } - - {label: "Meta Description", name: metaDescription, widget: text, required: false} - - label: "Social Sharing" - name: social - widget: object - required: false - fields: - - {label: "OpenGraph Image", name: ogImage, widget: image, required: false} - - {label: "Twitter Image", name: twitterImage, widget: image, required: false} - ``` -
    - -This defines another new collection called “Pages” that will consist of many files all stored in the `/_pages/` folder of your project. The files will be named according to the pattern in the slug field, which we’ve confusingly set to have a pattern of `{{slug}}`. Don’t worry, in this case it just means we’ll be using the default value, which is the contents of the `title` field. You can configure this in many ways to include dates and other things to match your intended use, but this is perfect for our case. - -![Screenshot of the Pages collections in Netlify CMS admin](https://cdn.dwolla.com/com/prod/20190529161807/Screen-Shot-2019-05-29-at-4.17.02-PM.png) - -Of special note are the `permalink` and `preview_path` fields. We’ll use the permalink field to define the path of our page in Jekyll, and the preview field shares that definition with Netlify CMS so it knows how to link to the correct page preview (branch deploys FTW). - -Here’s an example of what the data file for a page might look like: - -
    -
    _pages/home.md
    - - ```liquid - --- - Title: Home - permalink: / - layout: home - metaDescription: Shout out what you’re about! - social: {} - --- - ``` -
    - -### How to Use a Folder Collection in Jekyll - -If you were reading closely, you may have noticed that the file collection is generating YAML files, while the folder collection is generating markdown files with front matter. You might think that’s a bit odd to have a markdown file with no content below the data in the front matter (demarcated by the triple dashes), but rest assured there’s a good reason! - -We’ll work in concert with Jekyll’s own [collections feature](https://jekyllrb.com/docs/collections/) to pair our markdown files with a template, read the data in the front matter and then use it to generate our page output. This lets us do neato things later like use the [variable type list widget](https://www.netlifycms.org/docs/beta-features/#list-widget-variable-types) to make a component based page builder! - -Before we start, we need to make an addition to the Jekyll config file: - -
    -
    _config.yml
    - - ```yaml - collections: - pages: - output: true - ``` -
    - -This tells Jekyll to generate a new page for each markdown file in the `pages` folder. - -But how does Jekyll know which template to use? In this case, the `layout` field we defined in Netlify CMS is doing exactly that. Jekyll maps the value in that front matter field directly to the name of a template file in the `_layouts` folder of your project. - -Let’s look at an example layout template: - -
    -
    _layouts/home.html
    - - ```liquid - --- - layout: default - --- - -

    {{ page.title }}

    - -
    - {{ content }} -
    - ``` -
    - -All of the data we are interested in from the front matter is available using the `{collection}.{field}` syntax that Jekyll provides. We’re able to use parent templates and all of the other features as you’d expect. - -### Making a Page Builder in Jekyll - -We’re off to a great start, but we didn’t need to go to all that trouble with our folder collection if we weren’t going to take it one step farther: let’s make a flexible, component-based page builder! - -First, we need to define our components in the Netlify CMS config file: - -
    -
    _admin/config.yml
    - - ```yaml - collections: - - label: "Pages" - ... - - label: "Content Blocks" - label_singular: "Content Block" - name: blocks - widget: list - types: - - label: "Hero" - name: hero - widget: object - fields: - - {label: "Heading", name: heading, widget: string} - - {label: "Content", name: content, widget: markdown, buttons: ["bold", "italic", "link"], required: false} - - label: "Rich Text Block" - name: textBlock - widget: object - fields: - - {label: "Heading", name: heading, widget: string, required: false} - - {label: "Content", name: content, widget: markdown} - ... - ``` - -
    - -Here we’ve extended our pages collection to include a variable type list widget that contains several different types of objects that the content editor will be able to dynamically add and rearrange from the CMS Admin. - -![Screenshot of a page builder in Netlify CMS admin](https://cdn.dwolla.com/com/prod/20190529162003/Screen-Shot-2019-05-29-at-4.19.06-PM.png) - -Now let’s make a new layout to render our widgets: - -
    -
    _layouts/blocks.html
    - - ```liquid - --- - layout: default - --- - - {% for block in page.blocks %} - {% include blocks/{{ block.type }}.html block=block %} - {% endfor %} - ``` -
    - -Here we’re looping through each component on the page, and including another template file that knows how to render it. Here’s what a component template might look like: - -
    -
    _includes/blocks/hero.html
    - - ```liquid -
    -

    {{ block.heading }}

    - {% if block.content and block.content != '' %} -
    - {{ block.content | markdownify }} -
    - {% endif %} -
    - ``` -
    - -Because we passed along our block variable, everything is right where we need it. You’ll also notice we took special care to translate our markdown into HTML with markdownify since that isn’t being automatically done for us any more. - -## Our Experience with Netlify + Netlify CMS - -Using these techniques, our engineers were able to integrate Netlify CMS into our existing Jekyll site for [Monetery](https://monetery.com/) and launch a working CMS within a matter of days (three, to be exact). Content editors were able to onboard quickly and start publishing changes and new pages shortly after launch. During that time we also onboarded a new engineer who was able to start making meaningful contributions on their second day of work! - - -That said, [we’re never done](https://www.dwolla.com/about/core-beliefs/). We’re constantly learning from our experiences and trying to improve. Let’s take a balanced look at both the pros and cons of using Netlify + Netlify CMS: - -### Pros -- Hosting on Netlify is a breeze and we haven’t experienced any issues with the site itself -- Netlify CMS was very easy to retrofit onto an existing Jekyll project and intuitive for new engineers to learn -- It’s easy and very useful to get a copy of your entire project, including content, and run it locally using docker< -- The Netlify CMS interface is simple and easy to learn for content editors -- Branch deploys and previews are amazing -- Netlify’s free plans give you the freedom to evaluate the offering before committing -- There is an active and very helpful [community chat](https://netlifycms.org/chat) for Netlify CMS -- Netlify CMS is open source and welcomes contributions - -### Cons -- Our content editors like the editorial workflow but don’t like the multiple steps to save and publish -- Saving and publishing is relatively slow, sometimes up to a few seconds -- We experience occasional—but frustrating—errors when using the CMS admin -- Some widgets or functionality that you might be looking for, such as conditional logic for displaying fields in the admin UI, hasn’t been implemented yet -- The CMS UI doesn’t work to save content to your machine during local development, it will always commit back to your Git repository, so be careful -- You are better off hosting with Netlify instead of another provider if you want features like branch deploys and a hosted Git Gateway - this may incur more cost to your business - -## The Community & Contributing Back - -The Netlify CMS community has been nothing short of wonderful to interact with, so we encourage you to reach out and give this technology a try. Dwolla also believes in linking our words with our actions, so we’re committed to giving back to the open source community. We’re happy to report that our first pull request contributing to Netlify CMS is already live! - - -Check out the code on GitHub: https://github.com/netlify/netlify-cms diff --git a/website/content/blog/netlify-cms-2-0-launches-with-bitbucket-support-and-a-new-monorepo-architecture.md b/website/content/blog/netlify-cms-2-0-launches-with-bitbucket-support-and-a-new-monorepo-architecture.md deleted file mode 100644 index 095e522b..00000000 --- a/website/content/blog/netlify-cms-2-0-launches-with-bitbucket-support-and-a-new-monorepo-architecture.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: >- - Netlify CMS 2.0 launches with Bitbucket support and a new monorepo - architecture -author: Phil Hawksworth -description: >- - Announcing the release of Netlify CMS v2.0, with new Bitbucket support and an - improved project architecture designed to ease contribution and the extension - of features. -date: 2018-07-26T12:00:00.000Z ---- -Today we’re releasing Netlify CMS 2.0, which adds support for using Bitbucket as a backend. - -With this release, Netlify CMS now supports all major Git collaboration providers, adding Bitbucket to the list of supported providers which already includes GitLab and GitHub. - -While you could already use Netlify CMS with most static site generators, our long-term vision is to be tool-agnostic so you can use whatever tool helps you work best. The latest release brings us one step closer by giving the option of an open source, Git-centric CMS to tens of thousands of businesses that depend on Bitbucket, including 60 of the Fortune 100. - -## Becoming a Monorepo - -The other big change with 2.0 is the migration from a single codebase to a collection of interdependent packages called a “monorepo”. Netlify CMS still lives in a [single repository on GitHub](https://github.com/netlify/netlify-cms), but the many extensions that were kept within Netlify CMS itself are now completely separate from the application core. This brings a few benefits: - -* Extension authors can easily copy an existing extension from the Netlify CMS repo and create a custom version. -* Your custom extensions can now do anything the “official” extensions can do (because official extensions are no longer taking advantage of privileged internal code). -* The monorepo approach provides a foundation that will encourage a more modular CMS, with shared parts that make extension authoring easier. - -## What’s next - -Upcoming feature releases will bring new image handling features and a number of improved APIs, adding even more possibilities to future CMS extensions. - -We’re always looking for more ideas and helping hands, so if you want to help build a smarter, safer, and more scalable CMS, we’d love your [contributions](/docs/contributor-guide/). Give us a shout on [Twitter](https://twitter.com/netlifycms) or in our [community chat](/chat) if you have questions or ideas. diff --git a/website/content/blog/netlify-cms-2-1-0-adds-external-media-support-with-uploadcare.md b/website/content/blog/netlify-cms-2-1-0-adds-external-media-support-with-uploadcare.md deleted file mode 100644 index 82c9156e..00000000 --- a/website/content/blog/netlify-cms-2-1-0-adds-external-media-support-with-uploadcare.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -title: Netlify CMS 2.1.0 adds external media support with Uploadcare -author: Shawn Erquhart -description: >- - Netlify CMS 2.1.0 adds external media support with Uploadcare, allowing files - like images and videos to be stored outside of your Git repository. -date: 2018-09-05T20:52:30.334Z -twitter_image: /img/netlify-cms-external-media-library.png ---- -Storing large files in Git works great if you only have a few, and uploading plain images is fine if that's all your site needs. For everything else, great services like Cloudinary, Filestack, and Uploadcare exist to help you optimize and store images and other media files separately from the rest of your site. Our users have long been asking for a way to work with these kinds of services from within Netlify CMS, and we're happy to say that our latest release makes it possible! - -Feast your eyes 😻 - -![Netlify CMS with external media library overlay](/img/netlify-cms-external-media-library.png) - -## How it works: BYOUI (Bring Your Own UI) - -Some services, like the ones mentioned above, provide portable interfaces that you can load into any website, like Uploadcare's [Widget](https://uploadcare.com/features/widget/), Cloudinary's [Media Library](https://cloudinary.com/documentation/media_library_widget), and Filestack's [Web Picker](https://www.filestack.com/docs/concepts/pickers/#web-picker). These libraries are generally created by the same folks that make the services, and are meant to optimally expose the unique functionality of each platform. As a bonus, the software is kept up to date with the service API's without our involvement. - -Since we don't have to create the UI, the actual integration with Netlify CMS can be quite small, being mostly focused on showing/hiding the media interface and retrieving the URL's for any images selected. - -## First Integration: Uploadcare - -
    - -![Uploadcare logo](/img/uc-logo-horizontal.svg) - -
    - -Uploadcare came up on our radar when they built a Netlify CMS integration for their service in response to customer requests - before we made it possible, and without our assistance. They did quite a lot of work, and the result helped to show that using an external interface with Netlify CMS could work really well. Their effort also helped us form the new not-yet-public API that Netlify CMS now uses to work with external media libraries. - -We're super excited to honor Uploadcare's love for Netlify CMS by launching external media handling with their service as the first integration! - -## Get started today! - -Here's how to start externalizing your media with Netlify CMS and Uploadcare: - -1. Make sure you've [upgraded Netlify CMS](/docs/update-the-cms-version/) to at least 2.1.0. -2. Head over to Uploadcare, sign up, and get your API key ([more info](https://uploadcare.com/docs/keys/)) -3. Remove the `media_folder` property from your CMS configuration file. -4. Add the following to your CMS configuration file: - ```yaml - media_library: - name: uploadcare - config: - publicKey: demopublickey # replace with your publickey, or use this just to test - ``` - -That's it! Check out [our docs](/docs/uploadcare/) for full details. - -## Next up - -As mentioned previously, we have more amazing providers coming soon! (Looking at you, Cloudinary 😻) - -We'll also be finalizing and documenting the media library integration API so developers can build their own integrations for services that aren't on our radar. S3 anybody? - -Questions or comments? Reach out in our [community chat](https://netlifycms.org/chat). diff --git a/website/content/blog/netlify-cms-2-4-0.md b/website/content/blog/netlify-cms-2-4-0.md deleted file mode 100644 index 1c5ffc25..00000000 --- a/website/content/blog/netlify-cms-2-4-0.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Netlify CMS 2.4.0 -author: Shawn Erquhart -description: >- - Netlify CMS 2.4.0 is out with Deploy Preview Links, a new Map widget, and - more! -twitter_image: /img/preview-link-published.png -date: 2019-02-08T23:00:58.501Z ---- -Netlify CMS 2.4.0 is out with significant bugfixes, like working validation for nested fields, and some nice new features, including [Deploy Preview Links](https://www.netlifycms.org/blog/2019/02/deploy-preview-links) and a new [Map widget](https://www.netlifycms.org/docs/widgets/#map)! - -## Release Notes - - -### Features -* `loadEntry` method now available to widgets ([@leonardodino](https://github.com/leonardodino) in [#2010](https://github.com/netlify/netlify-cms/pull/2010)) -* Loading `config.yml` can now be skipped ([@talves](https://github.com/talves) in [#2053](https://github.com/netlify/netlify-cms/pull/2053)) -* Map widget ([@friedjoff](https://github.com/friedjoff) in [#2051](https://github.com/netlify/netlify-cms/pull/2051) -* Deploy preview links ([@erquhart](https://github.com/erquhart) in [#2028](https://github.com/netlify/netlify-cms/pull/2028)) -* Number widget now offers range validation ([@lmcorreia](https://github.com/lmcorreia) in [#2049](https://github.com/netlify/netlify-cms/pull/2049)) - -### Bugfixes -* Markdown widget parsing improvements - leading/trailing whitespace ([@papandreou](https://github.com/papandreou) in [#1517](https://github.com/netlify/netlify-cms/pull/1517)) -* Relation widgets in a list no longer swap values after drag and drop ([@barthc](https://github.com/barthc) in [#2018](https://github.com/netlify/netlify-cms/pull/2018)) -* Defining custom frontmatter delimiters with an array works ([@daneden](https://github.com/daneden) in [#1997](https://github.com/netlify/netlify-cms/pull/1997)) -* Use label instead of value in select widget when using multiple select ([@selaux](https://github.com/selaux) in [#2054](https://github.com/netlify/netlify-cms/pull/2054) -* Field validation now works for nested fields (inside of object or list widget) ([@barthc](https://github.com/barthc) in [#1873](https://github.com/netlify/netlify-cms/pull/1873)) -* Fix preview reliability issue for relation widget ([@barthc](https://github.com/barthc) in [#2011](https://github.com/netlify/netlify-cms/pull/2011)) diff --git a/website/content/blog/netlify-cms-gatsby-plugin-4-0-0.md b/website/content/blog/netlify-cms-gatsby-plugin-4-0-0.md deleted file mode 100644 index c5602582..00000000 --- a/website/content/blog/netlify-cms-gatsby-plugin-4-0-0.md +++ /dev/null @@ -1,133 +0,0 @@ ---- -title: React Hooks support in Netlify CMS (and the Gatsby plugin) -author: Tony Alves -description: >- - Netlify CMS 2.9.0 allows React Hooks to be used in custom Netlify CMS previews and widgets, and `gatsby-plugin-netlify-cms` 4.0.0 extends that support to Gatsby projects. -date: 2019-07-23T00:00:10.000Z ---- - -Netlify CMS is an extensible app written in, and bundled with, React. The most common extension is the custom preview template, which allows the preview on the right side of the editor to show what the site will actually look like as you type. These preview templates are also written in React. - -Preview templates and other extensions can only use the Netlify CMS bundled copy of React via the `createClass()` method that Netlify CMS exports. Since React components are most often written in JSX and transpiled through a build system, most developers won't want to use this method, so the preview templates are created with a separate copy of React. - -**This means that Netlify CMS has two instances of React running at once.** - -But everything still worked - until React Hooks was released. - -## The problem: React Hooks -Before [Hooks](https://reactjs.org/docs/hooks-intro), multiple instances of React _could_ work on the same DOM, although it was warned against and technically not supported. React Hooks [changed this](https://reactjs.org/warnings/invalid-hook-call-warning#duplicate-react) by throwing an error if multiple instances are detected. When developers started using hooks in their Netlify CMS previews and widgets, their applications stopped working 😭 - -## The solution: `netlify-cms-app` -In the past, the `netlify-cms` npm package was the only way to run Netlify CMS - it's a "batteries included" distribution that runs as-is, bringing along React and a number of default extensions (widgets, backends, etc). - -As of Netlify CMS 2.9.0, a new `netlify-cms-app` package is provided as a slimmed down alternative to `netlify-cms`. It still includes most default extensions, but excludes some of the heavier ones, like media libraries for external providers. - -Most importantly, **it does not include `react` or `react-dom`**, requiring them instead as [peer dependencies](https://nodejs.org/es/blog/npm/peer-dependencies/). This allows Netlify CMS and any extensions to all use a single instance of React and React DOM. As a bonus, the `netlify-cms-app` bundle is a bit smaller than `netlify-cms`. - -## How to use it -**If you're building your site with Gatsby, skip this section.** For all others, you'll want to: - -1. Uninstall `netlify-cms` if you're already using it -2. Install `netlify-cms-app` -3. Install `react` and `react-dom` -4. Optionally install and register media libraries (see below). - -```bash -npm uninstall netlify-cms -npm install netlify-cms-app react react-dom -``` - -That's it! Now Netlify CMS will use the version of React that you provide. - -## The Gatsby plugin -Gatsby provides transpiling and bundling with Babel and Webpack, and accepts plugins to support various JavaScript dialects, e.g., TypeScript. If a developer sets up their Gatsby site to be written a certain way, they'll want any CMS customization code to be written the same way. The problem is that Netlify CMS is a standalone app that would typically live in Gatsby's `static` directory, and Gatsby doesn't really have a way to handle a secondary entry point for the CMS for outputting a dedicated bundle. - -For this reason, we support an official Gatsby plugin, [`gatsby-plugin-netlify-cms`](https://github.com/gatsbyjs/gatsby/tree/master/packages/gatsby-plugin-netlify-cms), which bundles preview templates and other Netlify CMS extensions using the same Babel and Webpack configuration as the Gatsby site itself. - -## Using React Hooks with Netlify CMS and Gatsby -The recent 4.0.0 release of `gatsby-plugin-netlify-cms` is the first to use `netlify-cms-app` and enable the use of React Hooks in Netlify CMS previews/widgets for Gatsby projects. - -If you want to start a new site now, or would like to see an example, check out [`gatsby-starter-netlify-cms`](https://github.com/netlify-templates/gatsby-starter-netlify-cms#gatsby--netlify-cms-starter) - it provides a great starting point and implements all of the remaining steps in this post. - -You can deploy it to Netlify right now with one click! - -[![Deploy to Netlify](https://www.netlify.com/img/deploy/button.svg)](https://app.netlify.com/start/deploy?repository=https://github.com/netlify-templates/gatsby-starter-netlify-cms&stack=cms) - -### Upgrading an existing project -If you're already using `gatsby-plugin-netlify-cms`, you'll want to: -1. Upgrade to 4.0.0 or newer -2. Remove the `netlify-cms` dependency -3. Add `netlify-cms-app` - -```bash -npm upgrade gatsby-plugin-netlify-cms@^4.0.0 -npm uninstall netlify-cms -npm install --save netlify-cms-app -``` - -Note that you'll already have React and React DOM installed in your Gatsby project, so no need to do that here. - -### Adding to a new project -If you're **not** already using `gatsby-plugin-netlify-cms` with your Gatsby project, you can install it and `netlify-cms-app` via npm (or your package manager of choice): - -```bash -npm install --save netlify-cms-app gatsby-plugin-netlify-cms -``` - -You'll also need to register the plugin in `gatsby-config.js` in the site root. Create that file if it’s not already there, and add the following to register the Netlify CMS plugin: - -```javascript -// gatsby-config.js - -module.exports = { - plugins: [`gatsby-plugin-netlify-cms`], -} -``` - -The plugin will create the Netlify CMS app and output it to `/admin/index.html` on your site. The CMS will look for your configuration to be in the same directory on your live site, at `/admin/config.yml`, so you’ll want to place the configuration file in the `static` directory of your repo at `static/admin/config.yml`. You can also [configure Netlify CMS with JavaScript](https://www.netlifycms.org/docs/beta-features/#manual-initialization). Read more about configuring the CMS in our docs, or check out the Gatsby / Netlify CMS integration guides in both our docs and theirs. - -- [Netlify CMS Configuration Guide](https://www.netlifycms.org/docs/add-to-your-site/#configuration) -- [Netlify CMS Integration Guide for Gatsby Sites](https://www.netlifycms.org/docs/gatsby/) -- [Gatsby Guide - Sourcing from Netlify CMS](https://www.gatsbyjs.org/docs/sourcing-from-netlify-cms/) - -## Using Media Libraries with `netlify-cms-app` -The Netlify CMS media library extensions for Cloudinary and Uploadcare are not included in `netlify-cms-app`. If you're using `netlify-cms-app`, you'll need to register media libraries yourself. - -**Note:** if you're using `gatsby-starter-netlify-cms`, the media libraries are registered within the starter itself. - -```javascript -import CMS from 'netlify-cms-app'; - -// You only need to import the media library that you'll use. We register both -// here for example purposes. -import uploadcare from 'netlify-cms-media-library-uploadcare'; -import cloudinary from 'netlify-cms-media-library-cloudinary'; - -CMS.registerMediaLibrary(uploadcare); -CMS.registerMediaLibrary(cloudinary); -``` - -For more information about the media libraries, refer to the docs. - -- [Using Cloudinary with Netlify CMS](https://www.netlifycms.org/docs/cloudinary/) -- [Using Uploadcare with Netlify CMS](https://www.netlifycms.org/docs/uploadcare/) - -### With `gatsby-plugin-netlify-cms@^4.0.0` -In addition to calling `registerMediaLibrary()` as mentioned above, make sure to provide the path to your CMS customization entry point to Gatsby via `gatsby-config.js`: - -```javascript -// gatsby-config.js - -module.exports = { - plugins: [ - { - resolve: 'gatsby-plugin-netlify-cms', - options: { - modulePath: `${__dirname}/src/cms/cms.js`, - }, - }, - ] -} -``` - -If you run into a problem or need help, [open an issue on GitHub](https://github.com/netlify/netlify-cms/issues/new/choose) or [chat with our community](https://netlifycms.org/chat)! diff --git a/website/content/blog/netlify-cms-now-supports-gitlab-as-a-backend.md b/website/content/blog/netlify-cms-now-supports-gitlab-as-a-backend.md deleted file mode 100644 index d60b65e8..00000000 --- a/website/content/blog/netlify-cms-now-supports-gitlab-as-a-backend.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -title: Netlify CMS now supports GitLab as a backend -author: Benaiah Mischenko -description: >- - Netlify CMS, the open source, headless CMS that provides a user-friendly UI - around your Git repository, can now be used with GitLab in addition to - GitHub. -date: 2018-06-13T00:00:10.000Z ---- -Netlify CMS is releasing support for GitLab as a backend, creating the world's first completely open source stack for Git-based content editing. - - - -We heard [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-383283557) (and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-355386542), and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-343569725), and [you](https://github.com/netlify/netlify-cms/pull/517#issuecomment-333629637))! While you want to use Netlify CMS as the headless content management system for your Jamstack projects, all of your code lives in GitLab. Our long-term vision is to be tool-agnostic so you can use whatever tool helps you work best. But while you can already use Netlify CMS with most static site generators, backend support was limited to GitHub. - -Immediately after the December release of Netlify CMS 1.0, contributors got to work on improving the API for backend integrations. At the urging of the community, we prioritized support for GitLab. With today’s release of Netlify CMS 1.9.0, you can now use GitLab as the backend for Netlify CMS. - -Adding support for GitLab means that millions more developers can now use Netlify CMS with their projects. Seriously — millions. GitLab is used by more than 100,000 organizations like Ticketmaster, Intel, Red Hat, and CERN. - -## How it works - -Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflow. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your GitLab repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git. - -In case you want an even easier way to get started, or just want to poke around in the code, you can use the button below to automatically deploy a starter site that uses the Hugo static site generator along with Netlify CMS. - -Deploy to Netlify - -Lastly, one particularly exciting thing about using GitLab as your backend is that it doesn’t require an authentication server. While the GitHub integration requires a hop to an authentication server (something Netlify provides for most users), GitLab’s implicit auth flow allows you to connect directly from your browser to gitlab.com, or even to your own self-hosted GitLab server! - -## What’s next - -We’re already working toward [Bitbucket](https://github.com/netlify/netlify-cms/pull/525) support and will be releasing it as soon as possible! We’re also focused on the upcoming release of [Netlify CMS 2.0](https://github.com/netlify/netlify-cms/issues/1280), which will bring new image handling features and improvements, and improved APIs for better CMS extensions. We’re also looking for more ideas and helping hands, so if you’re keen to build a smarter, safer, and more scalable CMS, we’d love your contributions. Give us a shout on [Twitter](https://twitter.com/netlifycms) or in [community chat](/chat) if you have questions or ideas. diff --git a/website/content/docs/add-to-your-site.md b/website/content/docs/add-to-your-site.md deleted file mode 100644 index 40068bc1..00000000 --- a/website/content/docs/add-to-your-site.md +++ /dev/null @@ -1,281 +0,0 @@ ---- -group: Intro -weight: 3 -title: Add to Your Site ---- -You can adapt Netlify CMS to a wide variety of projects. It works with any content written in markdown, JSON, YAML, or TOML files, stored in a repo on [GitHub](https://github.com/), [GitLab](https://about.gitlab.com/), or [Bitbucket](https://bitbucket.org). You can also create your own custom backend. - -This tutorial guides you through the steps for adding Netlify CMS to a site that's built with a common [static site generator](https://www.staticgen.com/), like Jekyll, Hugo, Hexo, or Gatsby. Alternatively, you can [start from a template](../start-with-a-template) or dive right into [configuration options](../configuration-options). - -## App File Structure - -A static `admin` folder contains all Netlify CMS files, stored at the root of your published site. Where you store this folder in the source files depends on your static site generator. Here's the static file location for a few of the most popular static site generators: - -| These generators | store static files in | -| ------------------------------------------------------- | --------------------- | -| Jekyll, GitBook | `/` (project root) | -| Hugo, Gatsby, Nuxt 2, Gridsome, Zola, Sapper, SvelteKit | `/static` | -| Next, Nuxt 3 | `/public` | -| Hexo, Middleman, Jigsaw | `/source` | -| Wyam | `/input` | -| Pelican | `/content` | -| Spike | `/views` | -| VuePress | `/.vuepress/public` | -| Elmstatic | `/_site` | -| 11ty | `/_site` | -| preact-cli | `/src/static` | -| Docusaurus | `/static` | - -If your generator isn't listed here, you can check its documentation, or as a shortcut, look in your project for a `css` or `images` folder. The contents of folders like that are usually processed as static files, so it's likely you can store your `admin` folder next to those. (When you've found the location, feel free to add it to these docs by [filing a pull request](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md#pull-requests)!) - -Inside the `admin` folder, you'll create two files: - -```bash -admin - ├ index.html - └ config.yml -``` - -The first file, `admin/index.html`, is the entry point for the Netlify CMS admin interface. This means that users navigate to `yoursite.com/admin/` to access it. On the code side, it's a basic HTML starter page that loads the Netlify CMS JavaScript file. The second file, `admin/config.yml`, is the heart of your Netlify CMS installation, and a bit more complex. The [Configuration](#configuration) section covers the details. - -In this example, we pull the `admin/index.html` file from a public CDN. - -```html - - - - - - Content Manager - - - - - - -``` - -In the code above the `script` is loaded from the `unpkg` CDN. Should there be any issue, `jsDelivr` can be used as an alternative source. Simply set the `src` to `https://cdn.jsdelivr.net/npm/netlify-cms@^2.0.0/dist/netlify-cms.js` - -### Installing with npm - -You can also use Netlify CMS as an npm module. Wherever you import Netlify CMS, it automatically runs, taking over the current page. Make sure the script that imports it only runs on your CMS page. First install the package and save it to your project: - -```bash -npm install netlify-cms-app --save -``` - -Then import it (assuming your project has tooling for imports): - -```js -import CMS from 'netlify-cms-app' -// Initialize the CMS object -CMS.init() -// Now the registry is available via the CMS object. -CMS.registerPreviewTemplate('my-template', MyTemplate) -``` - -## Configuration - -Configuration is different for every site, so we'll break it down into parts. Add all the code snippets in this section to your `admin/config.yml` file. - -### Backend - -We're using [Netlify](https://www.netlify.com) for our hosting and authentication in this tutorial, so backend configuration is fairly straightforward. - -For GitHub and GitLab repositories, you can start your Netlify CMS `config.yml` file with these lines: - -```yaml -backend: - name: git-gateway - branch: master # Branch to update (optional; defaults to master) -``` - -*(For Bitbucket repositories, use the [Bitbucket backend](/docs/bitbucket-backend) instructions instead.)* - -The configuration above specifies your backend protocol and your publication branch. Git Gateway is an open source API that acts as a proxy between authenticated users of your site and your site repo. (We'll get to the details of that in the [Authentication section](#authentication) below.) If you leave out the `branch` declaration, it defaults to `master`. - -### Editorial Workflow - -**Note:** Editorial workflow works with GitHub repositories, and support for GitLab and Bitbucket is [in beta](/docs/beta-features/#gitlab-and-bitbucket-editorial-workflow-support). - -By default, saving a post in the CMS interface pushes a commit directly to the publication branch specified in `backend`. However, you also have the option to enable the [Editorial Workflow](../configuration-options/#publish-mode), which adds an interface for drafting, reviewing, and approving posts. To do this, add the following line to your Netlify CMS `config.yml`: - -```yaml -# This line should *not* be indented -publish_mode: editorial_workflow -``` - -### Media and Public Folders - -Netlify CMS allows users to upload images directly within the editor. For this to work, the CMS needs to know where to save them. If you already have an `images` folder in your project, you could use its path, possibly creating an `uploads` sub-folder, for example: - -```yaml -# This line should *not* be indented -media_folder: "images/uploads" # Media files will be stored in the repo under images/uploads -``` - -If you're creating a new folder for uploaded media, you'll need to know where your static site generator expects static files. You can refer to the paths outlined above in [App File Structure](#app-file-structure), and put your media folder in the same location where you put the `admin` folder. - -Note that the`media_folder` file path is relative to the project root, so the example above would work for Jekyll, GitBook, or any other generator that stores static files at the project root. However, it would not work for Hugo, Hexo, Middleman or others that store static files in a subfolder. Here's an example that could work for a Hugo site: - -```yaml -# These lines should *not* be indented -media_folder: "static/images/uploads" # Media files will be stored in the repo under static/images/uploads -public_folder: "/images/uploads" # The src attribute for uploaded media will begin with /images/uploads -``` - -The configuration above adds a new setting, `public_folder`. While `media_folder` specifies where uploaded files are saved in the repo, `public_folder` indicates where they are found in the published site. Image `src` attributes use this path, which is relative to the file where it's called. For this reason, we usually start the path at the site root, using the opening `/`. - -*If `public_folder` is not set, Netlify CMS defaults to the same value as `media_folder`, adding an opening `/` if one is not included.* - -### Collections - -Collections define the structure for the different content types on your static site. Since every site is different, the `collections` settings differ greatly from one site to the next. - -Let's say your site has a blog, with the posts stored in `_posts/blog`, and files saved in a date-title format, like `1999-12-31-lets-party.md`. Each post begins with settings in yaml-formatted front matter, like so: - -```yaml ---- -layout: blog -title: "Let's Party" -date: 1999-12-31 11:59:59 -0800 -thumbnail: "/images/prince.jpg" -rating: 5 ---- - -This is the post body, where I write about our last chance to party before the Y2K bug destroys us all. -``` - -Given this example, our `collections` settings would look like this in your NetlifyCMS `config.yml` file: - -```yaml -collections: - - name: "blog" # Used in routes, e.g., /admin/collections/blog - label: "Blog" # Used in the UI - folder: "_posts/blog" # The path to the folder where the documents are stored - create: true # Allow users to create new documents in this collection - slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md - fields: # The fields for each document, usually in front matter - - {label: "Layout", name: "layout", widget: "hidden", default: "blog"} - - {label: "Title", name: "title", widget: "string"} - - {label: "Publish Date", name: "date", widget: "datetime"} - - {label: "Featured Image", name: "thumbnail", widget: "image"} - - {label: "Rating (scale of 1-5)", name: "rating", widget: "number"} - - {label: "Body", name: "body", widget: "markdown"} -``` - -Let's break that down: - - - - - - - - - - - - - - - - - - - - - - - - - - -
    namePost type identifier, used in routes. Must be unique.
    labelWhat the admin UI calls the post type.
    folderWhere files of this type are stored, relative to the repo root.
    createSet to true to allow users to create new files in this collection. -
    slugTemplate for filenames. {{year}}, {{month}}, and {{day}} pulls from the post's date field or save date. {{slug}} is a url-safe version of the post's title. Default is simply {{slug}}. -
    fieldsFields listed here are shown as fields in the content editor, then saved as front matter at the beginning of the document (except for body, which follows the front matter). Each field contains the following properties: -
      -
    • label: Field label in the editor UI.
    • -
    • name: Field name in the document front matter.
    • -
    • widget: Determines UI style and value data type (details below).
    • -
    • default (optional): Sets a default value for the field.
    • -
    -
    - -As described above, the `widget` property specifies a built-in or custom UI widget for a given field. When a content editor enters a value into a widget, that value is saved in the document front matter as the value for the `name` specified for that field. A full listing of available widgets can be found in the [Widgets doc](../widgets). - -Based on this example, you can go through the post types in your site and add the appropriate settings to your Netlify CMS `config.yml` file. Each post type should be listed as a separate node under the `collections` field. See the [Collections reference doc](../configuration-options/#collections) for more configuration options. - -### Filter - -The entries for any collection can be filtered based on the value of a single field. The example collection below only shows post entries with the value `en` in the `language` field. - -```yaml -collections: - - name: "posts" - label: "Post" - folder: "_posts" - filter: - field: language - value: en - fields: - - {label: "Language", name: "language"} -``` - -## Authentication - -Now that you have your Netlify CMS files in place and configured, all that's left is to enable authentication. We're using the [Netlify](https://www.netlify.com/) platform here because it's one of the quickest ways to get started, but you can learn about other authentication options in the [Backends](/docs/backends-overview) doc. - -### Setup on Netlify - -Netlify offers a built-in authentication service called Identity. In order to use it, connect your site repo with Netlify. Netlify has published a general [Step-by-Step Guide](https://www.netlify.com/blog/2016/10/27/a-step-by-step-guide-deploying-a-static-site-or-single-page-app/) for this, along with detailed guides for many popular static site generators, including [Jekyll](https://www.netlify.com/blog/2015/10/28/a-step-by-step-guide-jekyll-3.0-on-netlify/), [Hugo](https://www.netlify.com/blog/2016/09/21/a-step-by-step-guide-victor-hugo-on-netlify/), [Hexo](https://www.netlify.com/blog/2015/10/26/a-step-by-step-guide-hexo-on-netlify/), [Middleman](https://www.netlify.com/blog/2015/10/01/a-step-by-step-guide-middleman-on-netlify/), [Gatsby](https://www.netlify.com/blog/2016/02/24/a-step-by-step-guide-gatsby-on-netlify/), and more. - -### Enable Identity and Git Gateway - -Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. -3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**. -4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/). - -### Add the Netlify Identity Widget - -With the backend set to handle authentication, now you need a frontend interface to connect to it. The open source Netlify Identity Widget is a drop-in widget made for just this purpose. To include the widget in your site, add the following script tag in two places: - -```html - -``` - -Add this to the `` of your CMS index page at `/admin/index.html`, as well as the `` of your site's main index page. Depending on how your site generator is set up, this may mean you need to add it to the default template, or to a "partial" or "include" template. If you can find where the site stylesheet is linked, that's probably the right place. Alternatively, you can include the script in your site using Netlify's [Script Injection](https://www.netlify.com/docs/inject-analytics-snippets/) feature. - -When a user logs in with the Netlify Identity widget, an access token directs to the site homepage. In order to complete the login and get back to the CMS, redirect the user back to the `/admin/` path. To do this, add the following script before the closing `body` tag of your site's main index page: - -```html - -``` - -Note: This example script requires modern JavaScript and does not work on IE11. For legacy browser support, use function expressions (`function () {}`) in place of the arrow functions (`() => {}`), or use a transpiler such as [Babel](https://babeljs.io/). - -## Accessing the CMS - -Your site CMS is now fully configured and ready for login! - -If you set your registration preference to "Invite only," invite yourself (and anyone else you choose) as a site user. To do this, select the **Identity** tab from your site dashboard, and then select the **Invite users** button. Invited users receive an email invitation with a confirmation link. Clicking the link will take you to your site with a login prompt. - -If you left your site registration open, or for return visits after confirming an email invitation, access your site's CMS at `yoursite.com/admin/`. - -**Note:** No matter where you access Netlify CMS — whether running locally, in a staging environment, or in your published site — it always fetches and commits files in your hosted repository (for example, on GitHub), on the branch you configured in your Netlify CMS config.yml file. This means that content fetched in the admin UI matches the content in the repository, which may be different from your locally running site. It also means that content saved using the admin UI saves directly to the hosted repository, even if you're running the UI locally or in staging. - -Happy posting! diff --git a/website/content/docs/architecture.md b/website/content/docs/architecture.md deleted file mode 100755 index dbeedf35..00000000 --- a/website/content/docs/architecture.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Architecture -position: 90 -group: Contributing -weight: 200 ---- - -Netlify CMS is a React application, using Redux for state management with immutable data structures (immutable.js). - -The core abstractions for content editing are `collections`, `entries`, and `widgets`. - -Each `collection` represents a collection of entries. This can either be a collection of similar entries with the same structure, or a set of entries where each has its own structure. - -The structure of an entry is defined as a series of fields, each with a `name`, a `label`, and a `widget`. - -The `widget` determines the UI widget that the content editor will use when editing this field of an entry, as well as how the content of the field is presented in the editing preview. - -Entries are loaded and persisted through a `backend` that will typically represent a `git` repository. - -## State shape / reducers -**Auth:** Keeps track of the logged state and the current user. - -**Config:** Holds the environment configuration (backend type, available collections and fields). - -**Collections:** List of available collections, their fields and metadata information. - -**Entries:** Entries for each field. - -**EntryDraft:** Reused for each entry that is edited or created. It holds the entry's temporary data until it's persisted on the backend. - -## Selectors -Selectors are functions defined within reducers used to compute derived data from the Redux store. The available selectors are: - -**selectEntry:** Selects a single entry, given the collection and a slug. - -**selectEntries:** Selects all entries for a given collection. - -**getAsset:** Selects a single AssetProxy object for the given path. - -## Value Objects -**AssetProxy:** AssetProxy is a Value Object that holds information regarding an asset file (for example, an image), whether it's persisted online or held locally in cache. - -For a file persisted online, the AssetProxy only keeps information about its URI. For local files, the AssetProxy will keep a reference to the actual File object while generating the expected final URIs and on-demand blobs for local preview. - -The AssetProxy object can be used directly inside a media tag (such as ``), as it will always return something that can be used by the media tag to render correctly (either the URI for the online file or a single-use blob). - -## Components structure and Workflows -Components are separated into two main categories: Container components and Presentational components. - -### Entry Editing -For either updating an existing entry or creating a new one, the `EntryEditor` is used and the flow is the same: - -* When mounted, the `EntryPage` container component dispatches the `createDraft` action, setting the `entryDraft` state to a blank state (in case of a new entry) or to a copy of the selected entry (in case of an edit). -* The `EntryPage` will also render widgets for each field type in the given entry. -* Widgets are used for editing entry fields. There are different widgets for different field types, and they are always defined in a pair containing a `control` component and a `preview` component. The control component is responsible for presenting the user with the appropriate interface for manipulating the current field value. The preview component is responsible for displaying the value with the appropriate styling. - -#### Widget components implementation -The control component receives one (1) callback as a prop: `onChange`. - -* onChange (required): Should be called when the users changes the current value. It will ultimately end up updating the EntryDraft object in the Redux Store, thus updating the preview component. -* onAddAsset & onRemoveAsset (optionals): Should be invoked with an `AssetProxy` value object if the field accepts file uploads for media (images, for example). `onAddAsset` will get the current media stored in the Redux state tree while `onRemoveAsset` will remove it. AssetProxy objects are stored in the `Medias` object and referenced in the `EntryDraft` object on the state tree. - -Both control and preview widgets receive a `getAsset` selector via props. Displaying the media (or its URI) for the user should always be done via `getAsset`, as it returns an AssetProxy that can return the correct value for both medias already persisted on the server and cached media not yet uploaded. - -The actual persistence of the content and medias inserted into the control component is delegated to the backend implementation. The backend will be called with the updated values and a list of assetProxy objects for each field of the entry, and should return a promise that can resolve into the persisted entry object and the list of the persisted media URIs. - - -## Editorial Workflow implementation - -Instead of adding logic to `CollectionPage` and `EntryPage`, the Editorial Workflow is implemented as Higher Order Components, adding UI and dispatching additional actions. - -Furthermore, all editorial workflow state is managed in Redux - there's an `actions/editorialWorkflow.js` file and a `reducers/editorialWorkflow.js` file. - -### About metadata - -Netlify CMS embraces the idea of Git-as-backend for storing metadata. The first time it runs with the `editorial_workflow` setup, it creates a new ref called `meta/_netlify_cms`, pointing to an empty, orphan tree. - -Actual data are stored in individual `json` files committed to this tree. diff --git a/website/content/docs/azure-backend.md b/website/content/docs/azure-backend.md deleted file mode 100644 index 1814803c..00000000 --- a/website/content/docs/azure-backend.md +++ /dev/null @@ -1,32 +0,0 @@ ---- -group: Accounts -weight: 20 -title: Azure ---- - -For repositories stored on Azure, the `azure` backend allows CMS users to log in directly with their Azure account. Note that all users must have write access to your content repository for this to work. - -In order to get Netlify-CMS working with Azure DevOps, you need a Tenant Id and an Application Id. - -1. If you do not have an Azure account, [create one here](https://azure.microsoft.com/en-us/free/?WT.mc_id=A261C142F) and make sure to have a credit card linked to the account. -2. If you do not have an Azure Active Directory Tenant Id, [set one up here](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-create-new-tenant). -3. [Register an application with Azure AD](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app). Configure it as a Single tenant Web application and add a redirect URI (e.g. `http://localhost:8080/`) -4. Add the `Azure DevOps->user_impersonation` [permission](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#add-permissions-to-access-your-web-api) for the created application. -5. [Grant admin consent](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-configure-app-access-web-apis#admin-consent-button) for the application. -6. Under `Authentication->Implicit grant` enable [Access tokens](https://docs.microsoft.com/en-us/azure/active-directory/develop/access-tokens) for the application and click `Save`. -7. Verify your Azure DevOps organization is connected to the same directory as your tenant under: `https://dev.azure.com//_settings/organizationAad` -8. Add the following lines to your Netlify CMS `config.yml` file: - -```yaml -backend: - name: azure - repo: organization/project/repo # replace with actual path - tenant_id: tenantId # replace with your tenantId - app_id: appId # replace with your appId -``` - -### Limitations - -1. Pagination is not supported so some endpoints might return missing data - -2. Nested collection are partially supported as Azure doesn't allow [renaming and editing](https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pushes/create?view=azure-devops-rest-6.1&source=docs#rename-a-file) in a single operation diff --git a/website/content/docs/backends-overview.md b/website/content/docs/backends-overview.md deleted file mode 100644 index 2e2f4a5d..00000000 --- a/website/content/docs/backends-overview.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -group: Accounts -weight: 1 -title: Overview ---- - -A backend is JavaScript code that allows Netlify CMS to communicate with a service that stores content - typically a Git host like GitHub or GitLab. It provides functions that Netlify CMS can use to do things like read and update files using API's provided by the service. - -## Backend Configuration - -Individual backends should provide their own configuration documentation, but there are some configuration options that are common to multiple backends. A full reference is below. Note that these are properties of the `backend` field, and should be nested under that field. - -| Field | Default | Description | -| --------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | -| `repo` | none | **Required** for `github`, `gitlab`, and `bitbucket` backends; ignored by `git-gateway`. Follows the pattern `[org-or-username]/[repo-name]`. | -| `branch` | `master` | The branch where published content is stored. All CMS commits and PRs are made to this branch. | -| `api_root` | `https://api.github.com` (GitHub), `https://gitlab.com/api/v4` (GitLab), or `https://api.bitbucket.org/2.0` (Bitbucket) | The API endpoint. Only necessary in certain cases, like with GitHub Enterprise or self-hosted GitLab. | -| `site_domain` | `location.hostname` (or `cms.netlify.com` when on `localhost`) | Sets the `site_id` query param sent to the API endpoint. Non-Netlify auth setups will often need to set this for local development to work properly. | -| `base_url` | `https://api.netlify.com` (GitHub, Bitbucket) or `https://gitlab.com` (GitLab) | OAuth client hostname (just the base domain, no path). **Required** when using an external OAuth server or self-hosted GitLab. | -| `auth_endpoint` | `auth` (GitHub, Bitbucket) or `oauth/authorize` (GitLab) | Path to append to `base_url` for authentication requests. Optional. | -| `cms_label_prefix` | `netlify-cms/` | Pull (or Merge) Requests label prefix when using editorial workflow. Optional. | - -## Creating a New Backend - -Anyone can write a backend, but we don't yet have a finalized and documented API. If you would like to write your own backend for a service that does not have one currently, we recommend using the [GitHub backend](https://github.com/netlify/netlify-cms/tree/master/packages/netlify-cms-backend-github) as a reference for API and best practices. diff --git a/website/content/docs/beta-features.md b/website/content/docs/beta-features.md deleted file mode 100644 index cc7de9c4..00000000 --- a/website/content/docs/beta-features.md +++ /dev/null @@ -1,685 +0,0 @@ ---- -group: Configuration -weight: 200 -title: Beta Features! ---- -We run new functionality in an open beta format from time to time. That means that this functionality is totally available for use, and we *think* it might be ready for primetime, but it could break or change without notice. - -**Use these features at your own risk.** - -## Working with a Local Git Repository - -***added in netlify-cms@2.10.17 / netlify-cms-app@2.11.14*** - -You can connect Netlify CMS to a local Git repository, instead of working with a live repo. - -1. Navigate to a local Git repository configured with the CMS. -2. Add the top-level property `local_backend` configuration to your `config.yml`: - -```yaml -backend: - name: git-gateway - -# when using the default proxy server port -local_backend: true -``` - -3. Run `npx netlify-cms-proxy-server` from the root directory of the above repository. - - * If the default port (8081) is in use, the proxy server won't start and you will see an error message. In this case, follow [these steps](#configure-the-netlify-cms-proxy-server-port-number) before proceeding. -4. Start your local development server (e.g. run `gatsby develop`). -5. Open `http://localhost:/admin` to verify that your can administer your content locally. Replace `` with the port of your local development server. For example Gatsby's default port is `8000` - -**Note:** `netlify-cms-proxy-server` runs an unauthenticated express server. As any client can send requests to the server, it should only be used for local development. Also note that `editorial_workflow` is not supported in this environment. - -### Configure the Netlify CMS proxy server port number - -1. Create a `.env` file in the project's root folder and define the PORT you'd like the proxy server to use - -```ini -PORT=8082 -``` - -2. Update the `local_backend` object in `config.yml` and specify a `url` property to use your custom port number - -```yaml -backend: - name: git-gateway - -local_backend: - # when using a custom proxy server port - url: http://localhost:8082/api/v1 - # when accessing the local site from a host other than 'localhost' or '127.0.0.1' - allowed_hosts: ['192.168.0.1'] -``` - -## GitLab and BitBucket Editorial Workflow Support - -***added in netlify-cms@2.10.6 / netlify-cms-app@2.11.3*** - -You can enable the Editorial Workflow with the following line in your Netlify CMS `config.yml` file: - -```yaml -publish_mode: editorial_workflow -``` - -In order to track unpublished entries statuses the GitLab implementation uses merge requests labels and the BitBucket implementation uses pull requests comments. - -## i18n Support - -The CMS can provide a side by side interface for authoring content in multiple languages. -Configuring the CMS for i18n support requires top level configuration, collection level configuration and field level configuration. - -### Top level configuration - -```yaml -i18n: - # Required and can be one of multiple_folders, multiple_files or single_file - # multiple_folders - persists files in `//.` - # multiple_files - persists files in `/..` - # single_file - persists a single file in `/.` - structure: multiple_folders - - # Required - a list of locales to show in the editor UI - locales: [en, de, fr] - - # Optional, defaults to the first item in locales. - # The locale to be used for fields validation and as a baseline for the entry. - default_locale: en -``` - -### Collection level configuration - -```yaml -collections: - - name: i18n_content - # same as the top level, but all fields are optional and defaults to the top level - # can also be a boolean to accept the top level defaults - i18n: true -``` - -When using a file collection, you must also enable i18n for each individual file: - -```yaml -collections: - - name: pages - label: Pages - # Configure i18n for this collection. - i18n: - structure: single_file - locales: [en, de, fr] - files: - - name: about - label: About Page - file: site/content/about.yml - # Enable i18n for this file. - i18n: true - fields: - - { label: Title, name: title, widget: string, i18n: true } -``` - -### Field level configuration - -```yaml -fields: - - label: Title - name: title - widget: string - # same as 'i18n: translate'. Allows translation of the title field - i18n: true - - label: Date - name: date - widget: datetime - # The date field will be duplicated from the default locale. - i18n: duplicate - - label: Body - name: body - # The markdown field will be omitted from the translation. - widget: markdown -``` - -Example configuration: - -```yaml -i18n: - structure: multiple_folders - locales: [en, de, fr] - -collections: - - name: posts - label: Posts - folder: content/posts - create: true - i18n: true - fields: - - label: Title - name: title - widget: string - i18n: true - - label: Date - name: date - widget: datetime - i18n: duplicate - - label: Body - name: body - widget: markdown -``` - -### Limitations - -1. File collections support only `structure: single_file`. -2. List widgets only support `i18n: true`. `i18n` configuration on sub fields is ignored. -3. Object widgets only support `i18n: true` and `i18n` configuration should be done per field: - -```yaml -- label: 'Object' - name: 'object' - widget: 'object' - i18n: true - fields: - - { label: 'String', name: 'string', widget: 'string', i18n: true } - - { label: 'Date', name: 'date', widget: 'datetime', i18n: duplicate } - - { label: 'Boolean', name: 'boolean', widget: 'boolean', i18n: duplicate } - - { - label: 'Object', - name: 'object', - widget: 'object', - i18n: true, - field: { label: 'String', name: 'string', widget: 'string', i18n: duplicate }, - } -``` - -## GitHub GraphQL API - -Experimental support for GitHub's [GraphQL API](https://developer.github.com/v4/) is now available for the GitHub backend. - -**Note: not compatible with Git Gateway.** - -GraphQL allows to retrieve data using less individual API requests compared to a REST API. GitHub's GraphQL API still does not support all mutations necessary to completely replace their REST API, so this feature only calls the new GraphQL API where possible. - -You can use the GraphQL API for the GitHub backend by setting `backend.use_graphql` to `true` in your CMS config: - -```yml -backend: - name: github - repo: owner/repo # replace this with your repo info - use_graphql: true -``` - -Learn more about the benefits of GraphQL in the [GraphQL docs](https://graphql.org). - -## GitLab GraphQL API - -Experimental support for GitLab's [GraphQL API](https://docs.gitlab.com/ee/api/graphql/) is now available for the GitLab backend. - -**Note: not compatible with Git Gateway.** - -GraphQL allows to retrieve data using less individual API requests compared to a REST API. -The current implementation uses the GraphQL API in specific cases, where using the REST API can be slow and lead to exceeding GitLab's rate limits. As we receive feedback and extend the feature, we'll migrate more functionality to the GraphQL API. - -You can enable the GraphQL API for the GitLab backend by setting `backend.use_graphql` to `true` in your CMS config: - -```yml -backend: - name: gitlab - repo: owner/repo # replace this with your repo info - use_graphql: true - - # optional, defaults to 'https://gitlab.com/api/graphql'. Can be used to configure a self hosted GitLab instance. - graphql_api_root: https://my-self-hosted-gitlab.com/api/graphql -``` -## Open Authoring - -When using the [GitHub backend](/docs/github-backend), you can use Netlify CMS to accept contributions from GitHub users without giving them access to your repository. When they make changes in the CMS, the CMS forks your repository for them behind the scenes, and all the changes are made to the fork. When the contributor is ready to submit their changes, they can set their draft as ready for review in the CMS. This triggers a pull request to your repository, which you can merge using the GitHub UI. - -At the same time, any contributors who *do* have write access to the repository can continue to use Netlify CMS normally. - -More details and setup instructions can be found on [the Open Authoring docs page](/docs/open-authoring). - -## Folder Collections Path - -By default the CMS stores folder collection content under the folder specified in the collection setting. - -For example configuring `folder: posts` for a collection will save the content under `posts/post-title.md`. - -You can now specify an additional `path` template (similar to the `slug` template) to control the content destination. - -This allows saving content in subfolders, e.g. configuring `path: '{{year}}/{{slug}}'` will save the content under `posts/2019/post-title.md`. - -## Folder Collections Media and Public Folder - -By default the CMS stores media files for all collections under a global `media_folder` directory as specified in the configuration. - -When using the global `media_folder` directory any entry field that points to a media file will use the absolute path to the published file as designated by the `public_folder` configuration. - -For example configuring: - -```yaml -media_folder: static/media -public_folder: /media -``` - -And saving an entry with an image named `image.png` will result in the image being saved under `static/media/image.png` and relevant entry fields populated with the value of `/media/image.png`. - -Some static site generators (e.g. Gatsby) work best when using relative image paths. - -This can now be achieved using a per collection `media_folder` configuration which specifies a relative media folder for the collection. - -For example, the following configuration will result in media files being saved in the same directory as the entry, and the image field being populated with the relative path to the image. - -```yaml -media_folder: static/media -public_folder: /media -collections: - - name: posts - label: Posts - label_singular: 'Post' - folder: content/posts - path: '{{slug}}/index' - media_folder: '' - public_folder: '' - fields: - - label: Title - name: title - widget: string - - label: 'Cover Image' - name: 'image' - widget: 'image' -``` - -More specifically, saving an entry with a title of `example post` with an image named `image.png` will result in a directory structure of: - -```bash -content - posts - example-post - index.md - image.png -``` - -And for the image field being populated with a value of `image.png`. - -**Note: When specifying a `path` on a folder collection, `media_folder` defaults to an empty string.** - -**Available template tags:** - -Supports all of the [`slug` templates](/docs/configuration-options#slug) and: - -* `{{dirname}}` The path to the file's parent directory, relative to the collection's `folder`. -* `{{filename}}` The file name without the extension part. -* `{{extension}}` The file extension. -* `{{media_folder}}` The global `media_folder`. -* `{{public_folder}}` The global `public_folder`. - -## List Widget: Variable Types - -Before this feature, the [list widget](/docs/widgets/#list) allowed a set of fields to be repeated, but every list item had the same set of fields available. With variable types, multiple named sets of fields can be defined, which opens the door to highly flexible content authoring (even page building) in Netlify CMS. - -**Note: this feature does not yet support default previews and requires [registering a preview template](/docs/customization#registerpreviewtemplate) in order to show up in the preview pane.** - -To use variable types in the list widget, update your field configuration as follows: - -1. Instead of defining your list fields under `fields` or `field`, define them under `types`. Similar to `fields`, `types` must be an array of field definition objects. -2. Each field definition under `types` must use the `object` widget (this is the default value for - `widget`). - -### Additional list widget options - -* `types`: a nested list of object widgets. All widgets must be of type `object`. Every object widget may define different set of fields. -* `typeKey`: the name of the field that will be added to every item in list representing the name of the object widget that item belongs to. Ignored if `types` is not defined. Default is `type`. -* `summary`: allows customization of a collapsed list item object in a similar way to a [collection summary](/docs/configuration-options/?#summary) - -### Example Configuration - -The example configuration below imagines a scenario where the editor can add two "types" of content, -either a "carousel" or a "spotlight". Each type has a unique name and set of fields. - -```yaml -- label: 'Home Section' - name: 'sections' - widget: 'list' - types: - - label: 'Carousel' - name: 'carousel' - widget: object - summary: '{{fields.header}}' - fields: - - { label: Header, name: header, widget: string, default: 'Image Gallery' } - - { label: Template, name: template, widget: string, default: 'carousel.html' } - - label: Images - name: images - widget: list - field: { label: Image, name: image, widget: image } - - label: 'Spotlight' - name: 'spotlight' - widget: object - fields: - - { label: Header, name: header, widget: string, default: 'Spotlight' } - - { label: Template, name: template, widget: string, default: 'spotlight.html' } - - { label: Text, name: text, widget: text, default: 'Hello World' } -``` - -### Example Output - -The output for the list widget will be an array of objects, and each object will have a `type` key -with the name of the type used for the list item. The `type` key name can be customized via the -`typeKey` property in the list configuration. - -If the above example configuration were used to create a carousel, a spotlight, and another -carousel, the output could look like this: - -```yaml -title: Home -sections: - - type: carousel - header: Image Gallery - template: carousel.html - images: - - images/image01.png - - images/image02.png - - images/image03.png - - type: spotlight - header: Spotlight - template: spotlight.html - text: Hello World - - type: carousel - header: Image Gallery - template: carousel.html - images: - - images/image04.png - - images/image05.png - - images/image06.png -``` - -## Custom Mount Element - -Netlify CMS always creates its own DOM element for mounting the application, which means it always takes over the entire page, and is generally inflexible if you're trying to do something creative, like injecting it into a shared context. - -You can now provide your own element for Netlify CMS to mount in by setting the target element's ID as `nc-root`. If Netlify CMS finds an element with this ID during initialization, it will mount within that element instead of creating its own. - -## Manual Initialization - -Netlify CMS can now be manually initialized, rather than automatically loading up the moment you import it. The whole point of this at the moment is to inject configuration into Netlify CMS before it loads, bypassing need for an actual Netlify CMS `config.yml`. This is important, for example, when creating tight integrations with static site generators. - -Assuming you have the netlify-cms package installed to your project, manual initialization works by setting `window.CMS_MANUAL_INIT = true` **before importing the CMS**: - -```js -// This global flag enables manual initialization. -window.CMS_MANUAL_INIT = true -// Usage with import from npm package -import CMS, { init } from 'netlify-cms' -// Usage with script tag -const { CMS, initCMS: init } = window -/** - * Initialize without passing in config - equivalent to just importing - * Netlify CMS the old way. - */ -init() -/** - * Optionally pass in a config object. This object will be merged into - * `config.yml` if it exists, and any portion that conflicts with - * `config.yml` will be overwritten. Arrays will be replaced during merge, - * not concatenated. - * - * For example, the code below contains an incomplete config, but using it, - * your `config.yml` can be missing its backend property, allowing you - * to set this property at runtime. - */ -init({ - config: { - backend: { - name: 'git-gateway', - }, - }, -}) -/** - * Optionally pass in a complete config object and set a flag - * (`load_config_file: false`) to ignore the `config.yml`. - * - * For example, the code below contains a complete config. The - * `config.yml` will be ignored when setting `load_config_file` to false. - * It is not required if the `config.yml` file is missing to set - * `load_config_file`, but will improve performance and avoid a load error. - */ -init({ - config: { - backend: { - name: 'git-gateway', - }, - load_config_file: false, - media_folder: "static/images/uploads", - public_folder: "/images/uploads", - collections: [ - { label: "Blog", name: "blog", folder: "_posts/blog", create: true, fields: [ - { label: "Title", name: "title", widget: "string" }, - { label: "Publish Date", name: "date", widget: "datetime" }, - { label: "Featured Image", name: "thumbnail", widget: "image" }, - { label: "Body", name: "body", widget: "markdown" }, - ]}, - ], - }, -}) -// The registry works as expected, and can be used before or after init. -CMS.registerPreviewTemplate(...); -``` - -## Raw CSS in `registerPreviewStyle` - -`registerPreviewStyle` can now accept a CSS string, in addition to accepting a url. The feature is activated by passing in an object as the second argument, with `raw` set to a truthy value. This is critical for integrating with modern build tooling. Here's an example using webpack: - -```js -/** - * Assumes a webpack project with `sass-loader` and `css-loader` installed. - * Takes advantage of the `toString` method in the return value of `css-loader`. - */ -import CMS from 'netlify-cms'; -import styles from '!css-loader!sass-loader!../main.scss'; -CMS.registerPreviewStyle(styles.toString(), { raw: true }); -``` - -## Squash merge GitHub pull requests - -When using the [Editorial Workflow](../configuration-options/#publish-mode) with the `github` or GitHub-connected `git-gateway` backends, Netlify CMS creates a pull request for each unpublished entry. Every time the unpublished entry is changed and saved, a new commit is added to the pull request. When the entry is published, the pull request is merged, and all of those commits are added to your project commit history in a merge commit. - -The squash merge option causes all commits to be "squashed" into a single commit when the pull request is merged, and the resulting commit is rebased onto the target branch, avoiding the merge commit altogether. - -To enable this feature, you can set the following option in your Netlify CMS `config.yml`: - -```yaml -backend: - squash_merges: true -``` - -## Commit Message Templates - -You can customize the templates used by Netlify CMS to generate commit messages by setting the `commit_messages` option under `backend` in your Netlify CMS `config.yml`. - -Template tags wrapped in curly braces will be expanded to include information about the file changed by the commit. For example, `{{path}}` will include the full path to the file changed. - -Setting up your Netlify CMS `config.yml` to recreate the default values would look like this: - -```yaml -backend: - commit_messages: - create: Create {{collection}} “{{slug}}” - update: Update {{collection}} “{{slug}}” - delete: Delete {{collection}} “{{slug}}” - uploadMedia: Upload “{{path}}” - deleteMedia: Delete “{{path}}” - openAuthoring: '{{message}}' -``` - -Netlify CMS generates the following commit types: - -| Commit type | When is it triggered? | Available template tags | -| --------------- | ---------------------------------------- | ----------------------------------------------------------- | -| `create` | A new entry is created | `slug`, `path`, `collection`, `author-login`, `author-name` | -| `update` | An existing entry is changed | `slug`, `path`, `collection`, `author-login`, `author-name` | -| `delete` | An existing entry is deleted | `slug`, `path`, `collection`, `author-login`, `author-name` | -| `uploadMedia` | A media file is uploaded | `path`, `author-login`, `author-name` | -| `deleteMedia` | A media file is deleted | `path`, `author-login`, `author-name` | -| `openAuthoring` | A commit is made via a forked repository | `message`, `author-login`, `author-name` | - -Template tags produce the following output: - -* `{{slug}}`: the url-safe filename of the entry changed -* `{{collection}}`: the name of the collection containing the entry changed -* `{{path}}`: the full path to the file changed -* `{{message}}`: the relevant message based on the current change (e.g. the `create` message when an entry is created) -* `{{author-login}}`: the login/username of the author -* `{{author-name}}`: the full name of the author (might be empty based on the user's profile) - -## Image widget file size limit - -You can set a limit to as what the maximum file size of a file is that users can upload directly into a image field. - -Example config: - -```yaml -- label: 'Featured Image' - name: 'thumbnail' - widget: 'image' - default: '/uploads/chocolate-dogecoin.jpg' - media_library: - config: - max_file_size: 512000 # in bytes, only for default media library -``` - -## Summary string template transformations - -You can apply transformations on fields in a summary string template using filter notation syntax. - -Example config: - -```yaml -collections: - - name: 'posts' - label: 'Posts' - folder: '_posts' - summary: "{{title | upper}} - {{date | date('YYYY-MM-DD')}} – {{body | truncate(20, '***')}}" - fields: - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -The above config will transform the title field to uppercase and format the date field using `YYYY-MM-DD` format. -Available transformations are `upper`, `lower`, `date('')`, `default('defaultValue')`, `ternary('valueForTrue','valueForFalse')` and `truncate()`/`truncate(, '')` - -## Registering to CMS Events - -You can execute a function when a specific CMS event occurs. - -Example usage: - -```javascript -CMS.registerEventListener({ - name: 'prePublish', - handler: ({ author, entry }) => console.log(JSON.stringify({ author, data: entry.get('data') })), -}); -``` - -Supported events are `prePublish`, `postPublish`, `preUnpublish`, `postUnpublish`, `preSave` and `postSave`. The `preSave` hook can be used to modify the entry data like so: - -```javascript -CMS.registerEventListener({ - name: 'preSave', - handler: ({ entry }) => { - return entry.get('data').set('title', 'new title'); - }, -}); -``` - -## Dynamic Default Values - -When linking to `/admin/#/collections/posts/new` you can pass URL parameters to pre-populate an entry. - -For example given the configuration: - -```yaml -collections: - - name: posts - label: Posts - folder: content/posts - create: true - fields: - - label: Title - name: title - widget: string - - label: Object - name: object - widget: object - fields: - - label: Title - name: title - widget: string - - label: body - name: body - widget: markdown -``` - -clicking the following link: `/#/collections/posts/new?title=first&object.title=second&body=%23%20content` - -will open the editor for a new post with the `title` field populated with `first`, the nested `object.title` field -with `second` and the markdown `body` field with `# content`. - -**Note:** URL Encoding might be required for certain values (e.g. in the previous example the value for `body` is URL encoded). - -## Nested Collections - -Allows a folder collection to show a nested structure of entries and edit the locations of the entries. - -Example configuration: - -```yaml -collections: - - name: pages - label: Pages - label_singular: 'Page' - folder: content/pages - create: true - # adding a nested object will show the collection folder structure - nested: - depth: 100 # max depth to show in the collection tree - summary: '{{title}}' # optional summary for a tree node, defaults to the inferred title field - fields: - - label: Title - name: title - widget: string - - label: Body - name: body - widget: markdown - # adding a meta object with a path property allows editing the path of entries - # moving an existing entry will move the entire sub tree of the entry to the new location - meta: { path: { widget: string, label: 'Path', index_file: 'index' } } -``` - -Nested collections expect the following directory structure: - -```bash -content -└── pages - ├── authors - │ ├── author-1 - │ │ └── index.md - │ └── index.md - ├── index.md - └── posts - ├── hello-world - │ └── index.md - └── index.md -``` - -## Remark plugins - -You can register plugins to customize [`remark`](https://github.com/remarkjs/remark), the library used by the richtext editor for serializing and deserializing markdown. - -```js -// register a plugin -CMS.registerRemarkPlugin(plugin); - -// provide global settings to all plugins, e.g. for customizing `remark-stringify` -CMS.registerRemarkPlugin({ settings: { bullet: '-' } }); -``` - -Note that `netlify-widget-markdown` currently uses `remark@10`, so you should check a plugin's compatibility first. diff --git a/website/content/docs/bitbucket-backend.md b/website/content/docs/bitbucket-backend.md deleted file mode 100644 index 26ea8f8e..00000000 --- a/website/content/docs/bitbucket-backend.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -group: Accounts -weight: 20 -title: Bitbucket ---- -For repositories stored on Bitbucket, the `bitbucket` backend allows CMS users to log in directly with their Bitbucket account. Note that all users must have write access to your content repository for this to work. - -To enable it: - -1. Follow the authentication provider setup steps in the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider). -2. Add the following lines to your Netlify CMS `config.yml` file: - - ```yaml - backend: - name: bitbucket - repo: owner-name/repo-name # Path to your Bitbucket repository - ``` - -### Client-Side Implicit Grant (Bitbucket) - -With Bitbucket's Implicit Grant, users can authenticate with Bitbucket directly from the client. To do this: - -1. Follow the [Atlassian docs](https://confluence.atlassian.com/bitbucket/oauth-on-bitbucket-cloud-238027431.html) to create an OAuth consumer. Make sure you allow `Account/Read` and `Repository/Write` permissions. To use the [Editorial Workflow](https://www.netlifycms.org/docs/configuration-options/#publish-mode), allow `PullRequests/Write` permissions. For the **Callback URL**, enter the address where you access Netlify CMS, for example, `https://www.mysite.com/admin/`. -2. Bitbucket gives you a **Key**. Copy this Key and enter it in your Netlify CMS `config.yml` file, along with the following settings: - - ```yaml - backend: - name: bitbucket - repo: owner-name/repo-name - branch: default - auth_type: implicit - app_id: # The Key from your Bitbucket settings - ``` - -**Warning:** With Bitbucket implicit grant, the authentication is valid for 1 hour only. After that, the user has to login again, **which can lead to data loss** if the expiration occurs while content is being edited. diff --git a/website/content/docs/cloudinary.md b/website/content/docs/cloudinary.md deleted file mode 100644 index 23fb12a5..00000000 --- a/website/content/docs/cloudinary.md +++ /dev/null @@ -1,136 +0,0 @@ ---- -title: Cloudinary -group: Media -weight: 10 ---- -Cloudinary is a digital asset management platform with a broad feature set, including support for responsive image generation and url based image transformation. They also provide a powerful media library UI for managing assets, and tools for organizing your assets into a hierarchy. - -The Cloudinary media library integration for Netlify CMS uses Cloudinary's own media library interface within Netlify CMS. To get started, you'll need a Cloudinary account and Netlify CMS 2.3.0 or greater. - -## Creating a Cloudinary Account - -You can [sign up for Cloudinary](https://cloudinary.com/users/register/free) for free. Once you're logged in, you'll need to retrieve your Cloud name and API key from the upper left corner of the Cloudinary console. - -![Cloudinary console screenshot](/img/cloudinary-console-details.png) - -## Connecting Cloudinary to Netlify CMS - -To use the Cloudinary media library within Netlify CMS, you'll need to update your Netlify CMS configuration file with the information from your Cloudinary account: - -```yaml -media_library: - name: cloudinary - config: - cloud_name: your_cloud_name - api_key: your_api_key -``` - -**Note:** The user must be logged in to the Cloudinary account connected to the `api_key` used in your Netlify CMS configuration. - -**Note:** The Netlify CMS media library extensions for Cloudinary are not included in `netlify-cms-app`. If you're using `netlify-cms-app`, you'll need to [register the media libraries yourself](https://www.netlifycms.org/blog/2019/07/netlify-cms-gatsby-plugin-4-0-0#using-media-libraries-with-netlify-cms-app). - -### Security Considerations -Although this setup exposes the `cloud_name` and `api_key` publicly via the `/admin/config.yml` endpoint, this information is not sensitive. Any integration of the Cloudinary media library requires this information to be exposed publicly. To use this library or use the restricted Cloudinary API endpoints, the user must have access to the Cloudinary account login details or the `api_secret` associated with the `cloud_name` and `api_key`. - -## Netlify CMS configuration options - -The following options are specific to the Netlify CMS integration for Cloudinary: - -* **`output_filename_only`**: _(default: `false`)_\ - By default, the value provided for a selected image is a complete URL for the asset on Cloudinary's CDN. Setting `output_filename_only` to `true` will instead produce just the filename (e.g. `image.jpg`). This should be `true` if you will be directly embedding cloudinary transformation urls in page templates. Refer to [Inserting Cloudinary URL in page templates](#inserting-cloudinary-url-in-page-templates). -* **`use_transformations`**: _(default: `true`)_\ - If `true`, uses derived url when available (the url will have image transformation segments included). Has no effect if `output_filename_only` is set to `true`. -* **`use_secure_url`**: _(default: `true`)_\ - Controls whether an `http` or `https` URL is provided. Has no effect if `output_filename_only` is set to `true`. - -## Cloudinary configuration options - -The following options are used to configure the media library. All options are listed in Cloudinary's [media library documentation](https://cloudinary.com/documentation/media_library_widget#3_set_the_configuration_options), but only options listed below are available or recommended for the Netlify CMS integration: - -### Authentication - -* `cloud_name` -* `api_key` - -### Media library behavior - -* `default_transformations` _\- only the first [image transformation](#image-transformations) is used, be sure to use the `SDK Parameter` column transformation names from the_ [_transformation reference_](https://cloudinary.com/documentation/image_transformation_reference) -* `max_files` _\- has no impact on images inside the [markdown widget](/docs/widgets/#markdown)_. Refer to [media library documentation](https://cloudinary.com/documentation/media_library_widget#3_set_the_configuration_options) for details on this property -* `multiple` _\- has no impact on images inside the [markdown widget](/docs/widgets/#markdown)_. Refer to [media library documentation](https://cloudinary.com/documentation/media_library_widget#3_set_the_configuration_options) for details on this property - -## Image transformations - -The Cloudinary integration allows images to be transformed in two ways: directly within Netlify CMS via [Cloudinary's Media Library](#transforming-images-via-media-library), and separately from the CMS via Cloudinary's [dynamic URL's](https://cloudinary.com/documentation/image_transformations#delivering_media_assets_using_dynamic_urls) by [inserting cloudinary urls](#inserting-cloudinary-url-in-page-templates). - -### Transforming images via Media Library -If you transform and insert images from within the Cloudinary media library, the transformed image URL will be output by default. This gives the editor complete freedom to make changes to the image output. -There are two ways to configure image transformation via media library - [globally](#global-configuration) and per [field](#field-configuration). Global options will be overridden by field options. - -#### Global configuration - -Global configuration, which is meant to affect the Cloudinary widget at all times, can be provided -as seen below, under the primary `media_library` property. Settings applied here will affect every -instance of the Cloudinary widget. - -```yaml -# global -media_library: - name: cloudinary - output_filename_only: false - config: - default_transformations: - - - fetch_format: auto - width: 160 - quality: auto - crop: scale -``` - -#### Field configuration - -Configuration can also be provided for individual fields that use the media library. The structure -is very similar to the global configuration, except the settings are added to an individual `field`. -For example: - -```yaml -# field -fields: # The fields each document in this collection have -- label: 'Cover Image' - name: 'image' - widget: 'image' - required: false - tagname: '' - media_library: - config: - default_transformations: - - fetch_format: auto - width: 300 - quality: auto - crop: fill - effect: grayscale -``` - -## Inserting Cloudinary URL in page templates - -If you prefer to provide direction so that images are transformed in a specific way, or dynamically retrieve images based on viewport size, you can do so by providing your own base Cloudinary URL and only storing the asset filenames in your content: - -* Either globally or for specific fields, configure the Cloudinary extension to only output the asset filename - -```yaml -# global -media_library: - name: cloudinary - output_filename_only: true -# field -media_library: - name: cloudinary - output_filename_only: true -``` - -* Provide a dynamic URL in the site template - -```handlebars -{{! handlebars example }} - -``` - -Your dynamic URL can be formed conditionally to provide any desired transformations - please see Cloudinary's [image transformation reference](https://cloudinary.com/documentation/image_transformation_reference) for available transformations. diff --git a/website/content/docs/collection-types.md b/website/content/docs/collection-types.md deleted file mode 100644 index 344bbf8d..00000000 --- a/website/content/docs/collection-types.md +++ /dev/null @@ -1,125 +0,0 @@ ---- -group: Collections -weight: 10 -title: Collection Types ---- -All editable content types are defined in the `collections` field of your `config.yml` file, and display in the left sidebar of the Content page of the editor UI. - -Collections come in two main types: `folder` and `files`. - -## Folder collections - -Folder collections represent one or more files with the same format, fields, and configuration options, all stored within the same folder in the repository. You might use a folder collection for blog posts, product pages, author data files, etc. - -Unlike file collections, folder collections have the option to allow editors to create new items in the collection. This is set by the boolean `create` field. - -**Note:** Folder collections must have at least one field with the name `title` for creating new entry slugs. That field should use the default `string` widget. The `label` for the field can be any string value. If you wish to use a different field as your identifier, set `identifier_field` to the field name. See the [Collections reference doc](/docs/configuration-options/#collections) for details on how collections and fields are configured. If you forget to add this field, you will get an error that your collection "must have a field that is a valid entry identifier". - -Example: - -```yaml -collections: - - label: "Blog" - name: "blog" - folder: "_posts/blog" - create: true - fields: - - {label: "Title", name: "title", widget: "string"} - - {label: "Publish Date", name: "date", widget: "datetime"} - - {label: "Featured Image", name: "thumbnail", widget: "image"} - - {label: "Body", name: "body", widget: "markdown"} -``` - -With `identifier_field`: - -```yaml -- label: "Blog" - name: "blog" - folder: "_posts/blog" - create: true - identifier_field: name - fields: - - {label: "Name", name: "name", widget: "string"} - - {label: "Publish Date", name: "date", widget: "datetime"} - - {label: "Featured Image", name: "thumbnail", widget: "image"} - - {label: "Body", name: "body", widget: "markdown"} -``` - -### Filtered folder collections - -The entries for any folder collection can be filtered based on the value of a single field. By filtering a folder into different collections, you can manage files with different fields, options, extensions, etc. in the same folder. - -The `filter` option requires two fields: - -* `field`: The name of the collection field to filter on. -* `value`: The desired field value. - -The example below creates two collections in the same folder, filtered by the `language` field. The first collection includes posts with `language: en`, and the second, with `language: es`. - -```yaml -collections: - - label: "Blog in English" - name: "english_posts" - folder: "_posts" - create: true - filter: {field: "language", value: "en"} - fields: - - {label: "Language", name: "language", widget: "select", options: ["en", "es"]} - - {label: "Title", name: "title", widget: "string"} - - {label: "Content", name: "body", widget: "markdown"} - - label: "Blog en Español" - name: "spanish_posts" - folder: "_posts" - create: true - filter: {field: "language", value: "es"} - fields: - - {label: "Lenguaje", name: "language", widget: "select", options: ["en", "es"]} - - {label: "Titulo", name: "title", widget: "string"} - - {label: "Contenido", name: "body", widget: "markdown"} -``` - -### Nested collections (beta) - -[Nested collections](/docs/beta-features/#nested-collections) is a beta feature that allows a folder collection to show a nested structure of entries and edit the locations of the entries. This feature is useful when you have a complex folder structure and may not want to create separate collections for every directory. As it is in beta, please use with discretion. - -## File collections - -A `files` collection contains one or more uniquely configured files. Unlike items in `folder` collections, which repeat the same configuration over all files in the folder, each item in a `files` collection has an explicitly set path, filename, and configuration. This can be useful for unique files with a custom set of fields, like a settings file or a custom landing page with a unique content structure. - -When configuring a `files` collection, configure each file in the collection separately, and list them under the `files` field of the collection. Each file has its own list of `fields` and a unique filepath specified in the `file` field (relative to the base of the repo). - -**Note:** Files listed in a file collection must already exist in the hosted repository branch set in your Netlify CMS [backend configuration](/docs/backends-overview). Files must also have a valid value for the file type. For example, an empty file works as valid YAML, but a JSON file must have a non-empty value to be valid, such as an empty object. - -Example: - -```yaml -collections: - - label: "Pages" - name: "pages" - files: - - label: "About Page" - name: "about" - file: "site/content/about.yml" - fields: - - {label: Title, name: title, widget: string} - - {label: Intro, name: intro, widget: markdown} - - label: Team - name: team - widget: list - fields: - - {label: Name, name: name, widget: string} - - {label: Position, name: position, widget: string} - - {label: Photo, name: photo, widget: image} - - label: "Locations Page" - name: "locations" - file: "site/content/locations.yml" - fields: - - {label: Title, name: title, widget: string} - - {label: Intro, name: intro, widget: markdown} - - label: Locations - name: locations - widget: list - fields: - - {label: Name, name: name, widget: string} - - {label: Address, name: address, widget: string} -``` diff --git a/website/content/docs/configuration-options.md b/website/content/docs/configuration-options.md deleted file mode 100644 index 24ff89f0..00000000 --- a/website/content/docs/configuration-options.md +++ /dev/null @@ -1,458 +0,0 @@ ---- -group: Configuration -weight: 10 -title: Configuration Options ---- -## Configuration File - -All configuration options for Netlify CMS are specified in a `config.yml` file, in the folder where you access the editor UI (usually in the `/admin` folder). - -Alternatively, you can specify a custom config file using a link tag: - -```html - - -``` - -To see working configuration examples, you can [start from a template](../start-with-a-template) or check out the [CMS demo site](https://cms-demo.netlify.com). (No login required: click the login button and the CMS will open.) You can refer to the demo [configuration code](https://github.com/netlify/netlify-cms/blob/master/dev-test/config.yml) to see how each option was configured. - -You can find details about all configuration options below. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both. - -## Backend - -*This setting is required.* - -The `backend` option specifies how to access the content for your site, including authentication. Full details and code samples can be found in [Backends](/docs/backends-overview). - -**Note**: no matter where you access Netlify CMS — whether running locally, in a staging environment, or in your published site — it will always fetch and commit files in your hosted repository (for example, on GitHub), on the branch you configured in your Netlify CMS config.yml file. This means that content fetched in the admin UI will match the content in the repository, which may be different from your locally running site. It also means that content saved using the admin UI will save directly to the hosted repository, even if you're running the UI locally or in staging. If you want to have your local CMS write to a local repository, try the `local_backend` setting, [currently in beta](/docs/beta-features/#working-with-a-local-git-repository). - -## Publish Mode - -By default, all entries created or edited in the Netlify CMS are committed directly into the main repository branch. - -The `publish_mode` option allows you to enable "Editorial Workflow" mode for more control over the content publishing phases. All unpublished entries will be arranged in a board according to their status, and they can be further reviewed and edited before going live. - -**Note:** Editorial workflow works with GitHub repositories, and support for GitLab and Bitbucket is [in beta](/docs/beta-features/#gitlab-and-bitbucket-editorial-workflow-support). - -You can enable the Editorial Workflow with the following line in your Netlify CMS `config.yml` file: - -```yaml -# /admin/config.yml -publish_mode: editorial_workflow -``` - -From a technical perspective, the workflow translates editor UI actions into common Git commands: - -| Actions in Netlify UI | Perform these Git actions | -| ------------------------- | ----------------------------------------------------------------------------------------------------------------- | -| Save draft | Commits to a new branch (named according to the pattern `cms/collectionName/entrySlug`), and opens a pull request | -| Edit draft | Pushes another commit to the draft branch/pull request | -| Approve and publish draft | Merges pull request and deletes branch | - -## Media and Public Folders - -Netlify CMS users can upload files to your repository using the Media Gallery. The following settings specify where these files are saved, and where they can be accessed on your built site. - -### Media Folder - -*This setting is required.* - -The `media_folder` option specifies the folder path where uploaded files should be saved, relative to the base of the repo. - -```yaml -media_folder: "static/images/uploads" -``` - -### Public Folder - -The `public_folder` option specifies the folder path where the files uploaded by the media library will be accessed, relative to the base of the built site. For fields controlled by \[file] or \[image] widgets, the value of the field is generated by prepending this path to the filename of the selected file. Defaults to the value of `media_folder`, with an opening `/` if one is not already included. - -```yaml -public_folder: "/images/uploads" -``` - -Based on the settings above, if a user used an image widget field called `avatar` to upload and select an image called `philosoraptor.png`, the image would be saved to the repository at `/static/images/uploads/philosoraptor.png`, and the `avatar` field for the file would be set to `/images/uploads/philosoraptor.png`. - -This setting can be set to an absolute URL e.g. `https://netlify.com/media` should you wish, however in general this is not advisable as content should have relative paths to other content. - -## Media Library - -Media library integrations are configured via the `media_library` property, and its value should be an object with at least a `name` property. A `config` property can also be used for options that should be passed to the library in use. - -**Example:** - -```yaml -media_library: - name: uploadcare - config: - publicKey: demopublickey -``` - -## Site URL - -The `site_url` setting should provide a URL to your published site. May be used by the CMS for various functionality. Used together with a collection's `preview_path` to create links to live content. - -**Example:** - -```yaml -site_url: https://your-site.com -``` - -## Display URL - -When the `display_url` setting is specified, the CMS UI will include a link in the fixed area at the top of the page, allowing content authors to easily return to your main site. The text of the link consists of the URL with the protocol portion (e.g., `https://your-site.com`). - -Defaults to `site_url`. - -**Example:** - -```yaml -display_url: https://your-site.com -``` - -## Custom Logo - -When the `logo_url` setting is specified, the CMS UI will change the logo displayed at the top of the login page, allowing you to brand the CMS with your own logo. `logo_url` is assumed to be a URL to an image file. - -**Example:** - -```yaml -logo_url: https://your-site.com/images/logo.svg -``` - -## Locale - -The CMS locale. - -Defaults to `en`. - -Other languages than English must be registered manually. - -**Example** - -In your `config.yml`: - -```yaml -locale: 'de' -``` - -And in your custom JavaScript code: - -```js -import CMS from 'netlify-cms-app'; -import { de } from 'netlify-cms-locales'; - -CMS.registerLocale('de', de); -``` - -When a translation for the selected locale is missing the English one will be used. - -> When importing `netlify-cms` all locales are registered by default (so you only need to update your `config.yml`). - -## Show Preview Links - -[Deploy preview links](../deploy-preview-links) can be disabled by setting `show_preview_links` to `false`. - -**Example:** - -```yaml -show_preview_links: false -``` - -## Search - -The search functionally requires loading all collection(s) entries, which can exhaust rate limits on large repositories. -It can be disabled by setting the top level `search` property to `false`. - -Defaults to `true` - -**Example:** - -```yaml -search: false -``` - -## Slug Type - -The `slug` option allows you to change how filenames for entries are created and sanitized. It also applies to filenames of media inserted via the default media library.\ -For modifying the actual data in a slug, see the per-collection option below. - -`slug` accepts multiple options: - -* `encoding` - - * `unicode` (default): Sanitize filenames (slugs) according to [RFC3987](https://tools.ietf.org/html/rfc3987) and the [WHATWG URL spec](https://url.spec.whatwg.org/). This spec allows non-ASCII (or non-Latin) characters to exist in URLs. - * `ascii`: Sanitize filenames (slugs) according to [RFC3986](https://tools.ietf.org/html/rfc3986). The only allowed characters are (0-9, a-z, A-Z, `_`, `-`, `~`). -* `clean_accents`: Set to `true` to remove diacritics from slug characters before sanitizing. This is often helpful when using `ascii` encoding. -* `sanitize_replacement`: The replacement string used to substitute unsafe characters, defaults to `-`. - -**Example** - -```yaml -slug: - encoding: "ascii" - clean_accents: true - sanitize_replacement: "_" -``` - -## Collections - -*This setting is required.* - -The `collections` setting is the heart of your Netlify CMS configuration, as it determines how content types and editor fields in the UI generate files and content in your repository. Each collection you configure displays in the left sidebar of the Content page of the editor UI, in the order they are entered into your Netlify CMS `config.yml` file. - -`collections` accepts a list of collection objects, each with the following options: - -* `name` (required): unique identifier for the collection, used as the key when referenced in other contexts (like the [relation widget](../widgets/#relation)) -* `identifier_field`: see detailed description below -* `label`: label for the collection in the editor UI; defaults to the value of `name` -* `label_singular`: singular label for certain elements in the editor; defaults to the value of `label` -* `description`: optional text, displayed below the label when viewing a collection -* `files` or `folder` (requires one of these): specifies the collection type and location; details in [Collection Types](../collection-types) -* `filter`: optional filter for `folder` collections; details in [Collection Types](../collection-types) -* `create`: for `folder` collections only; `true` allows users to create new items in the collection; defaults to `false` -* `publish`: for `publish_mode: editorial_workflow` only; `false` hides UI publishing controls for a collection; defaults to `true` -* `hide`: `true` hides a collection in the CMS UI; defaults to `false`. Useful when using the relation widget to hide referenced collections. -* `delete`: `false` prevents users from deleting items in a collection; defaults to `true` -* `extension`: see detailed description below -* `format`: see detailed description below -* `frontmatter_delimiter`: see detailed description under `format` -* `slug`: see detailed description below -* `preview_path`: see detailed description below -* `preview_path_date_field`: see detailed description below -* `fields` (required): see detailed description below -* `editor`: see detailed description below -* `summary`: see detailed description below -* `sortable_fields`: see detailed description below -* `view_filters`: see detailed description below -* `view_groups`: see detailed description below - -The last few options require more detailed information. - -### `identifier_field` - -Netlify CMS expects every entry to provide a field named `"title"` that serves as an identifier for the entry. The identifier field serves as an entry's title when viewing a list of entries, and is used in [slug](#slug) creation. If you would like to use a field other than `"title"` as the identifier, you can set `identifier_field` to the name of the other field. - -**Example** - -```yaml -collections: - - name: posts - identifier_field: name -``` - -### `extension` and `format` - -These settings determine how collection files are parsed and saved. Both are optional—Netlify CMS will attempt to infer your settings based on existing items in the collection. If your collection is empty, or you'd like more control, you can set these fields explicitly. - -`extension` determines the file extension searched for when finding existing entries in a folder collection and it determines the file extension used to save new collection items. It accepts the following values: `yml`, `yaml`, `toml`, `json`, `md`, `markdown`, `html`. - -You may also specify a custom `extension` not included in the list above, as long as the collection files can be parsed and saved in one of the supported formats below. - -`format` determines how collection files are parsed and saved. It will be inferred if the `extension` field or existing collection file extensions match one of the supported extensions above. It accepts the following values: - -* `yml` or `yaml`: parses and saves files as YAML-formatted data files; saves with `yml` extension by default -* `toml`: parses and saves files as TOML-formatted data files; saves with `toml` extension by default -* `json`: parses and saves files as JSON-formatted data files; saves with `json` extension by default -* `frontmatter`: parses files and saves files with data frontmatter followed by an unparsed body text (edited using a `body` field); saves with `md` extension by default; default for collections that can't be inferred. Collections with `frontmatter` format (either inferred or explicitly set) can parse files with frontmatter in YAML, TOML, or JSON format. However, they will be saved with YAML frontmatter. -* `yaml-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved only as YAML, followed by unparsed body text. The default delimiter for this option is `---`. -* `toml-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved only as TOML, followed by unparsed body text. The default delimiter for this option is `+++`. -* `json-frontmatter`: same as the `frontmatter` format above, except frontmatter will be both parsed and saved as JSON, followed by unparsed body text. The default delimiter for this option is `{` `}`. - -### `frontmatter_delimiter` - -If you have an explicit frontmatter format declared, this option allows you to specify a custom delimiter like `~~~`. If you need different beginning and ending delimiters, you can use an array like `["(", ")"]`. - -### `slug` - -For folder collections where users can create new items, the `slug` option specifies a template for generating new filenames based on a file's creation date and `title` field. (This means that all collections with `create: true` must have a `title` field (a different field can be used via [`identifier_field`](#identifier_field)). - -The slug template can also reference a field value by name, eg. `{{title}}`. If a field name conflicts with a built in template tag name - for example, if you have a field named `slug`, and would like to reference that field via `{{slug}}`, you can do so by adding the explicit `fields.` prefix, eg. `{{fields.slug}}`. - -**Available template tags:** - -* Any field can be referenced by wrapping the field name in double curly braces, eg. `{{author}}` -* `{{slug}}`: a url-safe version of the `title` field (or identifier field) for the file -* `{{year}}`: 4-digit year of the file creation date -* `{{month}}`: 2-digit month of the file creation date -* `{{day}}`: 2-digit day of the month of the file creation date -* `{{hour}}`: 2-digit hour of the file creation date -* `{{minute}}`: 2-digit minute of the file creation date -* `{{second}}`: 2-digit second of the file creation date - -**Example:** - -```yaml -slug: "{{year}}-{{month}}-{{day}}_{{slug}}" -``` - -**Example using field names:** - -```yaml -slug: "{{year}}-{{month}}-{{day}}_{{title}}_{{some_other_field}}" -``` - -**Example using field name that conflicts with a template tag:** - -```yaml -slug: "{{year}}-{{month}}-{{day}}_{{fields.slug}}" -``` - -### `preview_path` - -A string representing the path where content in this collection can be found on the live site. This allows deploy preview links to direct to lead to a specific piece of content rather than the site root of a deploy preview. - -**Available template tags:** - -Template tags are the same as those for [slug](#slug), with the following exceptions: - -* `{{slug}}` is the entire slug for the current entry (not just the url-safe identifier, as is the case with [`slug` configuration](#slug)) -* The date based template tags, such as `{{year}}` and `{{month}}`, are pulled from a date field in your entry, and may require additional configuration - see [`preview_path_date_field`](#preview_path_date_field) for details. If a date template tag is used and no date can be found, `preview_path` will be ignored. -* `{{dirname}}` The path to the file's parent directory, relative to the collection's `folder`. -* `{{filename}}` The file name without the extension part. -* `{{extension}}` The file extension. - -**Examples:** - -```yaml -collections: - - name: posts - preview_path: "blog/{{year}}/{{month}}/{{slug}}" -``` - -```yaml -collections: - - name: posts - preview_path: "blog/{{year}}/{{month}}/{{filename}}.{{extension}}" -``` - -### `preview_path_date_field` - -The name of a date field for parsing date-based template tags from `preview_path`. If this field is not provided and `preview_path` contains date-based template tags (eg. `{{year}}`), Netlify CMS will attempt to infer a usable date field by checking for common date field names, such as `date`. If you find that you need to specify a date field, you can use `preview_path_date_field` to tell Netlify CMS which field to use for preview path template tags. - -**Example:** - -```yaml -collections: - - name: posts - preview_path_date_field: "updated_on" -``` - -### `fields` - -The `fields` option maps editor UI widgets to field-value pairs in the saved file. The order of the fields in your Netlify CMS `config.yml` file determines their order in the editor UI and in the saved file. - -`fields` accepts a list of collection objects, each with the following options: - -* `name` (required): unique identifier for the field, used as the key when referenced in other contexts (like the [relation widget](../widgets/#relation)) -* `label`: label for the field in the editor UI; defaults to the value of `name` -* `widget`: defines editor UI and inputs and file field data types; details in [Widgets](../widgets) -* `default`: specify a default value for a field; available for most widget types (see [Widgets](../widgets) for details on each widget type). Please note that field default value only works for folder collection type. -* `required`: specify as `false` to make a field optional; defaults to `true` -* `pattern`: add field validation by specifying a list with a regex pattern and an error message; more extensive validation can be achieved with [custom widgets](../custom-widgets/#advanced-field-validation) -* `comment`: optional comment to add before the field (only supported for `yaml`) - -In files with frontmatter, one field should be named `body`. This special field represents the section of the document (usually markdown) that comes after the frontmatter. - -**Example:** - -```yaml -fields: - - label: "Title" - name: "title" - widget: "string" - pattern: ['.{20,}', "Must have at least 20 characters"] - - {label: "Layout", name: "layout", widget: "hidden", default: "blog"} - - {label: "Featured Image", name: "thumbnail", widget: "image", required: false} - - {label: "Body", name: "body", widget: "markdown"} - comment: 'This is a multiline\ncomment' -``` - -### `editor` - -This setting changes options for the editor view of a collection or a file inside a files collection. It has one option so far: - -* `preview`: set to `false` to disable the preview pane for this collection or file; defaults to `true` - -**Example:** - -```yaml - editor: - preview: false -``` - -**Note**: Setting this as a top level configuration will set the default for all collections - -### `summary` - -This setting allows the customization of the collection list view. Similar to the `slug` field, a string with templates can be used to include values of different fields, e.g. `{{title}}`. This option over-rides the default of `title` field and `identifier_field`. - -**Available template tags:** - -Template tags are the same as those for [slug](#slug), with the following additions: - -* `{{dirname}}` The path to the file's parent directory, relative to the collection's `folder`. -* `{{filename}}` The file name without the extension part. -* `{{extension}}` The file extension. -* `{{commit_date}}` The file commit date on supported backends (git based backends). -* `{{commit_author}}` The file author date on supported backends (git based backends). - -**Example** - -```yaml - summary: "Version: {{version}} - {{title}}" -``` - -### `sortable_fields` - -An optional list of sort fields to show in the UI. - -Defaults to inferring `title`, `date`, `author` and `description` fields and will also show `Update On` sort field in git based backends. - -When `author` field can't be inferred commit author will be used. - -**Example** - -```yaml - # use dot notation for nested fields - sortable_fields: ['commit_date', 'title', 'commit_author', 'language.en'] -``` - -### `view_filters` - -An optional list of predefined view filters to show in the UI. - -Defaults to an empty list. - -**Example** - -```yaml - view_filters: - - label: "Alice's and Bob's Posts" - field: author - pattern: 'Alice|Bob' - - label: 'Posts published in 2020' - field: date - pattern: '2020' - - label: Drafts - field: draft - pattern: true -``` - -### `view_groups` - -An optional list of predefined view groups to show in the UI. - -Defaults to an empty list. - -**Example** - -```yaml - view_groups: - - label: Year - field: date - # groups items based on the value matched by the pattern - pattern: \d{4} - - label: Drafts - field: draft -``` \ No newline at end of file diff --git a/website/content/docs/contributor-guide.md b/website/content/docs/contributor-guide.md deleted file mode 100644 index 95b10b11..00000000 --- a/website/content/docs/contributor-guide.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -title: Contributor Guide -weight: 20 -group: Contributing ---- - -We're hoping that Netlify CMS will do for the [Jamstack](https://www.jamstack.org) what WordPress did for dynamic sites back in the day. We know we can't do that without building a thriving community of contributors and users, and we'd love to have you join us. - -## Getting started with contributing -Being a developer is not a requirement for contributing to Netlify CMS, you only need the desire, a web browser, and a [GitHub account](https://github.com/join). The GitHub repo has a step-by-step [guide](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md) to get started with the code. - -## The basics of the Netlify CMS docs -The documentation for Netlify CMS is written in [Markdown](http://daringfireball.net/projects/markdown/) (a good cheatsheet on Markdown is [here](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)), with the source residing on [GitHub](https://github.com/netlify/netlify-cms) in the `/website/content/docs` folder. - -The GitHub website allows you to submit issues, work with files, search for content, and browse changes that have been submitted in the past and those that are being submitted now (aka Pull Requests). - -## Style guidelines -A [style guide](/docs/writing-style-guide/) is available to help provide context around grammar, code styling, syntax, etc. - -## Filing issues -If you have a GitHub account, you can file an [issue](https://github.com/netlify/netlify-cms/issues) (aka bug report) against the Netlify CMS docs. Even if you're not able to, or don't know how to, fix the issue (see [Improve existing content](#improve-existing-content)), it helps to start the conversation. - -When filing an issue, it is important to remember the [Code of Conduct](https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md). - -## Improve existing content -If you are able to offer up a change to existing content, we welcome this. Once you've forked the repo, and changed the content, you would file a pull request (PR). The repo [Contributing file](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md) lays out the correct format for PRs. - -## Other places to get involved -While we work on building this page (and you can help!), here are some links with more information about getting involved: - -* [Setup instructions and Contribution Guidelines](https://github.com/netlify/netlify-cms/blob/master/CONTRIBUTING.md) -* [Join our Community Chat](https://netlifycms.org/chat) -* [Code of Conduct](https://github.com/netlify/netlify-cms/blob/master/CODE_OF_CONDUCT.md) -* [Project Milestones](https://github.com/netlify/netlify-cms/milestones) -* [Good First Issues](https://github.com/netlify/netlify-cms/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22+-label%3Aclaimed) diff --git a/website/content/docs/custom-widgets.md b/website/content/docs/custom-widgets.md deleted file mode 100644 index 43bf26a8..00000000 --- a/website/content/docs/custom-widgets.md +++ /dev/null @@ -1,564 +0,0 @@ ---- -group: Fields -weight: 20 -title: Creating Custom Widgets ---- -The NetlifyCMS exposes a `window.CMS` a global object that you can use to register custom widgets, previews, and editor plugins. The same object is also the default export if you import Netlify CMS as an npm module. The available widget extension methods are: - -* **registerWidget:** registers a custom widget. -* **registerEditorComponent:** adds a block component to the Markdown editor. - -### Writing React Components inline - -The `registerWidget` requires you to provide a React component. If you have a build process in place for your project, it is possible to integrate with this build process. - -However, although possible, it may be cumbersome or even impractical to add a React build phase. For this reason, NetlifyCMS exposes two constructs globally to allow you to create components inline: ‘createClass’ and ‘h’ (alias for React.createElement). - -## `registerWidget` - -Register a custom widget. - -```js -// Using global window object -CMS.registerWidget(name, control, [preview], [schema]); - -// Using npm module import -import CMS from 'netlify-cms'; -CMS.registerWidget(name, control, [preview], [schema]); -``` - -**Params:** - -| Param | Type | Description | -| ----------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `name` | `string` | Widget name, allows this widget to be used via the field `widget` property in config | -| `control` | `React.Component` or `string` |
    • React component that renders the control, receives the following props:
      • **value:** Current field value
      • **field:** Immutable map of current field configuration
      • **forID:** Unique identifier for the field
      • **classNameWrapper:** class name to apply CMS styling to the field
      • **onChange:** Callback function to update the field value
    • Name of a registered widget whose control should be used (includes built in widgets).
    | -| [`preview`] | `React.Component`, optional | Renders the widget preview, receives the following props:
    • **value:** Current preview value
    • **field:** Immutable map of current field configuration
    • **metadata:** Immutable map of any available metadata for the current field
    • **getAsset:** Function for retrieving an asset url for image/file fields
    • **entry:** Immutable Map of all entry data
    • **fieldsMetaData:** Immutable map of metadata from all fields.
    | -| [`schema`] | `JSON Schema object`, optional | Enforces a schema for the widget's field configuration | - -**Example:** - -`admin/index.html` - -```html - - -``` - -`admin/config.yml` - -```yml -collections: - - name: posts - label: Posts - folder: content/posts - fields: - - name: title - label: Title - widget: string - - name: categories - label: Categories - widget: categories - separator: __ -``` - -## `registerEditorComponent` - -Register a block level component for the Markdown editor: - -```js -CMS.registerEditorComponent(definition) -``` - -**Params** - -* **definition:** The component definition; must specify: id, label, fields, patterns, fromBlock, toBlock, toPreview - -> Additional properties are optional and will be passed to the underlying widget control (object widget by default). For example, adding a `collapsed: true` property will collapse the widget by default. - -**Example:** - -```html - - -``` - -**Result:** - -![youtube-widget](/img/screen shot 2018-01-05 at 4.25.07 pm.png) - -## Advanced field validation - -All widget fields, including those for built-in widgets, [include basic validation](../widgets/#common-widget-options) capability using the `required` and `pattern` options. - -With custom widgets, the widget control can also optionally implement an `isValid` method to perform custom validations, in addition to presence and pattern. The `isValid` method will be automatically called, and it can return either a boolean value, an object with an error message or a promise. Examples: - -**Boolean** -No errors: - -```javascript - isValid = () => { - // Do internal validation - return true; - }; -``` - -Existing error: - -```javascript - isValid = () => { - // Do internal validation - return false; - }; -``` - -**Object with `error` (useful for returning custom error messages)** -Existing error: - -```javascript - isValid = () => { - // Do internal validation - return { error: { message: 'Your error message.' } }; - }; -``` - -**Promise** -You can also return a promise from `isValid`. While the promise is pending, the widget will be marked as "in error". When the promise resolves, the error is automatically cleared. - -```javascript - isValid = () => { - return this.existingPromise; - }; -``` - -**Note:** Do not create a promise inside `isValid` - `isValid` is called right before trying to persist. This means that even if a previous promise was already resolved, when the user hits 'save', `isValid` will be called again. If it returns a new promise, it will be immediately marked as "in error" until the new promise resolves. - -## Writing custom widgets as a separate package - -Widgets are inputs for the Netlify CMS editor interface. It's a React component that receives user input and outputs a serialized value. Those are the only rules - the component can be extremely simple, like text input, or extremely complicated, like a full-blown markdown editor. They can make calls to external services, and generally do anything that JavaScript can do. - -For writing custom widgets as a separate package you should follow these steps: - -1. Create a directory - - ```javascript - mkdir my-custom-widget - ``` -2. Navigate to the directory - - ```javascript - cd my-custom-widget - ``` -3. For setting up a new npm package run this command: - - ```javascript - npm init - ``` -4. Answer the questions in the command line questionnaire. -5. In order to build React components, we need to set up a build step. We'll be using Webpack. Please run the following commands to install the required dependencies: - -```javascript - npm install --save-dev babel-loader@7 babel-core babel-plugin-transform-class-properties babel-plugin-transform-export-extensions babel-plugin-transform-object-rest-spread babel-preset-env babel-preset-react cross-env css-loader html-webpack-plugin netlify-cms react source-map-loader style-loader webpack webpack-cli webpack-serve -``` - -```javascript - npm install --save prop-types -``` - -And you should manually add "**peerDependencies**" and "**scripts**" as shown below. - -Here is the content of `package.json` that you will have at the end: - -```javascript -{ - "name": "netlify-cms-widget-starter", - "description": "A boilerplate for creating Netlify CMS widgets.", - "author": "name of developer", - "keywords": [ - "netlify", - "netlify-cms", - "cms", - "widget", - "starter", - "boilerplate" - ], - "version": "0.0.1", - "homepage": "https://github.com/netlify/netlify-cms-widget-starter", - "license": "MIT", - "main": "dist/main.js", - "devDependencies": { - "babel-loader": "^7.1.4", - "babel-plugin-transform-class-properties": "^6.24.1", - "babel-plugin-transform-export-extensions": "^6.22.0", - "babel-plugin-transform-object-rest-spread": "^6.26.0", - "babel-preset-env": "^1.6.1", - "babel-preset-react": "^6.24.1", - "cross-env": "^5.1.4", - "css-loader": "^0.28.11", - "html-webpack-plugin": "^3.2.0", - "netlify-cms": "^1.5.0", - "react": "^16.3.2", - "source-map-loader": "^0.2.3", - "style-loader": "^0.20.3", - "webpack": "^4.6.0", - "webpack-cli": "^2.0.14", - "webpack-serve": "^0.3.1" - }, - "dependencies": { - "prop-types": "^15.6.1" - }, - "peerDependencies": { - "react": "^16" - }, - "scripts": { - "start": "webpack-serve --static public --open" - } -} -``` - -5. Create a Webpack configuration file with this content: - - `webpack.config.js` - - ```javascript - const path = require('path') - const HtmlWebpackPlugin = require('html-webpack-plugin') - - const developmentConfig = { - mode: 'development', - entry: './dev/index.js', - output: { - path: path.resolve(__dirname, 'public'), - }, - optimization: { minimize: false }, - module: { - rules: [ - { - test: /\.js$/, - loader: 'source-map-loader', - enforce: 'pre', - }, - { - test: /\.jsx?$/, - exclude: /node_modules/, - loader: 'babel-loader', - }, - { - test: /\.css$/, - use: [{ loader: 'style-loader' }, { loader: 'css-loader' }], - }, - ], - }, - plugins: [ - new HtmlWebpackPlugin(), - ], - devtool: 'eval-source-map', - } - - const productionConfig = { - mode: 'production', - module: { - rules: [ - { - test: /\.jsx?$/, - loader: 'babel-loader', - }, - ], - }, - devtool: 'source-map', - } - - module.exports = process.env.NODE_ENV === 'production' ? productionConfig : developmentConfig - ``` -6. The `.babelrc` file is our local configuration for our code in the project. You should create it under the root of the application repo. It will affect all files that Babel processes. So, create a `.babelrc` file under the main project with this content: - -```javascript -{ - "presets": [ - "react", - "env", - ], - "plugins": [ - "transform-export-extensions", - "transform-class-properties", - "transform-object-rest-spread", - ], -} -``` - -7. Create a `src` directory with the files `Control.js`, `Preview.js` and `index.js` - -`src/Control.js` - -```javascript - import PropTypes from 'prop-types'; - import React from 'react'; - - export default class Control extends React.Component { - static propTypes = { - onChange: PropTypes.func.isRequired, - forID: PropTypes.string, - value: PropTypes.node, - classNameWrapper: PropTypes.string.isRequired, - } - - static defaultProps = { - value: '', - } - - render() { - const { - forID, - value, - onChange, - classNameWrapper, - } = this.props; - - return ( - onChange(e.target.value)} - /> - ); - } - } -``` - -`src/Preview.js` - -```javascript -import PropTypes from 'prop-types'; -import React from 'react'; - -export default function Preview({ value }) { - return
    { value }
    ; -} - -Preview.propTypes = { - value: PropTypes.node, -}; -``` - -`src/index.js` - -```javascript -import Control from './Control' -import Preview from './Preview' - -if (typeof window !== 'undefined') { - window.Control = Control - window.Preview = Preview -} - -export { Control, Preview } -``` - -8. Now you need to set up the locale example site. - Under the main project, create a `dev` directory with the files `bootstrap.js` and `index.js` - -`bootstrap.js` - -```javascript -window.CMS_MANUAL_INIT = true -``` - -`index.js` - -```javascript -import './bootstrap.js' -import CMS, { init } from 'netlify-cms' -import 'netlify-cms/dist/cms.css' -import { Control, Preview } from '../src' - -const config = { -backend: { - name: 'test-repo', - login: false, -}, -media_folder: 'assets', -collections: [{ - name: 'test', - label: 'Test', - files: [{ - file: 'test.yml', - name: 'test', - label: 'Test', - fields: [ - { name: 'test_widget', label: 'Test Widget', widget: 'test'}, - ], - }], -}], -} - -CMS.registerWidget('test', Control, Preview) - -init({ config }) -``` - -### [](https://github.com/netlify/netlify-cms-widget-starter#development)Development - -To run a copy of Netlify CMS with your widget for development, use the start script: - -```javascript -npm start -``` - -Your widget source is in the `src` directory, where there are separate files for the `Control` and `Preview` components. - -### [](https://github.com/netlify/netlify-cms-widget-starter#production--publishing)Production & Publishing - -You'll want to take a few steps before publishing a production built package to npm: - -1. Customize `package.json` with details for your specific widget, e.g. name, description, author, version, etc. - - ```json - { - "name": "netlify-cms-widget-starter", - "description": "A boilerplate for creating Netlify CMS widgets.", - "author": "name of developer", - "keywords": [ - "netlify", - "netlify-cms", - "cms", - "widget", - "starter", - "boilerplate" - ], - "version": "0.0.1", - // ... rest - } - ``` -2. For discoverability, ensure that your package name follows the pattern `netlify-cms-widget-`. -3. Delete this `README.md`, rename `README_TEMPLATE.md` to `README.md`, and update the new file for your specific widget. -4. Rename the exports in `src/index.js`. For example, if your widget is `netlify-cms-widget-awesome`, you would do: - -```javascript -if (typeof window !== 'undefined') { - window.AwesomeControl = Control - window.AwesomePreview = Preview -} - -export { Control as AwesomeControl, Preview as AwesomePreview } -``` - -5. Optional: customize the component and file names in `src`. -6. If you haven't already, push your repo to your GitHub account so the source available to other developers. -7. Create a production build, which will be output to `dist`: - -```javascript -npm run build -``` - -8. Finally, if you're sure things are tested and working, publish! - -```javascript -npm publish -``` diff --git a/website/content/docs/customization.md b/website/content/docs/customization.md deleted file mode 100644 index 1a0f4995..00000000 --- a/website/content/docs/customization.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -title: Creating Custom Previews -weight: 50 -group: Customization ---- - -The NetlifyCMS exposes a `window.CMS` global object that you can use to register custom widgets, previews and editor plugins. The available customization methods are: - -* **registerPreviewStyle:** Register a custom stylesheet to use on the preview pane. -* **registerPreviewTemplate:** Registers a template for a collection. - -### React Components inline interaction - -NetlifyCMS is a collection of React components and exposes two constructs globally to allow you to create components inline: ‘createClass’ and ‘h’ (alias for React.createElement). - -## `registerPreviewStyle` - -Register a custom stylesheet to use on the preview pane. - -```js -CMS.registerPreviewStyle(file); -``` - -**Params:** - -* **file:** css file path - -**Example:** - -```html -// index.html - - -``` - -```css -/* example.css */ - -html, -body { - color: #444; - font-size: 14px; - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; -} - -body { - padding: 20px; -} -``` - -## `registerPreviewTemplate` - -Registers a template for a folder collection or an individual file in a file collection. - -`CMS.registerPreviewTemplate(name, react_component);` - -**Params:** - -* name: The name of the collection (or file for file collections) which this preview component will be used for. - * Folder collections: Use the name of the collection - * File collections: Use the name of the file -* react_component: A React component that renders the collection data. Six props will be passed to your component during render: - * entry: Immutable collection containing the entry data. - * widgetFor: Returns the appropriate widget preview component for a given field. - * [widgetsFor](#lists-and-objects): Returns an array of objects with widgets and associated field data. For use with list and object type entries. - * getAsset: Returns the correct filePath or in-memory preview for uploaded images. - **Example:** - - ```html - - - ``` - * document: The preview pane iframe's [document instance](https://github.com/ryanseddon/react-frame-component/tree/9f8f06e1d3fc40da7122f0a57c62f7dec306e6cb#accessing-the-iframes-window-and-document). - * window: The preview pane iframe's [window instance](https://github.com/ryanseddon/react-frame-component/tree/9f8f06e1d3fc40da7122f0a57c62f7dec306e6cb#accessing-the-iframes-window-and-document). - - ### Lists and Objects - The API for accessing the individual fields of list- and object-type entries is similar to the API for accessing fields in standard entries, but there are a few key differences. Access to these nested fields is facilitated through the `widgetsFor` function, which is passed to the preview template component during render. - **Note**: as is often the case with the NetlifyCMS API, arrays and objects are created with Immutable.js. If some of the methods that we use are unfamiliar, such as `getIn`, check out [their docs](https://facebook.github.io/immutable-js/docs/#/) to get a better understanding. - **List Example:** - ```html - - ``` - - **Object Example:** - ```html - - ``` - ### Accessing Metadata - Preview Components also receive an additional prop: `fieldsMetaData`. It contains aditional information (besides the plain textual value of each field) that can be useful for preview purposes. For example, the Relation widget passes the whole selected relation data in `fieldsMetaData`. - ```js - export default class ArticlePreview extends React.Component { - render() { - const {entry, fieldsMetaData} = this.props; - const author = fieldsMetaData.getIn(['authors', data.author]); - - return

    { entry.getIn(['data', 'title']) }

    - {author &&} -
    - } - } - ``` \ No newline at end of file diff --git a/website/content/docs/deploy-preview-links.md b/website/content/docs/deploy-preview-links.md deleted file mode 100644 index 968806f1..00000000 --- a/website/content/docs/deploy-preview-links.md +++ /dev/null @@ -1,149 +0,0 @@ ---- -group: Workflow -weight: 10 -title: Deploy Preview Links ---- -When using the editorial workflow, content editors can create and save content without publishing it -to a live site. Deploy preview links provide a way to view live content when it has not been -published, provided that you're using a continuous deployment platform to provide "deploy previews" -of your unmerged content. - -## Using deploy preview links - -Deploy preview links will work without configuration when all of the following requirements are met: - -* Netlify CMS version is 2.4.0+ for GitHub support and 2.10.6+ for GitLab/Bitbucket support -* Using editorial workflow -* Have a continuous deployment platform that builds every commit and provides statuses to your repo - -Any site created using one of the Deploy to Netlify options on our [starters -page](../start-with-a-template) will automatically meet these criteria (barring any changes made to -your Netlify settings), but you may need to [update](../update-the-cms-version) your Netlify CMS version to get the -functionality. - -**Note:** If you're using a custom backend (one that is not included with Netlify CMS), please check the -documentation for that backend for more information about enabling deploy preview links. - -Deploy preview links are provided in the editor toolbar, near the publishing controls: - -![Deploy preview link for unpublished content](/img/preview-link-unpublished.png) - -### Waiting for builds - -Deploy your site preview may take ten seconds or ten minutes, depending on many factors. For maximum -flexibility, Netlify CMS provides a "Check for Preview" refresh button when the deploy preview is -pending, which a content editor can use to manually check for a finished preview until it's ready: - -![Deploy preview link for unpublished content](/img/preview-link-check.png) - -## Configuring preview paths - -Deploy preview links point to the site root by default, but you'll probably want them to point to -the specific piece of content that the content editor is viewing. You can do this by providing a -`preview_path` string template for each collection, or for inidividual files in a files collection. - -Let's say we have a `blog` collection that stores content in our repo under `content/blog`. The path -to a post in your repo may look like `content/blog/2018-01-new-post.md`, but the path to that post -on your site would look more like: `/blog/2018-01-new-post/`. Here's how you would use -`preview_path` in your configuration for this scenario: - -```yaml -collections: - - name: blog - folder: content/blog - slug: {{year}}-{{month}}-{{slug}} - preview_path: blog/{{slug}} -``` - -Similarly, for an `about` page in a files collection under `content/pages` which maps to `/about-the-project` -on your site, you would configure `preview_path` like this: - -```yaml -collections: - - name: pages - files: - - name: about - file: content/pages/about.md - preview_path: about-the-project -``` - -With the above configuration, the deploy preview URL from your backend will be combined with your -preview path to create a URL to a specific blog post. - -**Note:** `{{slug}}` in `preview_path` is different than `{{slug}}` in `slug`. In the `slug` -template, `{{slug}}` is only the url-safe [identifier -field](../configuration-options/#identifier_field), while in the `preview_path` template, `{{slug}}` -is the entire slug for the entry. For example: - -```yaml -# for an entry created Jan 1, 2000 with identifier "My New Post!" -collections: - - name: posts - slug: {{year}}-{{month}}-{{slug}} # {{slug}} will compile to "my-new-post" - preview_path: blog/{{slug}} # {{slug}} will compile to "2000-01-my-new-post" -``` - -### Dates in preview paths - -Some static site generators allow URL's to be customized with date parameters - for example, Hugo -can be configured to use values like `year` and `month` in a URL. These values are generally derived -by the static site generator from a date field in the content file. `preview_path` accepts these -parameters as well, similar to the `slug` configuration, except `preview_path` populates date values -based on a date value from the entry, just like static site generators do. Netlify CMS will attempt -to infer an obvious date field, but you can also specify which date field to use for `preview_path` -template tags by using -[`preview_path_date_field`](../configuration-options/#preview_path_date_field). - -Together with your other field values, dates can be used to configure most URL schemes available -through static site generators. - -**Example** - -```yaml -# This collection's date field will be inferred because it has a field named `"date"` -collections: - - name: posts - preview_path: blog/{{year}}/{{month}}/{{title}} - fields: - - { name: title, label: Title } - { name: date, label: Date, widget: date } - { name: body, label: Body, widget: markdown } -# This collection requires `path_preview_date_field` because the no obvious date field is available -collections: - - name: posts - preview_path: blog/{{year}}/{{month}}/{{title}} - preview_path_date_field: published_at - fields: - - { name: title, label: Title } - { name: published_at, label: Published At, widget: date } - { name: body, label: Body, widget: markdown } -``` - -## Preview links for published content - -You may also want preview links for published content as a convenience. You can do this by providing -a `site_url` in your configuration, which will be used in place of the deploy preview URL that a -backend would provide for an unpublished entry. Just as for deploy preview links to unpublished -content, links to published content will use any `preview_path` values that are defined in the -collection configurations. - -Preview links for published content will also work if you are not using the editorial workflow. - -![Deploy preview link for unpublished content](/img/preview-link-unpublished.png) - -## Disabling deploy preview links - -To disable deploy preview links, set `show_preview_links` to false in your CMS configuration. - -## How it works - -Deploy preview links are provided through your CMS backend, and Netlify CMS is unopinionated about -where the links come from or how they're created. That said, the general approach for Git backends -like GitHub is powered by "commit statuses". Continuous deployment platforms like Netlify can deploy -a version of your site for every commit that is pushed to your remote Git repository, and then send -a commit status back to your repository host with the URL. - -The deploy preview URL provided by a backend will lead to the root of the deployed site. Netlify CMS -will then use the `preview_path` template in an entry's collection configuration to build a path to -a specific piece of content. If a `preview_path` is not provided for an entry's collection, the URL -will be used as is. diff --git a/website/content/docs/docusaurus.md b/website/content/docs/docusaurus.md deleted file mode 100644 index 63b70231..00000000 --- a/website/content/docs/docusaurus.md +++ /dev/null @@ -1,256 +0,0 @@ ---- -group: Guides -weight: 80 -title: Docusaurus ---- -This guide instructs you on how to integrate Netlify CMS with Docusaurus. - -### Before you begin - -* Sign up for [GitHub](www.github.com) and [Netlify](www.netlify.com). -* Download [Node.js](https://nodejs.org/en/download/) version 14 or above. -* Install the [GitHub CLI](https://cli.github.com/). -* Install and authenticate the [Netlify CLI](https://docs.netlify.com/cli/get-started/). - -## Create a new Docusaurus project - -```bash -# 1. Use Docusaurus to create a site scaffold. -npx create-docusaurus@latest my-website classic - -# 2. Run the development server. -cd my-website -npm run start -``` - -A browser window opens at `http://localhost:3000`. - -The development server now serves your website at `http://localhost:3000`. As you edit the source files in `/my-website/`, you can visit `http://localhost:3000` to preview your changes. - - - - - -## Push your project to GitHub - -Netlify CMS requires a [backend](https://www.netlifycms.org/docs/backends-overview/) to store content. Netlify CMS supports using Git hosts, like GitHub or GitLab, as backends. This guide uses GitHub. - -```bash -# 1. Initialize your local Git repository. -git init - -# 2. Rename your initial branch to match GitHub. -git branch -m main - -# 3. Stage all your local files to your repository. -git add . - -# 4. Commit your staged changes. -git commit -m 'Initial commit' - -# 5. Create a remote repository on GitHub using the GitHub CLI. -gh repo create my-website -``` - -Don't add a license or a .gitignore. Do add an "origin" git remote. - -![](/img/screen-shot-2021-11-15-at-4.16.53-pm.png) - -```bash -# 6. Update your remote repository with your staged changes. -git push -u origin main -``` - -## Publish your project using Netlify CLI - -
      -
    1. Connect Netlify CLI to your GitHub repository. - -```bash -netlify init -``` - -
    2. -
    3. Choose Create & configure a new site.
    4. -
    5. Choose your team and site name.
    6. -
    7. Choose yarn build for your build command.
    8. -
    9. Choose build for your deployment directory.
    10. -
    - -![](/img/screen-shot-2021-11-16-at-1.34.18-PM.png) - -Choose the default option for everything else. - -Your website is now deployed. Netlify provides you with a randomly generated domain name. Run `netlify open --site` to view your deployed site. - -## Add Netlify CMS to your project - -### Before you begin - -
      - -
    1. Remove all existing posts from /blog. - -```bash -rm -rf ./blog/* -``` - -
    2. - -
    3. Create a new blog post post titled 2021-11-15-first-blog-post.md. - -```bash -touch ./blog/2021-11-15-first-blog-post.md -``` - -
    4. - -
    5. Edit 2021-11-15-first-blog-post.md to look like this: - -```yaml ---- -title: First Blog Post -slug: first-blog-post -tags: - - foo - - bar -authors: - - name: Garrison McMullen - title: Instruction Writer - url: https://github.com/garrison0 - image_url: https://avatars.githubusercontent.com/u/4089393?v=4 ---- -Lorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque elementum dignissim ultricies. Fusce rhoncus ipsum tempor eros aliquam consequat. -``` - -
    6. - -
    - -### Procedure - -
      - -
    1. Create an admin directory inside static. - -```bash -cd static -mkdir admin -``` - -
    2. - -
    3. In the admin directory, create a config.yml file and an index.html file. - -```bash -cd admin -touch config.yml -touch index.html -``` - -
    4. - -
    5. Edit index.html to look like this: - -```html - - - - - - Content Manager - - - - - - -``` - -`index.html` displays the Netlify CMS admin interface. You'll use the admin interface to edit your blog posts. - -
    6. - -
    7. Edit config.yml to look like this: - -```yaml -backend: - name: github - branch: main - repo: /my-website - -# These lines should *not* be indented -media_folder: "static/img" # Media files will be stored in the repo under static/images/uploads -public_folder: "/img/" # The src attribute for uploaded media will begin with /images/uploads - -collections: -- name: blog - label: "blog" - folder: blog - identifier_field: title - extension: md - widget: "list" - create: true - slug: "{{year}}-{{month}}-{{day}}-{{slug}}" # Filename template, e.g., YYYY-MM-DD-title.md - fields: - - { name: title, label: Title, widget: string } - - { name: body, label: Body, widget: markdown } - - { name: slug, label: Slug, widget: string } - - label: "Tags" - name: "tags" - widget: "list" - - label: "Authors" - name: "authors" - widget: "list" - fields: - - { name: name, label: Name, widget: string } - - { name: title, label: Title, widget: string } - - { name: url, label: URL, widget: string } - - { name: imageUrl, label: ImageURL, widget: string } -``` - -`config.yml` specifies what kind of content your blog posts have. The content specification enables Netlify CMS to edit existing posts and create new ones with the same format. To learn more, read about Netlify CMS' [](https://www.netlifycms.org/docs/configuration-options/)[Configuration options](https://www.netlifycms.org/docs/configuration-options/). -
    8. - -
    9. -Visit localhost:3000/admin - -You can now view and edit `2021-11-15-first-blog-post.md` through the admin interface. You can also create new blog posts. - -**Warning:** Any changes you publish through the admin interface will only effect your *remote GitHub repository*. To retrieve these changes locally, `git pull` from your local repository. -
    10. - -
    11. Commit and push your new changes to your remote repository. - -```bash -git add . -git commit -m "Add Netlify CMS" -git push -``` - -Netlify builds and deploys your new changes. - -
    12. - -
    - -## Add GitHub as an authentication provider - -Before you can access `/admin/` through your Netlify domain, you need to set up an authentication provider. The authentication provider allows Netlify CMS to determine whether users have read and write access to `/admin/`. This guide uses GitHub credentials for authentication. - -### Configure GitHub - -1. Create a new [GitHub OAuth application](https://github.com/settings/applications/new). -2. Enter your Netlify domain as the **Homepage URL**. -3. Enter https://api.netlify.com/auth/done as the **Authorization callback URL**. -4. Click **Register application.** -5. Click **Generate a new client secret.** -6. Copy the provided client secret and client ID. - -### Configure Netlify - -1. On Netlify, under `Site Settings > Access control > OAuth > Authentication Providers`, click **Install provider**. -2. Enter your client secret and client ID from GitHub. -3. Click **Install**. - -🎉 All done! Now you can access the admin interface through your Netlify URL. \ No newline at end of file diff --git a/website/content/docs/examples.md b/website/content/docs/examples.md deleted file mode 100644 index ca73ace5..00000000 --- a/website/content/docs/examples.md +++ /dev/null @@ -1,35 +0,0 @@ ---- -group: Contributing -weight: 110 -title: Examples ---- - -Do you have a great, open source example? Submit a pull request to this page! - -Example | Tools | Type | Source | More info | ---- | --- | --- | --- | --- -[Gatsby & Netlify CMS Meetup Group Template](https://github.com/robertcoopercode/gatsby-netlify-cms) | Gatsby | demo | [robertcoopercode/gatsby-netlify-cms](https://github.com/robertcoopercode/gatsby-netlify-cms) | [blog post](https://blog.logrocket.com/gatsby-netlify-cms-a-perfect-pairing-d50d59d16f67) -[This Developing Journey](https://briandouglas.me) | middleman | blog | [bdougie/blog](https://github.com/bdougie/blog) | [blog post](https://www.netlify.com/blog/2017/04/20/creating-a-blog-with-middleman-and-netlify-cms/) -[Jamstack Recipes](https://jamstack-cms.netlify.com) | Hugo, Azure | demo | [hlaueriksson/jamstack-cms](https://github.com/hlaueriksson/jamstack-cms) | [blog post](http://conductofcode.io/post/managing-content-for-a-jamstack-site-with-netlify-cms/) -[Bael](https://bael-theme.jake101.com/) | Vue, Nuxt | blog | [jake-101/bael-template](https://github.com/jake-101/bael-template) | [blog post](https://bael-theme.jake101.com/blog/2018-06-19-top-10-reasons-why) -[Forest Garden Wales](https://www.forestgarden.wales/) | Hugo | blog | [forestgardenwales/forestgarden.wales](https://github.com/forestgardenwales/forestgarden.wales) | [blog post](https://www.forestgarden.wales/blog/now-using-netlify-cms/) -[Jekyll Demo](https://jekyll-netlifycms.netlify.com/) | Jekyll, Gulp | demo | [NickStees/jekyll-cms](https://github.com/NickStees/jekyll-cms) | [read me](https://github.com/NickStees/jekyll-cms) -[Jekyll feat Alembic Theme Demo](https://alembic-kit-demo.netlify.com/) | Jekyll | demo | [DavidDarnes/alembic-netlifycms-kit](https://github.com/daviddarnes/alembic-netlifycms-kit) | [read me](https://github.com/daviddarnes/alembic-netlifycms-kit#starter-kit-for-alembic-with-netlify-cms) -[Eleventy Starter Project](https://eleventy-netlify-boilerplate.netlify.com/) | Eleventy | demo | [danurbanowicz/eleventy-netlify-boilerplate](https://github.com/danurbanowicz/eleventy-netlify-boilerplate) | [read me](https://github.com/danurbanowicz/eleventy-netlify-boilerplate) -[YellowCake - Complete website with blog](https://yellowcake.netlify.com) | Gatsby, Netlify-CMS, Uploadcare | demo | [thriveweb/yellowcake](https://github.com/thriveweb/yellowcake/) | [blog post](https://thriveweb.com.au/the-lab/yellowcake-gatsby-react-js-starter-project/) -[Vue.js - Nuxt.js Starter Project](https://github.com/renestalder/nuxt-netlify-cms-starter-template) | Vue, Nuxt | demo | [renestalder/nuxt-netlify-cms-starter-template](https://github.com/renestalder/nuxt-netlify-cms-starter-template) | [read me](https://github.com/renestalder/nuxt-netlify-cms-starter-template) -[Hexo Demo](https://hexocms.imst.xyz/) | Hexo | demo | [DemoMacro/Hexo-NetlifyCMS](https://github.com/DemoMacro/Hexo-NetlifyCMS) | [read me](https://github.com/DemoMacro/Hexo-NetlifyCMS) -[Gitbook Demo](https://gitbook.imst.xyz/) | Gitbook | demo | [DemoMacro/Gitbook-NetlifyCMS](https://github.com/DemoMacro/Gitbook-NetlifyCMS) | [read me](https://github.com/DemoMacro/Gitbook-NetlifyCMS) -[VuePress Demo](https://vuepress.imst.xyz/) | VuePress | demo | [DemoMacro/VuePress-NetlifyCMS](https://github.com/DemoMacro/VuePress-NetlifyCMS) | [read me](https://github.com/DemoMacro/VuePress-NetlifyCMS) -[Jigsaw Blog Starter Template Demo](https://jigsaw-blog-netlify-netlifycms-template.netlify.com/) | Jigsaw | demo | [erickpatrick/jigsaw-blog-netlify-netlifycms-template](https://github.com/erickpatrick/jigsaw-blog-netlify-netlifycms-template) | [blog post](https://www.erickpatrick.net/blog/augmenting-tightenco-jigsaw-with-netlifycms/) -[Nuxt & NetlifyCMS Boilerplate](https://nuxt-netlifycms-boilerplate.netlify.com/) | Vue, Nuxt | demo | [tylermercer/nuxt-netlifycms-boilerplate](https://github.com/tylermercer/nuxt-netlifycms-boilerplate) | [read me](https://github.com/tylermercer/nuxt-netlifycms-boilerplate) -[Next.js demo](https://netlifycms-nextjs.netlify.com) | Next.js | blog | [masives/netlifycms-nextjs](https://github.com/masives/netlifycms-nextjs) | [read me](https://github.com/masives/netlifycms-nextjs) -[Delog - Jamstack Blog with Netlify CMS](https://delog-w3layouts.netlify.com/) | Gatsby, Netlify-CMS | demo | [W3Layouts/gatsby-starter-delog](https://github.com/W3Layouts/gatsby-starter-delog) | [blog post](https://w3layouts.com/articles/delog-gatsby-starter-netlify-cms/) -[Netlify CMS template for Gridsome](https://netlifycms-gridsome.suits.at/) | Gridsome, Vue | demo | [suits-at/netlifycms-gridsome](https://github.com/suits-at/netlifycms-gridsome) | [read me](https://github.com/suits-at/netlifycms-gridsome) -[Next.js blogging template for Netlify](https://nextjs-netlify-blog-template.netlify.app/) | Next.js, Netlify | blog | [wutali/nextjs-netlify-blog-template](https://github.com/wutali/nextjs-netlify-blog-template) | [read me](https://github.com/wutali/nextjs-netlify-blog-template) -[Netlify CMS and OAuth server on AWS](https://github.com/pulumi/examples/tree/master/aws-ts-netlify-cms-and-oauth) | Netlify, Pulumi, AWS | blog | [pulumi/examples/aws-ts-netlify-cms-and-oauth](https://github.com/pulumi/examples/tree/master/aws-ts-netlify-cms-and-oauth) | [blog post](https://www.pulumi.com/blog/deploying-the-infrastructure-of-oauth-server-for-cms-app/) -[Eleventy Starter Boilerplate](https://creativedesignsguru.com/demo/Eleventy-Starter-Boilerplate/eleventy-starter-boilerplate-presentation/) | Eleventy, Netlify | demo | [ixartz/Eleventy-Starter-Boilerplate](https://github.com/ixartz/Eleventy-Starter-Boilerplate) | [read me](https://github.com/ixartz/Eleventy-Starter-Boilerplate) -[Nuxt, Tailwind & NetlifyCMS Boilerplate](https://ntn-boilerplate.netlify.app/) | Vue, Nuxt | demo | [Knogobert/ntn-boilerplate](https://github.com/Knogobert/ntn-boilerplate) | [read me](https://github.com/Knogobert/ntn-boilerplate#readme) -[Gatsby & Netlify CMS Personal Portfolio](https://kind-mestorf-5a2bc0.netlify.com/) | Gatsby | portfolio | [EarlGeorge/React-Gatsby](https://github.com/EarlGeorge/React-Gatsby) | [read me](https://github.com/EarlGeorge/React-Gatsby/blob/master/README.md) -[Gatsby, Tailwind CSS & NetlifyCMS Starter](https://infallible-varahamihira-058515.netlify.app/) | Gatsby v3, Netlify-CMS, Tailwind CSS | demo | [jimmybutton/gatsby-netlifycms-tailwind-starter](https://github.com/jimmybutton/gatsby-netlifycms-tailwind-starter) | [read me](https://github.com/jimmybutton/gatsby-netlifycms-tailwind-starter#readme) -[Metalsmith NetlifyCMS Starter](https://metalsmith-netlify-starter.netlify.app/) | Metalsmith and Netlify-CMS | demo | [metalsmith-netlify-starter](https://github.com/wernerglinka/metalsmith-netlify-starter) | [read me](https://github.com/wernerglinka/metalsmith-netlify-starter#readme) \ No newline at end of file diff --git a/website/content/docs/external-oauth-clients.md b/website/content/docs/external-oauth-clients.md deleted file mode 100644 index 5e08e6aa..00000000 --- a/website/content/docs/external-oauth-clients.md +++ /dev/null @@ -1,24 +0,0 @@ ---- -group: Accounts -weight: 60 -title: External OAuth Clients ---- -If you would like to facilitate your own OAuth authentication rather than use Netlify's service or a client side flow like implicit or PKCE, you can use one of the community-maintained projects below. Feel free to hit the "Edit this page" button if you'd like to add yours! - -| Author | Supported Git hosts | Language(s)/Platform(s) | Link | -| ------------------------------------------------------------ | --------------------------------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| [@vencax](https://github.com/vencax) | GitHub, GitHub Enterprise | Node.js | [Repo](https://github.com/vencax/netlify-cms-github-oauth-provider) | -| [@igk1972](https://github.com/igk1972) | GitHub, GitHub Enterprise | Go | [Repo](https://github.com/igk1972/netlify-cms-oauth-provider-go) | -| [@davidejones](https://github.com/davidejones) | GitHub, GitHub Enterprise | Python | [Repo](https://github.com/davidejones/netlify-cms-oauth-provider-python) | -| [@marcelkornblum](https://github.com/marcelkornblum) | GitHub, GitHub Enterprise | Google AppEngine with Python | [Repo](https://github.com/signal-noise/netlify-cms-oauth-provider-python-appengine) | -| [@marksteele](https://github.com/marksteele) | GitHub, GitHub Enterprise | Serverless | [Repo](https://github.com/marksteele/netlify-serverless-oauth2-backend), [Blog](https://www.control-alt-del.org/blog/serverless-blog-howto/) | -| [@Herohtar](https://github.com/Herohtar) | GitHub, GitHub Enterprise | Firebase Cloud Function | [Repo](https://github.com/Herohtar/netlify-cms-oauth-firebase) | -| [@abcalderon3](https://github.com/abcalderon3) | GitHub, GitHub Enterprise | Google Cloud Function with Python | [Repo](https://github.com/abcalderon3/netlify-cms-oauth-client-cloud-function) | -| [@TSV-Zorneding-1920](https://github.com/TSV-Zorneding-1920) | GitHub, GitHub Enterprise | PHP | [Repo](https://github.com/TSV-Zorneding-1920/netlify-cms-oauth-provider-php) | -| [@bericp1](https://github.com/bericp1) | GitHub, GitHub Enterprise | Node.js, Vercel Serverless | [Repo](https://github.com/bericp1/netlify-cms-oauth-provider-node) | -| [@mcdeck](https://github.com/mcdeck) | GitHub, GitHub Enterprise, GitLab | PHP | [Repo](https://github.com/mcdeck/netlify-cms-oauth-provider-php), [Blog](https://www.van-porten.de/blog/2021/01/netlify-auth-provider/) | -| [@deepbass](https://github.com/deepbass) | GitHub, GitHub Enterprise | Node.js Azure Functions | [Repo](https://github.com/deepbass/serverless-cms-azure), [Blog](https://www.danielbass.dev/building-a-serverless-cms-on-azure-with-netlify-cms-and-gatsby/) | -| [@adrian-ub](https://github.com/adrian-ub) | GitHub, GitLab | TypeScript | [Repo](https://github.com/ublabs/netlify-cms-oauth) | -| [@hatappo](https://github.com/hatappo) | GitHub | ClojureScript, Firebase Functions | [Repo](https://github.com/hatappo/netlifycms-oauth-server) | - -Check each project's documentation for instructions on installation and usage. diff --git a/website/content/docs/gatsby.md b/website/content/docs/gatsby.md deleted file mode 100644 index 8acd2700..00000000 --- a/website/content/docs/gatsby.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -title: Gatsby -group: Guides -weight: 10 ---- -This guide will help you get started using Netlify CMS and Gatsby. - -To get up and running with Gatsby, you’ll need to have [Node.js](https://nodejs.org/) installed on your computer. *Note: Gatsby's minimum supported Node.js version is Node 8.* - -## Create a new Gatsby site - -Let's create a new site using the default Gatsby Starter Blog. Run the following commands in the terminal, in the folder where you'd like to create the blog: - -```bash -npm install -g gatsby-cli -gatsby new blog https://github.com/gatsbyjs/gatsby-starter-blog -cd blog -``` - -## Get to know Gatsby - -In your favorite code editor, open up the code generated for your "Gatsby Starter Blog" site, and take a look at the `content` directory. - -You will see that there are multiple Markdown files that represent blog posts. Open one `.md` file and you will see something like this: - -```yml ---- -title: New Beginnings -date: "2015-05-28T22:40:32.169Z" -description: This is an optional description for SEO and Open Graph purposes, rather than the default generated excerpt. ---- - -Far far away, behind the word mountains, far from the countries Vokalia and -Consonantia, there live the blind texts. -``` - -We can see above that each blog post has a title, a date, a description and a body. Now, let's recreate this using Netlify CMS. - -## Add Netlify CMS to your site - -First let's install some dependencies. We'll need `netlify-cms-app` and `gatsby-plugin-netlify-cms`. Run the following command in the terminal at the root of your site: - -```bash -npm install --save netlify-cms-app gatsby-plugin-netlify-cms -``` - -### Configuration - -For the purpose of this guide we will deploy to Netlify from a GitHub repository which requires the minimum configuration. - -Create a `config.yml` file in the directory structure you see below: - -```bash -├── static -│ ├── admin -│ │ ├── config.yml -``` - -In your `config.yml` file paste the following configuration: - -```yml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) - -media_folder: static/img -public_folder: /img - -collections: - - name: 'blog' - label: 'Blog' - folder: 'content/blog' - create: true - slug: 'index' - media_folder: '' - public_folder: '' - path: '{{title}}/index' - editor: - preview: false - fields: - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { label: 'Description', name: 'description', widget: 'string' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -**Note:** The above configuration allows assets to be stored relative to their content. Therefore posts would be stored in the format below as it is in `gatsby-starter-blog`. - -```bash -content/ -├── blog -│ ├── first-post-title -│ │ ├── index.md -│ │ └── post-image.jpg -└── └── second-post-title - ├── index.md - └── post-image.jpg -``` - -Finally, add the plugin to your `gatsby-config.js`. - -```javascript -plugins: [`gatsby-plugin-netlify-cms`] -``` - -### Push to GitHub - -It's now time to commit your changes and push to GitHub. The Gatsby starter initializes Git automatically for you, so you only need to do: - -```bash -git add . -git commit -m "Initial Commit" -git remote add origin https://github.com/YOUR_USERNAME/NEW_REPO_NAME.git -git push -u origin main -``` - -### Add your repo to Netlify - -Go to Netlify and select 'New Site from Git'. Select GitHub and the repository you just pushed to. Click Configure Netlify on GitHub and give access to your repository. Finish the setup by clicking Deploy Site. Netlify will begin reading your repository and starting building your project. - -### Enable Identity and Git Gateway - -Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. -3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**. -4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/). - -## Start publishing - -It's time to create your first blog post. Login to your site's `/admin/` page and create a new post by clicking New Blog. Add a title, a date and some text. When you click Publish, a new commit will be created in your GitHub repo with this format `Create Blog “year-month-date-title”`. - -Then Netlify will detect that there was a commit in your repo, and will start rebuilding your project. When your project is deployed you'll be able to see the post you created. - -### Cleanup - -It is now safe to remove the default Gatsby blog posts. diff --git a/website/content/docs/git-gateway-backend.md b/website/content/docs/git-gateway-backend.md deleted file mode 100644 index 714dcd02..00000000 --- a/website/content/docs/git-gateway-backend.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: Git Gateway -weight: 10 -group: Accounts ---- - -[Git Gateway](https://github.com/netlify/git-gateway) is a Netlify open source project that allows you to add editors to your site CMS without giving them direct write access to your GitHub or GitLab repository. (For Bitbucket repositories, use the [Bitbucket backend](../bitbucket-backend/) instead.) - -## Git Gateway with Netlify - -The [Netlify Identity](https://www.netlify.com/docs/identity/) service can handle the authentication and provides a simple interface for user management. The Netlify CMS [featured templates](../start-with-a-template) are working examples of this backend. - -To use it in your own project stored on GitHub or GitLab, follow these steps: - -1. Head over to the [Netlify Identity docs](https://www.netlify.com/docs/identity) and follow the steps to get started. -2. Add the following lines to your Netlify CMS `config.yml` file: - -```yaml -backend: - name: git-gateway -``` - -## Reconnect after Changing Repository Permissions - -If you change ownership on your repository, or convert a repository from public to private, you may need to reconnect Git Gateway with proper permissions. Find further instructions in the [Netlify Git Gateway docs](https://www.netlify.com/docs/git-gateway/#reconnect-after-changing-repository-permissions). - -## Git Gateway without Netlify - -You can use [Git Gateway](https://github.com/netlify/git-gateway) without Netlify by setting up your own Git Gateway server and connecting it with your own instance of [GoTrue](https://www.gotrueapi.org) (the open source microservice that powers Netlify Identity), or with any other identity service that can issue JSON Web Tokens (JWT). - -To configure in Netlify CMS, use the same `backend` settings in your Netlify CMS `config.yml` file as described in Step 2 of the [Git Gateway with Netlify Identity](#git-gateway-with-netlify-identity) instructions above. diff --git a/website/content/docs/github-backend.md b/website/content/docs/github-backend.md deleted file mode 100644 index 264a9c81..00000000 --- a/website/content/docs/github-backend.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -group: Accounts -weight: 30 -title: GitHub ---- -For repositories stored on GitHub, the `github` backend allows CMS users to log in directly with their GitHub account. Note that all users must have push access to your content repository for this to work. - -Because Github [requires a server](https://github.com/netlify/netlify-cms/issues/663#issuecomment-335023723) for authentication, Netlify facilitates basic GitHub authentication. - -To enable basic GitHub authentication: - -1. Follow the authentication provider setup steps in the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider). -2. Add the following lines to your Netlify CMS `config.yml` file: - -```yaml -backend: - name: github - repo: owner-name/repo-name # Path to your GitHub repository - # optional, defaults to master - # branch: main -``` - -## Specifying a status for deploy previews - -The GitHub backend supports [deploy preview links](../deploy-preview-links). Netlify CMS checks the -`context` of a commit's [statuses](https://help.github.com/articles/about-status-checks/) and infers -one that seems to represent a deploy preview. If you need to customize this behavior, you can -specify which context to look for using `preview_context`: - -```yaml -backend: - name: github - repo: my/repo - preview_context: my-provider/deployment -``` - -The above configuration would look for the status who's `"context"` is `"my-provider/deployment"`. - -## Git Large File Storage (LFS) - -Please note that the GitHub backend **does not** support [git-lfs](https://git-lfs.github.com/), see [this issue](https://github.com/netlify/netlify-cms/issues/1206) for more information. diff --git a/website/content/docs/gitlab-backend.md b/website/content/docs/gitlab-backend.md deleted file mode 100644 index 5eef9e9b..00000000 --- a/website/content/docs/gitlab-backend.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: GitLab -group: Accounts -weight: 40 ---- -For repositories stored on GitLab, the `gitlab` backend allows CMS users to log in directly with their GitLab account. Note that all users must have push access to your content repository for this to work. - -**Note:** GitLab default branch is protected by default, thus typically requires `maintainer` permissions in order for users to have push access. - -The GitLab API allows for three types of OAuth2 flows: - -* [Authorization Code Flow](https://docs.gitlab.com/ce/api/oauth2.html#authorization-code-flow), which works much like the GitHub OAuth flow described above. -* [Authorization Code with PKCE Flow](https://docs.gitlab.com/ce/api/oauth2.html#authorization-code-with-proof-key-for-code-exchange-pkce), which operates *without* the need for an authentication server. -* (DEPRECATED [Implicit Grant Flow](https://docs.gitlab.com/ce/api/oauth2.html#implicit-grant-flow), which operates *without* the need for an authentication server. - -## Authorization Code Flow with Netlify - -When using GitLab's Authorization Code Flow for authentication, you can use Netlify to handle the server-side authentication requests. - -To enable it: - -1. Follow the [GitLab docs](https://docs.gitlab.com/ee/integration/oauth_provider.html#adding-an-application-through-the-profile) to add your Netlify CMS instance as an OAuth application. For the **Redirect URI**, enter `https://api.netlify.com/auth/done`, and check the box for `api` scope. -2. Follow the [Netlify docs](https://www.netlify.com/docs/authentication-providers/#using-an-authentication-provider) to add your new GitLab Application ID and Secret to your Netlify site dashboard. -3. In your repository, add the following lines to your Netlify CMS `config.yml` file: - -```yaml -backend: - name: gitlab - repo: owner-name/repo-name # Path to your GitLab repository -``` - - -## Client-Side PKCE Authorization - -With GitLab's PKCE authorization, users can authenticate with GitLab directly from the client. To do this: - -1. Follow the [GitLab docs](https://docs.gitlab.com/ee/integration/oauth_provider.html#adding-an-application-through-the-profile) to add your Netlify CMS instance as an OAuth application and uncheck the **Confidential** checkbox. For the **Redirect URI**, enter the address where you access Netlify CMS, for example, `https://www.mysite.com/admin/`. For scope, select `api`. -2. GitLab gives you an **Application ID**. Copy this ID and enter it in your Netlify CMS `config.yml` file, along with the following settings: - - ```yaml - backend: - name: gitlab - repo: owner-name/repo-name # Path to your GitLab repository - auth_type: pkce # Required for pkce - app_id: your-app-id # Application ID from your GitLab settings - ``` - - You can also use PKCE Authorization with a self-hosted GitLab instance. This requires adding `api_root`, `base_url`, and `auth_endpoint` fields: - - ```yaml - backend: - name: gitlab - repo: owner-name/repo-name # Path to your GitLab repository - auth_type: pkce # Required for pkce - app_id: your-app-id # Application ID from your GitLab settings - api_root: https://my-hosted-gitlab-instance.com/api/v4 - base_url: https://my-hosted-gitlab-instance.com - auth_endpoint: oauth/authorize - ``` - -## (DEPRECATED) Client-Side Implicit Grant - -**Note:** This method is not recommended and will be deprecated both [by GitLab](https://gitlab.com/gitlab-org/gitlab/-/issues/288516) and [in the OAuth 2.1 specification](https://oauth.net/2.1/) in the future. - -With GitLab's Implicit Grant, users can authenticate with GitLab directly from the client. To do this: - -1. Follow the [GitLab docs](https://docs.gitlab.com/ee/integration/oauth_provider.html#adding-an-application-through-the-profile) to add your Netlify CMS instance as an OAuth application and uncheck the **Confidential** checkbox. For the **Redirect URI**, enter the address where you access Netlify CMS, for example, `https://www.mysite.com/admin/`. For scope, select `api`. -2. GitLab gives you an **Application ID**. Copy this ID and enter it in your Netlify CMS `config.yml` file, along with the following settings: - - ```yaml - backend: - name: gitlab - repo: owner-name/repo-name # Path to your GitLab repository - auth_type: implicit # Required for implicit grant - app_id: your-app-id # Application ID from your GitLab settings - ``` - - You can also use Implicit Grant with a self-hosted GitLab instance. This requires adding `api_root`, `base_url`, and `auth_endpoint` fields: - - ```yaml - backend: - name: gitlab - repo: owner-name/repo-name # Path to your GitLab repository - auth_type: implicit # Required for implicit grant - app_id: your-app-id # Application ID from your GitLab settings - api_root: https://my-hosted-gitlab-instance.com/api/v4 - base_url: https://my-hosted-gitlab-instance.com - auth_endpoint: oauth/authorize - ``` - -**Note:** In all cases, GitLab also provides you with a client secret. You should *never* store this in your repo or reveal it in the client. diff --git a/website/content/docs/gridsome.md b/website/content/docs/gridsome.md deleted file mode 100644 index a59fd540..00000000 --- a/website/content/docs/gridsome.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -group: Guides -weight: 70 -title: Gridsome ---- -This guide will help you get started using Netlify CMS and Gridsome. - -## How to install Gridsome -### 1. Install Gridsome CLI tool - -```bash -# Using Yarn -yarn global add @gridsome/cli - -# Using NPM -npm install --global @gridsome/cli -``` - -## Create a new Gridsome website - -```bash -# To create a new project run -gridsome create gridsome-netlify-blog - -# Then navigate to the project folder -cd gridsome-netlify-blog - -# To start local dev server at http://localhost:8080 -gridsome develop -``` - -### Install Netlify CMS the required dependencies to your project - -```bash - -# Using Yarn -yarn add netlify-cms gridsome-plugin-netlify-cms @gridsome/source-filesystem @gridsome/transformer-remark - -# Using NPM -npm add netlify-cms gridsome-plugin-netlify-cms @gridsome/source-filesystem @gridsome/transformer-remark -``` - -Now that the plugins are installed, it's time to setup the configuration. Open the `gridsome.config.js` file and update its content to: - -```js -module.exports = { - siteName: 'Gridsome', - transformers: { - remark: { - externalLinksTarget: '_blank', - externalLinksRel: ['nofollow', 'noopener', 'noreferrer'], - anchorClassName: 'icon icon-link' - } - }, - - plugins: [ - { - use: '@gridsome/source-filesystem', - options: { - path: 'posts/**/*.md', - typeName: 'Post' - } - }, - { - use: `gridsome-plugin-netlify-cms`, - options: { - publicPath: `/admin` - } - }, - ] -} -``` - -Please read [gridsome-plugin-netlify-cms](https://gridsome.org/plugins/gridsome-plugin-netlify-cms), [transformer-remark](https://gridsome.org/plugins/@gridsome/transformer-remark) for more information. - -## Netlify CMS setup - -1. Create an `admin` directory inside the `src` -2. Create an `uploads` directory inside the root of your project -3. Add `index.html`, `index.js` and a `config.yml` file to your `admin` directory - -Your `index.html` should look like this: - -```html - - - - - - Netlify CMS - - - - - -``` - -Your `index.js` should look like this: - -```js -import CMS from "netlify-cms" -``` - -Your `config.yml` for GitHub should look like this: - -```yml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) - -media_folder: "static/uploads" -public_folder: "/uploads" - -collections: - - name: "posts" - label: "Posts" - folder: "posts" - create: true - slug: "{{slug}}" - fields: - - {label: "Title", name: "title", widget: "string"} - - {label: "Excerpt", name: "excerpt", widget: "string"} - - {label: "Publish Date", name: "date", widget: "datetime"} - - {label: "Body", name: "body", widget: "markdown"} -``` - -## Push to GitHub - -It's now time to commit your changes and push to GitHub. - -```bash -git init -git add . -git commit -m "Initial Commit" -git remote add origin https://github.com/YOUR_USERNAME/NEW_REPO_NAME.git -git push -u origin main -``` - -### Add your repo to Netlify - -Go to Netlify and select 'New Site from Git'. Select GitHub and the repository you just pushed to. Click Configure Netlify on GitHub and give access to your repository. Finish the setup by clicking Deploy Site. Netlify will begin reading your repository and starting building your project. - -### Enable Identity and Git Gateway - -Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. -3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**. -4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/). - - -## Start publishing - -It's time to create your first blog post. Login to your site's `/admin/` page and create a new post by clicking New Blog. Add a title, a date and some text. When you click Publish, a new commit will be created in your GitHub repo with this format `Create Blog “year-month-date-title”`. - -Then Netlify will detect that there was a commit in your repo, and will start rebuilding your project. When your project is deployed you'll be able to see the post you created. - -Your basic blog scaffold is done, now you can query data from the GraphQL server just like you're working with the filesystem. For more info read [querying data](https://gridsome.org/docs/querying-data). diff --git a/website/content/docs/hugo.md b/website/content/docs/hugo.md deleted file mode 100644 index 89a05cca..00000000 --- a/website/content/docs/hugo.md +++ /dev/null @@ -1,246 +0,0 @@ ---- -title: Hugo -group: Guides -weight: 20 ---- -## Introduction - -This guide will walk you through how to integrate Netlify CMS with Hugo. This is a good place to start if you want to learn from the ground up how these two tools work together. If you want to get up-and-running quicker, you can use one of the pre-existing and amazing [starter templates](/docs/start-with-a-template/)! - -## Getting started with Hugo - -### Installation - -To get started with Hugo, you should first install the command line tool. If you've already got it installed, you can [skip this step](#creating-a-new-site). On MacOS and Linux you can do this with: - -```bash -brew install hugo -``` - -To test that it's successfully installed, you can try this command, to get a list of Hugo's options: - -```bash -hugo help -``` - -### Creating a new site - -Create a new Hugo project and start it up using the following commands. - -```bash -hugo new site -cd -hugo server -``` - -You won't actually see anything, just yet, and that's because you don't have any template files. That's easily resolved. In the `layouts/` directory, create a file `index.html` and put a basic HTML structure in there: - -```html - - - - - - - Document - - -

    Nice. It's looking good already.

    - - -``` - -You'll also add some files to the `content/` and `data/` directories to make sure git tracks them. - -```bash -touch content/.keep data/.keep -``` - -This is as basic as you can get with a Hugo project. There's just enough here now for us to install Netlify CMS. - -## Getting Started With Netlify CMS - -### Add the Netlify CMS files to Hugo - -In Hugo, static files that don't need to be processed by the build commands live in the `static/` directory. You'll install the Netlify CMS admin and config files there. Create a directory `admin/` and within it, create two files `index.html` and `config.yml`. In the `index.html`, add the following content: - -```html - - - - - - Content Manager - - - - - - - - -``` - -In the `config.yml` file, you can add this basic configuration — you can customize as you see fit, this sample file is just to get you started. - -```yaml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) -media_folder: static/img -public_folder: /img -collections: - - name: 'blog' - label: 'Blog' - folder: 'content/blog' - create: true - slug: '{{year}}-{{month}}-{{day}}-{{slug}}' - editor: - preview: false - fields: - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { label: 'Description', name: 'description', widget: 'string' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -**Note:** You won't be able to access the CMS just yet — you still need to deploy the project with **Netlify** and authenticate with **Netlify Identity**. You'll handle this in the next few steps of this guide. - -### Pushing to GitHub - -It's now time to commit your changes and push to GitHub. You can run the following commands to initialize a git repository and push the changes so far. - -```bash -git init # Initialize a git repository -git add . # Add every file -git commit -m "Initial Commit" # Commit every file with the message 'Initial Commit' -git remote add origin https://github.com/YOUR_USERNAME/NEW_REPO_NAME.git # Create a new repo on GitHub and add it to this project as a remote repository. -git push -u origin main # Push your changes -``` - -### Deploying With Netlify - -Now you can go ahead and deploy to Netlify. Go to your Netlify dashboard and click **[New site from Git](https://app.netlify.com/start)**. Select the repo you just created. Under **Basic build settings**, you can set the build command to `hugo` and the publish directory to `public`. Click **Deploy site** to get the process going. - -### Authenticating with Netlify Identity - -**Add the Netlify Identity Widget** - -You've already added the Netlify Identity widget to our `admin/index.html`. The next thing to do is add the Netlify Identity widget to our site's index page. In `layouts/index.html`, we can add the following to the `` tag on the page: - -```html - -``` - -Once you've added this, make sure to push your changes to GitHub! - -### Enable Identity & Git Gateway in Netlify - -Back in your [Netlify dashboard](https://app.netlify.com/): - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Once enabled, select **Settings and usage**, and scroll down to **Registration preferences**. You can set this to either **Open** or **Invite only**, but usually **Invite only** is your best bet for a personal site. -3. If you don't want to create an account, or would like to use an external provider such as GitHub or Google, you can enable those services under **External providers**. -4. Scroll down to **Services** and click **Enable Git Gateway**. - -### Accessing the CMS - -Once you've reached this point, you should be able to access the CMS in your browser at `http://localhost:1313/admin`. You'll be prompted to add the URL of your Netlify site. Once you've added that URL, you can log in with an Identity account or with one of the External Providers you enabled in step 3 above. For the sake of this tutorial, you can create a blog post in the CMS, and publish it! Once you `git pull` in your project, the blog post will show up in the project at `content/blog/.md`. - -And that's it! From this point on, it's just a matter of following [the Hugo documentation](https://gohugo.io/templates/) for outputting the content from your `content/` directory into templates! For more information on configuring Netlify CMS, feel free to check out the [Netlify CMS configuration options documentation](/docs/configuration-options/). - -## Using Netlify CMS content in Hugo - -### Creating a list of posts - -In your `layouts/index.html` file, you'll create an unordered list element and use a Hugo `range` to output all posts. Inside that range, you can add a list item element with each post title and a link to the post inside it. - -**Note:** To learn more about Hugo's `range` function, check out [the Hugo documentation](https://gohugo.io/functions/range). - -```html - -

    Nice. It's looking good already.

    - - -``` - -That link won't work just right just yet. You'll need to make a single page layout for blog posts, so Hugo can create a page for the `.RelPermalink` to link to. - -### Creating a single page post layout - -Create a file `layouts/blog/single.html`, and put the following content in there: - -```html - - - - - - - {{ .Title }} - - -

    {{ .Title }}

    -

    {{ .Date }}

    -

    {{ .Params.description }}

    -
    - {{ .Content }} -
    - - -``` - -You can see this basic template includes all the fields you've specified in your Netlify CMS `config.yml` file. You can access any custom front-matter fields with `.Params.`! - -### Using Hugo shortcodes in the Markdown Editor - -Using `registerEditorComponent` we can register a block level component for the Markdown editor. You can use it to add Hugo's inbuilt shortcodes like `gist`,`youtube` and others as block components to the markdown editor. - -You can refer to [registering editor components](https://www.netlifycms.org/docs/custom-widgets/#registereditorcomponent) for a getting started guide or for creating your own editor components. - -**Example** - -```javascript -CMS.registerEditorComponent({ - id: "gist", - label: "Gist", - fields: [{ - name: "username", - label: "Github Username", - widget: "string" - }, - { - name: "gid", - label: "Gist ID", - widget: "string" - }, - ], - pattern: /^{{< gist ([a-zA-Z0-9]+) ([a-zA-Z0-9]+) >}}/, - fromBlock: function(match) { - return { - username: match[1], - gid: match[2], - }; - }, - toBlock: function(obj) { - return `{{< gist ${obj.username} ${obj.gid} >}}`; - }, - toPreview: function(obj) { - return 'gist'; - }, -}); -``` - -**Result** - -![Gist](/img/hugo_shortcode_gist.png "Gist") - -For getting started quickly you can refer to this amazing prebuilt resource of [hugo shortcodes editor components](https://github.com/sharadcodes/hugo-shortcodes-netlify-cms)! diff --git a/website/content/docs/intro.md b/website/content/docs/intro.md deleted file mode 100755 index 039aebfe..00000000 --- a/website/content/docs/intro.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -title: Overview -group: Intro -weight: 1 ---- - -Netlify CMS is an open source content management system for your Git workflow that enables you to provide editors with a friendly UI and intuitive workflows. You can use it with any static site generator to create faster, more flexible web projects. Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git. - -At its core, Netlify CMS is an open-source React app that acts as a wrapper for the Git workflow, using the GitHub, GitLab, or Bitbucket API. This provides many advantages, including: - -* **Fast, web-based UI:** With rich-text editing, real-time preview, and drag-and-drop media uploads. -* **Platform agnostic:** Works with most static site generators. -* **Easy installation:** Add two files to your site and hook up the backend by including those files in your build process or linking to our Content Delivery Network (CDN). -* **Modern authentication:** Using GitHub, GitLab, or Bitbucket and JSON web tokens. -* **Flexible content types:** Specify an unlimited number of content types with custom fields. -* **Fully extensible:** Create custom-styled previews, UI widgets, and editor plugins. - -## Netlify CMS vs. Netlify - -[Netlify.com](https://www.netlify.com/) is a platform you can use to automatically build, deploy, serve, and manage your frontend sites and web apps. It also provides a variety of other features like form processing, serverless functions, and split testing. Not all Netlify sites use Netlify CMS, and not all sites using Netlify CMS are on Netlify. - -The folks at Netlify created Netlify CMS to fill a gap in the static site generation pipeline. There were some great proprietary headless CMS options, but no real contenders that were open source and extensible—that could turn into a community-built ecosystem like WordPress or Drupal. For that reason, Netlify CMS is _made_ to be community-driven, and has never been locked to the Netlify platform (despite the name). - -With this in mind, you can: - -* Use Netlify CMS without Netlify and deploy your site where you always have, hooking up your own CI, site hosting, CDN, etc. -* Use Netlify without Netlify CMS and edit your static site in your code editor. -* Or, use them together and have a fully-working CMS-enabled site with [one click](../start-with-a-template/)! - -If you hook up Netlify CMS to your website, you're basically adding a tool for content editors to make commits to your site repository without touching code or learning Git. - -### Find out more - -- Get a feel for the UI in the [demo site](https://cms-demo.netlify.com). (No login required. Click the login button to go straight to the CMS editor UI.) -- [Start with a template](../start-with-a-template/) to make a Netlify CMS-enabled site of your own. -- Configure your existing site by following a [tutorial](../add-to-your-site/) or checking [configuration options](../configuration-options). -- Ask questions and share ideas in the Netlify CMS [community chat](https://netlifycms.org/chat). -- Get involved in new developments and become a [contributor](../contributor-guide/). diff --git a/website/content/docs/jekyll.md b/website/content/docs/jekyll.md deleted file mode 100644 index 6b41eb1e..00000000 --- a/website/content/docs/jekyll.md +++ /dev/null @@ -1,299 +0,0 @@ ---- -group: Guides -weight: 30 -title: Jekyll ---- -## Introduction - -This section will help you integrate Netlify CMS with a new or existing Jekyll project. - -[Jekyll](https://jekyllrb.com/) is a blog-aware static site generator built with Ruby. [Github Pages](https://pages.github.com/) are powered by Jekyll, making it a popular choice for developer blogs and project pages. - -If you're starting a new project, the fastest route to publishing on a Jekyll website with Netlify CMS is to [deploy a template on Netlify](https://templates.netlify.com/). - -## Setup - -This guide will use the blog you get if you follow the [really excellent official Jekyll step by step tutorial](https://jekyllrb.com/docs/step-by-step/01-setup/) as a starting point. If you're new to Jekyll - I recommended you start by following the tutorial so you know your way around your new blog. Otherwise [you can clone this repo](https://github.com/adamwatters/jekyll-tutorial-with-netlify-cms/tree/without-cms) and checkout the `without-cms` branch. - -![Jekyll tutorial blog screenshot](https://www.netlifycms.org/img/screenshot-jekyll-tutorial-blog.png?raw=true) - -## Add Netlify CMS - -### Add admin/index.html - -Create a file `admin/index.html` in the root of your repo - it should look like this: - -```html - - - - - - - Content Manager - - - - - - - - -``` - -### Add admin/config.yml - -Create a file `admin/config.yml` in the root of your repo - it should look like this: - -```yml -# config.yml - -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) -media_folder: 'assets/uploads' -collections: - - name: 'blog' - label: 'Blog' - folder: '_posts/' - fields: - - { name: Title } -``` - -### Enable authentication for CMS users - -Netlify CMS stores content in your online Git repository. Therefore, to make content changes, users need to authenticate with the corresponding Git provider to prove that they have read and write access to that content. - -Follow the directions in the Introduction section to [enable Netlify Identity and Git Gateway services](https://www.netlifycms.org/docs/add-to-your-site/#enable-identity-and-git-gateway) for the backend, then [add the Identity widget](https://www.netlifycms.org/docs/add-to-your-site/#add-the-netlify-identity-widget) to render a login portal on the frontend. - -## CMS Configuration - -### Blog Collection - -We'll start by updating the `blog` collection. Blogging is baked into Jekyll, and the `_posts/` directory uses [some special conventions](https://jekyllrb.com/docs/posts/) we'll need to keep in mind as we configure Netlify CMS. Copy and paste the following into your `config.yml`. - -```yaml -collections: - - name: 'blog' - label: 'Blog' - folder: '_posts/' - create: true - slug: '{{year}}-{{month}}-{{day}}-{{slug}}' - editor: - preview: false - fields: - - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' } - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -A few things to note. - -* We set the `slug` to `'{{year}}-{{month}}-{{day}}-{{slug}}'` because [Jekyll requires this format for blog posts](https://jekyllrb.com/docs/posts/#creating-posts). `year`, `month`, and `day` will be extracted from the `date` field, and `slug` will be generated from the `title` field. -* We added `editor` configuration with a field `preview: false`. This will eliminate the preview pane. Because Jekyll uses Liquid templates, there currently isn't a good way to provide a preview of pages as you update the content. -* The `layout` field default is set to `post` so Jekyll knows to use `_layouts/post.html` when it renders a post. This field is hidden because we want all posts to use the same layout. -* The `date` and `title` field will be used by the `slug` - as noted above, Jekyll relies on the filename to determine a post's publish date, but Netlify CMS does not pull date information from the filename and requires a frontmatter `date` field. **Note** Changing the `date` or `title` fields in Netlify CMS will not update the filename. This has a few implications: - - * If you change the `date` or `title` fields in Netlify CMS, Jekyll won't notice - * You don't necessarily need to change the `date` and `title` fields for existing posts, but if you don't the filenames and frontmatter will disagree in a way that might be confusing - * If you want to avoid these issues, use a regular Jekyll collection instead of the special `_posts` directory - -### Author Collection - -In addition to `_posts`, the Jekyll tutorial blog includes a collection of authors in the `_authors` directory. Before we can configure Netlify CMS to work with the `authors` collection, we'll need to make a couple tweaks to our Jekyll blog. Here's the front matter for one of the authors. - -```yaml -short_name: jill -name: Jill Smith -position: Chief Editor -``` - -`name` has special meaning as a unique identifier in Netlify CMS, but as set up now our Jekyll blog is using `short_name` as the unique identifier for authors. For each author, update the frontmatter like so. - -```yaml -name: jill -display_name: Jill Smith -position: Chief Editor -``` - -then update `_layouts/author.html`, `_layouts/post.html` and `staff.html` accordingly. - -```html - ---- layout: default --- - -

    {{ page.display_name }}

    -

    {{ page.position }}

    - -{{ content }} - -

    Posts

    -
      - {% assign filtered_posts = site.posts | where: 'author', page.name %} {% for post in - filtered_posts %} -
    • - {{ post.title }} -
    • - {% endfor %} -
    -``` - -```html - ---- layout: default --- - -

    {{ page.title }}

    - -

    - {{ page.date | date_to_string }} {% assign author = site.authors | where: 'name', page.author | - first %} {% if author %} - {{ author.display_name }} - {% endif %} -

    - -{{ content }} -``` - -```html - ---- layout: default --- - -

    Staff

    - -
      - {% for author in site.authors %} -
    • -

      - {{ author.display_name }} -

      -

      {{ author.position }}

      -

      {{ author.content | markdownify }}

      -
    • - {% endfor %} -
    -``` - -Next, copy and paste the following into the collections array in `config.yml` below the `blog` collection. - -```yaml -- name: 'authors' - label: 'Authors' - folder: '_authors/' - create: true - editor: - preview: false - fields: - - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'author' } - - { label: 'Short Name', name: 'name', widget: 'string' } - - { label: 'Display Name', name: 'display_name', widget: 'string' } - - { label: 'Position', name: 'position', widget: 'string' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -Now that we have the `authors` collection configured, we can add an `author` field to the `blog` collection. We'll use the [relation widget](https://www.netlifycms.org/docs/widgets/#relation) to define the relationship between blog posts and authors. - -```yaml -# updated fields in blog collection configuration -fields: - - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'post' } - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { - label: 'Author', - name: 'author', - widget: 'relation', - collection: 'authors', - display_fields: [display_name], - search_fields: [display_name], - value_field: 'name', - } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -With that configuration added, you should be able to select the author for a post from a dropdown. - -### About Page - -Our Jekyll blog includes an About page. It would nice to be able to edit that page just like we can edit our blog and author pages. Netlify CMS provides [file collections](https://www.netlifycms.org/docs/collection-types/#file-collections) to solve this problem. - -Copy and paste the following into the collections array in `config.yml` - -```yaml -- name: 'pages' - label: 'Pages' - editor: - preview: false - files: - - label: 'About Page' - name: 'about' - file: 'about.md' - fields: - - { label: 'Title', name: 'title', widget: 'hidden', default: 'about' } - - { label: 'Layout', name: 'layout', widget: 'hidden', default: 'about' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -### Navigation - -The last aspect of our Jekyll blog we might want to bring under the control of Netlify CMS is our Navigation menu. Our Jekyll tutorial blog has a file `_data/navigation.yml` that defines the links rendered by `_includes/navigation.html`. It looks like this. - -```yaml -# _data/navigation.yml -- name: Home - link: / -- name: About - link: /about.html -- name: Blog - link: /blog.html -- name: Staff - link: /staff.html -``` - -To make this file editable with Netlify CMS, we'll need to make one minor tweak. The issue is this file contains a yaml array at the top level, but Netlify CMS is designed to work with yaml objects. Update `_data/navigation.yml` so it looks like so. - -```yaml -# _data/navigation.yml -items: - - name: Home - link: / - - name: About - link: /about.html - - name: Blog - link: /blog.html - - name: Staff - link: /staff.html -``` - -You'll need to update `_includes/navigation.html` accordingly. `{% for item in site.data.navigation %}` should be changed to `{% for item in site.data.navigation.items %}`. When you're done, the nav html should look like this. - -```html - -``` - -Finally, add the following to the collections array in `config.yml` - -```yaml -- name: 'config' - label: 'Config' - editor: - preview: false - files: - - label: 'Navigation' - name: 'navigation' - file: '_data/navigation.yml' - fields: - - label: 'Navigation Items' - name: 'items' - widget: 'list' - fields: - - { label: Name, name: name, widget: string } - - { label: Link, name: link, widget: string } -``` - -Now you can add, rename, and rearrange the navigation items on your blog. \ No newline at end of file diff --git a/website/content/docs/middleman.md b/website/content/docs/middleman.md deleted file mode 100644 index 1f6e4f97..00000000 --- a/website/content/docs/middleman.md +++ /dev/null @@ -1,180 +0,0 @@ ---- -title: Middleman -group: Guides -weight: 60 ---- -This guide will help you get started using Netlify CMS and Middleman. - -## Installation -To get up and running with Middleman, you need both the Ruby language runtime and RubyGems installed on your computer. Check out the [Middleman installation docs](https://middlemanapp.com/basics/install/) for more details. If you already have your environment set up, use the following command to install Middleman: - -```bash -gem install middleman -``` - -## Create a new Middleman site -Let's create a new site from scratch. Run the following commands in the terminal, in the folder where you'd like to create the blog: - -```bash -middleman init blog -cd blog -``` - -### Add the Middleman blog extension -Middleman has an official extension to support blogging, articles and tagging. `middleman-blog` ships as an extension and must be installed to use. Simply specify the gem in your Gemfile: - -```bash -gem "middleman-blog" -``` -Install the dependencies and run Middleman with the following commands: - -```bash -bundle install -middleman server -``` - -## Get started with Middleman - -Now we have our site up and running let's open up a code editor and create a new folder `source/posts` and add your first article named `2019-01-01-example-article.html.md` with the following content: - - -```yml ---- -title: Example Article -date: 2019-01-01 ---- - -This is an example article. You probably want to delete it and write your own articles once you finished this guide! -``` - -### Activate the blog extension -We can then activate the blog in `config.rb`. Be sure to check out the [Middleman blogging docs](https://middlemanapp.com/basics/blogging/) for all the configuration options. - -```bash -activate :blog do | blog | - blog.permalink = "blog/{title}.html" - blog.sources = "posts/{year}-{month}-{day}-{title}.html" - blog.layout = "blog-layout" -end -``` - -### Load the articles -Time to load our articles in `index.html.erb`. - -```ruby -

    Recent articles

    - -<% blog.articles.each do | article | %> -
    -

    - <%= article.title %> -

    - - <%= link_to 'Read more', article %> -
    - -<% end %> -``` - -### Add an article layout -In the last step before we add Netlify CMS, we add a layout for the article page. Create a new layout `source/layouts/blog-layout.html.erb`. For now we will get the title and the content: -```ruby -

    - <%= current_page.data.title %> -

    - -<%= yield %> -``` - -Now that we have a functioning blog, let's get started with Netlify CMS! - -## Add Netlify CMS to your site - -Create two files in a new folder called `admin`, `index.html` and `config.yml`. Also add an `upload` folder in the images directory that will function as our `media_folder`. -```bash -├── source -│ ├── admin -│ │ ├── index.html -│ │ ├── config.yml -│ │ -│ ├── images -│ │ ├── uploads -``` - - -In the newly created `index.html` we add scripts for Netlify CMS and the Netlify Identity Widget: - -```html - - - - - - - Netlify CMS - - - - - - - -``` - -### Configuration - -For the purpose of this guide we will deploy to Netlify from a GitHub repository which requires the minimum configuration. In `config.yml` file paste the following code: - -```yml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) - -media_folder: source/images/uploads -public_folder: /images/uploads - -collections: - - name: blog - label: Blog - folder: source/posts/ - extension: .html.md - format: frontmatter - create: true - slug: '{{year}}-{{month}}-{{day}}-{{title}}' - fields: - - {label: Title, name: title, widget: string} - - {label: Publish Date, name: date, widget: datetime} - - {label: Body, name: body, widget: markdown} -``` - -### Push to GitHub -It's now time to commit your changes and push to GitHub. - -```bash -git init -git add . -git commit -m "Initial Commit" -git remote add origin https://github.com/YOUR_USERNAME/NEW_REPO_NAME.git -git push -u origin main -``` - -### Add your repo to Netlify - -Go to Netlify and select 'New Site from Git'. Select GitHub and the repository you just pushed to. Click Configure Netlify on GitHub and give access to your repository. Finish the setup by clicking Deploy Site. Netlify will begin reading your repository and starting building your project. - -### Enable Identity and Git Gateway - -Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. -3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**. -4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/). - -## Start publishing - -It's time to create your first blog post. Login to your site's `/admin/` page and create a new post by clicking New Blog. Add a title, a date and some text. When you click Publish, a new commit will be created in your GitHub repo with this format `Create Blog “year-month-date-title”`. - -Then Netlify will detect that there was a commit in your repo, and will start rebuilding your project. When your project is deployed you'll be able to see the post you created. - -Be sure to checkout the official [Middleman Starter](https://github.com/tomrutgers/middleman-starter-netlify-cms) for more examples. diff --git a/website/content/docs/netlify-large-media.md b/website/content/docs/netlify-large-media.md deleted file mode 100644 index 34b71e16..00000000 --- a/website/content/docs/netlify-large-media.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -title: Netlify Large Media -group: Media -weight: 20 ---- - -[Netlify Large Media](https://www.netlify.com/features/large-media/) is a [Git LFS](https://git-lfs.github.com/) implementation for repositories connected to Netlify sites. This means that you can use Git to work with large asset files like images, audio, and video, without bloating your repository. It does this by replacing the asset files in your repository with text pointer files, then uploading the assets to the Netlify Large Media storage service. - -If you have a Netlify site with Large Media enabled, Netlify CMS (version 2.6.0 and above) will handle Large Media asset files seamlessly, in the same way as files stored directly in the repository. - -## Requirements - -To use Netlify Large Media with Netlify CMS, you will need to do the following: - -- [Upgrade Netlify CMS](/docs/update-the-cms-version/) to version 2.6.0 or above. -- Configure Netlify CMS to use the [Git Gateway backend with Netlify Identity](/docs/git-gateway-backend/#git-gateway-with-netlify-identity). -- Configure the Netlify site and connected repository to use Large Media, following the [Large Media docs on Netlify](https://www.netlify.com/docs/large-media/). - -When these are complete, you can use Netlify CMS as normal, and the configured asset files will automatically be handled by Netlify Large Media. - -## Image transformations - -All JPEG, PNG, and GIF files that are handled with Netlify Large Media also have access to Netlify's on-demand image transformation service. This service allows you to request an image to match the dimensions you specify in a query parameter added to the image URL. - -You can learn more about this feature in [Netlify's image transformation docs](https://www.netlify.com/docs/image-transformation/). - -### Transformation control for media gallery thumbnails - -In repositories enabled with Netlify Large Media, Netlify CMS will use the image transformation query parameters to load thumbnail-sized images for the media gallery view. This makes images in the media gallery load significantly faster. - -**Note:** When using this option all tracked file types have to be imported into Large Media. For example if you track `*.jpg` but still have jpg-files that are not imported into Large Media the backend will throw an error. Check the [netlify docs](https://docs.netlify.com/large-media/setup/#migrate-files-from-git-history) on how to add previously committed files to Large Media. - -You can disable the automatic image transformations with the `use_large_media_transforms_in_media_library` configuration setting, nested under `backend` in the CMS `config.yml` file: - -```yaml -backend: - name: git-gateway - ## Set to false to prevent transforming images in media gallery view - use_large_media_transforms_in_media_library: false -``` diff --git a/website/content/docs/nextjs.md b/website/content/docs/nextjs.md deleted file mode 100644 index f2992faa..00000000 --- a/website/content/docs/nextjs.md +++ /dev/null @@ -1,234 +0,0 @@ ---- -group: Guides -weight: 40 -title: NextJS ---- -This guide will help you get started using Netlify CMS with NextJS. - -## Creating a new project - -Let's repeat some of the basics of setting up a simple NextJS project (check out [nextjs.org/learn](http://nextjs.org/learn) for a more detailed version). - -```bash -# Create new directory and navigate into it -mkdir awesome-kitties -cd awesome-kitties - -# Initialize a new project -npm init -y - -# Install required dependencies -npm install --save react react-dom next - -# Install webpack loader for Markdown (Use version 3+) -npm install --save-dev frontmatter-markdown-loader - -# If using NextJS v11.0.0 or above, @babel/core and @babel/preset-react has to be installed as dependencies of frontmatter-markdown-loader -npm install --save-dev @babel/core @babel/preset-react - -# Create folder for pages (default for NextJS), and add a index file -mkdir pages -touch pages/index.js - -# Create a folder for content, and a markdown file: -mkdir content -touch content/home.md - -# Create a folder for static assets -mkdir public -``` - -Next, we need to add some modifications to our `package.json` file to make it easier to run and deploy our new site: - -```json -{ - "scripts": { - "dev": "next", - "build": "next build", - "start": "next start", - "export": "npm run build && next export" - } -} -``` - -There is a lot of different ways to create and display Markdown content, but to make this as easy as possible we'll be using a webpack-loader that enables us to load markdown files directly in our React components ([frontmatter-markdown-loader](https://www.npmjs.com/package/frontmatter-markdown-loader)). - -Add the following content to your `content/home.md` file: - -```md ---- -title: Awesome kitties -date: 2019-03-17T19:31:20.591Z -cats: - - description: 'Maru is a Scottish Fold from Japan, and he loves boxes.' - name: Maru (まる) - - description: Lil Bub is an American celebrity cat known for her unique appearance. - name: Lil Bub - - description: 'Grumpy cat is an American celebrity cat known for her grumpy appearance.' - name: Grumpy cat (Tardar Sauce) ---- -Welcome to my awesome page about cats of the internet. - -This page is built with NextJS, and content is managed in Netlify CMS -``` - -Next, we need to tell webpack how to load Markdown files. Create a new `next.config.js` file at the root of your project with the following content: - -```js -module.exports = { - webpack: (cfg) => { - cfg.module.rules.push( - { - test: /\.md$/, - loader: 'frontmatter-markdown-loader', - options: { mode: ['react-component'] } - } - ) - return cfg; - } -} -``` - -Almost there! The last thing we need to do is to add some content to our `pages/index.js` file. With a little help of our webpack loader, we can now easily import Markdown files: - -```js -import Head from "next/head" -import { Component } from 'react' -import { attributes, react as HomeContent } from '../content/home.md'; - -export default class Home extends Component { - render() { - let { title, cats } = attributes; - return ( - <> - - - -
    -

    {title}

    - -
      - {cats.map((cat, k) => ( -
    • -

      {cat.name}

      -

      {cat.description}

      -
    • - ))} -
    -
    - - ) - } -} -``` - -Great! We now have a page that displays content from our Markdown file. Go ahead and start your development server to test if everything is working: - -```bash -npm run dev -``` - -## Adding Netlify CMS - -There are many different ways to add Netlify CMS to your project. The easiest is probably just to embed it from a CDN, and that's exactly what we're gonna do. To avoid making this guide too complicated, we're just going to add Netlify into a subfolder inside the `/public` directory (which is just served as static files by Next): - -```bash -# Create and navigate into public/admin folder -mkdir -p public/admin -cd public/admin - -# Create index.html and config.yml file -touch index.html -touch config.yml -``` - -Paste HTML for Netlify CMS into your `public/admin/index.html` file (check out the [Add Netlify To Your Site](https://www.netlifycms.org/docs/add-to-your-site/) section for more information) - -```html - - - - - - Content Manager - - - - - - - -``` - -Notice that we also added the identity widget. This allows sign up when the project is hosted at Netlify. - -Paste the following configuration into your `public/admin/config.yml` file: - -```yaml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) -media_folder: public/img -public_folder: img -collections: - - name: "pages" - label: "Pages" - files: - - label: "Home" - name: "home" - file: "content/home.md" - fields: - - { label: "Title", name: "title", widget: "string"} - - { label: "Publish Date", name: "date", widget: "datetime" } - - { label: "Body", name: "body", widget: "markdown"} - - label: 'Cats' - name: "cats" - widget: list - fields: - - { label: "Name", name: "name", widget: "string"} - - { label: "Description", name: "description", widget: "text"} -``` - -Awesome! Netlify CMS should now be available at `localhost:3000/admin/index.html`. Unfortunately we can't edit our content just yet. First we need to move our code into a git repository, and create a new Netlify site. - -**Tip:** If you want to test changes made to your config.yml file locally, swap out "git-gateway" with "test-repo" and navigate to `localhost:3000/admin/index.html` to view Netlify CMS locally (you can't make changes or read actual content from Git this way, but it's great to verify how things will look). - -## Publishing to GitHub and Netlify - -Create a new repository at GitHub (or one of the other supported git services) and follow the instructions on how to push existing files into your new repository. - -Now is probably also a good time to add a `.gitignore` file: - -```bash -.next/ -node_modules/ -/npm-debug.log -.DS_Store -out/ -``` - -When your project is under version control, go to Netlify and select "New Site from Git". Select GitHub (or whatever service you used in the previous step), and the repository you just pushed to. - -Under the final step (Build options, and deploy!), make sure you enter the following: - -| Field | Value | -| ----------------- | ------------------ | -| Build command | **npm run export** | -| Publish directory | **out** | - -### Enable Identity and Git Gateway - -Netlify's Identity and Git Gateway services allow you to manage CMS admin users for your site without requiring them to have an account with your Git host or commit access on your repo. From your site dashboard on Netlify: - -1. Go to **Settings > Identity**, and select **Enable Identity service**. -2. Under **Registration preferences**, select **Open** or **Invite only**. In most cases, you want only invited users to access your CMS, but if you're just experimenting, you can leave it open for convenience. -3. If you'd like to allow one-click login with services like Google and GitHub, check the boxes next to the services you'd like to use, under **External providers**. -4. Scroll down to **Services > Git Gateway**, and click **Enable Git Gateway**. This authenticates with your Git host and generates an API access token. In this case, we're leaving the **Roles** field blank, which means any logged in user may access the CMS. For information on changing this, check the [Netlify Identity documentation](https://www.netlify.com/docs/identity/). - -### Celebrate! - -Great job - you did it! Open your new page via the new Netlify URL, and navigate to `/admin`. If you did everything correct in the previous step, you should now be able to sign up for an account, and log in. - -**Tip:** Signing up with an external provider is the easiest. If you want to sign up by email, you'll have to set up a redirect in your index.js page (which we won't be covering in this guide). For more information, have a look at the [Add To Your Site](https://www.netlifycms.org/docs/add-to-your-site) section. - -Congratulations - you can finally manage your new list of cats! diff --git a/website/content/docs/nuxt.md b/website/content/docs/nuxt.md deleted file mode 100644 index 6ba1a673..00000000 --- a/website/content/docs/nuxt.md +++ /dev/null @@ -1,269 +0,0 @@ ---- -group: Guides -weight: 50 -title: Nuxt ---- -This guide will walk you through how to integrate Netlify CMS with Nuxt. - -## Starting With `create-nuxt-app` - -Follow the instructions on the [Nuxt documentation](https://nuxtjs.org/guide/installation#using-code-create-nuxt-app-code-) for creating a new project, or run: - -```bash -npx create-nuxt-app -cd -npm run dev -``` - -## Setting Up Netlify CMS - -### Add the Netlify CMS files to Nuxt - -In the `static/` directory, create a new directory `admin/`. Inside that directory you'll create two files, your `index.html` and a `config.yml`. Per the [Netlify CMS documentation](/docs/add-to-your-site/), we'll set the content of `static/admin/index.html` to the following: - -```html - - - - - - Content Manager - - - - - - - - -``` - -For your `static/admin/config.yml` file, you can put in a basic starter config: - -```yaml -backend: - name: git-gateway - branch: main # Branch to update (optional; defaults to master) - -media_folder: static/img -public_folder: /img - -collections: - - name: 'blog' - label: 'Blog' - folder: 'content/blog' - format: 'frontmatter' - create: true - slug: '{{year}}-{{month}}-{{day}}-{{slug}}' - editor: - preview: false - fields: - - { label: 'Title', name: 'title', widget: 'string' } - - { label: 'Publish Date', name: 'date', widget: 'datetime' } - - { label: 'Description', name: 'description', widget: 'string' } - - { label: 'Body', name: 'body', widget: 'markdown' } -``` - -You can build whatever collections and content modeling you want. The important thing to note is the `format: 'frontmatter'` value on each collection. This is important for consuming content in Nuxt with the [nuxt/content](https://content.nuxtjs.org) module. - -### Add the `content/` directory to Nuxt - -In your root directory, you can create a new directory `content/`. As you might guess, this is where our content will live. Your filesystem should look about like this, so far: - -```bash -root/ -├ content/ -├ components/ -├ layouts/ -├ middleware/ -├ pages/ -├ plugins/ -├ static/ -│ └ admin/ -│ ├ index.html -│ └ config.yml -├ store/ -└ // .editorconfig, .gitignore, nuxt.config.js, etc... -``` - -### Pushing to GitHub - -It's now time to commit your changes and push to GitHub. `create-nuxt-app` initializes Git automatically for you, so you only need to do: - -```bash -git add . -git commit -m "Initial Commit" -git remote add origin https://github.com/YOUR_USERNAME/NEW_REPO_NAME.git -git push -u origin main -``` - -### Deploying With Netlify - -Now you can go ahead and deploy to Netlify. Go to your Netlify dashboard and click **[New site from Git](https://app.netlify.com/start)**. Select the repo you just created. Under **Basic build settings**, you can set the build command to `npm run generate` . Set the publish directory to `dist`. Click **Deploy site** to get the process going. - -### Authenticating with Netlify Identity - -**Add the Netlify Identity Widget** - -You've already added the Netlify Identity widget to our `admin/index.html`. The next thing to do is add the Netlify Identity widget to our site's index page. In `pages/index.vue`, we can add the following to the page ` -``` - -### Example Blog Post - -To generate blog posts create a `_slug.vue` file in the pages folder. By using `$content` you would get a json which you can use to display. But if you are using `markdown` to write and store your posts you can use `` module which gives you option to edit content on page in dev mode and many more [features](https://content.nuxtjs.org/). - -```javascript - - - -``` - -### Generating pages with the `generate` property - -Since Nuxt 2.13+, nuxt export has a crawler feature integrated which will crawl all your links and generate your routes based on those links. Therefore you do not need to do anything in order for your dynamic routes to be crawled. i.e, if you are on version of nuxt above 2.14 add target as static in nuxt.config.js and use `nuxt generate` to build your static site. - -```javascript -// nuxt.config.js -target: 'static' -``` - -If you are using **nuxt version below 2.14** you have to use generate option in nuxt/content module to generate pages - -```javascript -//nuxt.config.js -export default { - modules: [, - '@nuxt/content' - ], - generate: { - async routes () { - const { $content } = require('@nuxt/content') - const files = await $content().only(['path']).fetch() - - return files.map(file => file.path === '/index' ? '/' : file.path) - } - } -} -``` - -To render your site as a static site, you'll need to create or update the `generate` property in `nuxt.config.js` to create dynamic routes and provide their content as a `payload`. In `generate`, make your `routes` entry a function: - -```javascript -export default { - generate: { - routes: function() { - const fs = require('fs'); - const path = require('path'); - return fs.readdirSync('./content/blog').map(file => { - return { - route: `/blog/${path.parse(file).name}`, // Return the slug - payload: require(`./content/blog/${file}`), - }; - }); - }, - }, -}; -``` - -To see the generated site, navigate to name-of-your-website.netlify.app/blog diff --git a/website/content/docs/open-authoring.md b/website/content/docs/open-authoring.md deleted file mode 100644 index 8969c264..00000000 --- a/website/content/docs/open-authoring.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -group: Workflow -weight: 20 -title: Open Authoring ---- -**This is a [beta feature](/docs/beta-features#open-authoring).** - -When using the [GitHub backend](/docs/github-backend), you can use Netlify CMS to accept contributions from GitHub users without giving them access to your repository. When they make changes in the CMS, the CMS forks your repository for them behind the scenes, and all the changes are made to the fork. When the contributor is ready to submit their changes, they can set their draft as ready for review in the CMS. This triggers a pull request to your repository, which you can merge using the GitHub UI. - -At the same time, any contributors who *do* have write access to the repository can continue to use Netlify CMS normally. - -## Requirements - -* You must use [the GitHub backend](/docs/github-backend). - - **Note that the [Git Gateway backend](/docs/git-gateway-backend/#git-gateway-with-netlify-identity) does *not* support Open Authoring, even when the underlying repo is on GitHub.** -* For private GitHub repos the user must have `read` access on the repo, and you must explicitly set the auth_scope to `repo`, for example: - -```yaml -backend: - name: github - repo: owner-name/private-repo-name # path to private repo - auth_scope: repo # this is needed to fork the private repo - open_authoring: true -``` - -## Enabling Open Authoring - -1. [Enable the editorial workflow](/docs/configuration-options/#publish-mode) by setting `publish_mode` to `editorial_workflow` in your `config.yml`. -2. Set `open_authoring` to `true` in the `backend` section of your `config.yml`, as follows: - - ```yaml - backend: - name: github - repo: owner-name/repo-name # Path to your GitHub repository - open_authoring: true - ``` - -## Usage - -When a user logs into Netlify CMS who doesn't have write access to your repo, the CMS asks for permission to create a fork of your repo (or uses their existing fork, if they already have one). They are then presented with the normal CMS interface. The published content shown is from the original repo, so it stays up-to-date as changes are made. - -On the editorial workflow screen, the normal three columns are replaced by two columns instead — "Draft" and "Ready to Review". - -When they make changes to content in the CMS, the changes are made to a branch on their fork. In the editorial workflow screen, they see only their own pending changes. Once they're ready to submit their changes, they can move the card into the "Ready To Review" column to create a pull request. When the pull request is merged (by a repository maintainer via the GitHub UI), Netlify CMS deletes the branch and removes the card from the user's editorial workflow screen. Open Authoring users cannot publish entries through the CMS. - -Users who *do* have write access to the original repository continue to use the CMS normally. Unpublished changes made by users via Open Authoring are not visible on the editorial workflow screen, and their unpublished changes must be merged through the GitHub UI. - -## Alternative for external contributors with Git Gateway - -[As noted above](#requirements), Open Authoring does not work with the Git Gateway backend. However, you can use Git Gateway on a site with Netlify Identity that has [open registration](https://www.netlify.com/docs/identity/#adding-identity-users). This lets users create accounts on your site and log into the CMS. There are a few differences, including the following: - -* Users don't need to know about GitHub or create a GitHub account. Instead, they use Netlify Identity accounts that are created on your site and managed by you. -* The CMS applies users' changes directly to your repo, not to a fork. (If you use the editorial workflow, you can use features like [GitHub's protected branches](https://help.github.com/en/articles/about-protected-branches) or [Netlify's locked deploys](https://www.netlify.com/docs/locked-deploys/) to prevent users from publishing directly to your site from the CMS.) -* There is no distinction between users with write access to the repo and users without — all editorial workflow entries are visible from within the CMS and can be published with the CMS. (Unpublished Open Authoring entries, on the other hand, are visible only to the author in the CMS UI or publicly as GitHub PRs.) - -## Linking to specific entries in the CMS - -Open authoring often includes some sort of "Edit this page" link on the live site. Netlify CMS supports this via the **edit** path: - -```js -/#/edit/{collectionName}/{entryName} -``` - -For the entry named "general" in the "settings" file collection - -```html -https://www.example.com/path-to-cms/#/edit/settings/general -``` - -For blog post "test.md" in the "posts" folder collection - -```html -https://www.example.com/path-to-cms/#/edit/posts/test -``` - -* **`collectionName`**: the name of the collection as entered in the CMS config. -* **`entryName`** *(for [file collections](/docs/collection-types/#file-collections)*: the `name` of the entry from the CMS config. -* **`entryName`** *(for [folder collections](/docs/collection-types/#folder-collections)*: the filename, sans extension (the slug). \ No newline at end of file diff --git a/website/content/docs/releases.md b/website/content/docs/releases.md deleted file mode 100644 index 35528880..00000000 --- a/website/content/docs/releases.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -title: Releases -group: Intro -weight: 4 ---- - - - -## Update the CMS Version - -The update procedure for your CMS depends upon the method you used to install Netlify CMS. - -### Package Manager - -If you are using a package manager like Yarn or NPM, use their standard procedure to update. This is how both the Hugo and Gatsby starters are set up. - -### CDN - -If you are using the CMS through a CDN like Unpkg, then that depends on the version tag you are using. You can find the version tag in the `/admin/index.html` file of your site. - -- (Recommended) If you use `^2.0.0`, the CMS does all updates except major versions automatically. - - It upgrades to `2.0.1`, `2.1.0`, `2.1.2`. - - It does not upgrade to `3.0.0` or higher. - - It does not upgrade to beta versions. - -- If you use `~2.0.0`, the CMS will do only patch updates automatically. - - It upgrades `2.0.1`, `2.0.2`. - - It does not upgrade to `2.1.0` or higher. - - It does not upgrade beta versions. diff --git a/website/content/docs/site-generator-overview.md b/website/content/docs/site-generator-overview.md deleted file mode 100644 index 69a22e47..00000000 --- a/website/content/docs/site-generator-overview.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -title: Overview -group: Guides -weight: 1 ---- - -The process for adding Netlify CMS to a static site can be divided into four main steps: - -### Install Netlify CMS - -This is a single page app available at the `/admin` route of your website. -Check out the [general overview](/docs/intro/) to see what the installation process entails. - -### Set up a backend - -This serves two purpose: Secure access to your website's Netlify CMS and allows it to read and update content files in your repo. More information about configuring the backend can be found [here](/docs/backends-overview/). - -### Configure Netlify CMS using a configuration file - -For starters, you can get by with a basic configuration that includes required information like Git provider, branch and folders to save files to. - -Once you've gotten the hang of it, you can use the file to build whatever collections and content modeling you want. Check out the [this section](/docs/configuration-options/#configuration-file) for full details about all available configuration options. - -### Render the content provided by Netlify CMS as web pages - -Netlify CMS manages your content, and provides editorial and admin features, but it doesn't deliver content. It only makes your content available through an API. - -It is up to developers to determine how to build the raw content into something useful and delightful on the frontend. - -To learn how to query raw content managed by Netlify CMS and reformat them for delivery to end users, please refer the dedicated section for your site generator in the Table of Content. -___ -### Local development - -If you are experimenting with Netlify CMS or testing things out, you can connect it to a local Git repository instead of a live one. Learn how to do it [here](/docs/beta-features/#working-with-a-local-git-repository). diff --git a/website/content/docs/start-with-a-template.md b/website/content/docs/start-with-a-template.md deleted file mode 100644 index d02aefe4..00000000 --- a/website/content/docs/start-with-a-template.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -group: Intro -weight: 2 -title: Start with a Template ---- -You can add Netlify CMS [to an existing site](/docs/add-to-your-site/), but the quickest way to get started is with a template. Found below, our featured templates deploy a bare-bones site and Netlify CMS to Netlify ([what's the difference, you ask?](../intro/#netlify-cms-vs-netlify)), giving you a fully working CMS-enabled site with just a few clicks. - -
    -
    -
    - -
    -

    Hugo Site Starter

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Gatsby Site Starter

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Middleman Site Starter

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Preact CLI

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Next.js Blog Template

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Eleventy Starter

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Nuxt.js Boilerplate

    -

    Deploy to Netlify

    -
    -
    -
    - -
    -

    Metalsmith Starter

    -

    Deploy to Netlify

    -
    -
    - -After clicking one of those buttons, authenticate with GitHub or GitLab and choose a repository name. Netlify then automatically creates a clone of the repository in your GitHub or GitLab account. Next, it builds and deploys the new site on Netlify, bringing you to the site dashboard after completing the build. - -**Note for Bitbucket users:** Netlify CMS supports Bitbucket repositories, but Bitbucket's permissions won't work with the Deploy to Netlify buttons above. You can still set up a repository manually, or follow the [tutorial](/docs/add-to-your-site) for adding Netlify CMS to an existing site. - -## Access Netlify CMS on your new site - -1. The template deploy process sends you an invitation to your new site, sent from `no-reply@netlify.com`. - ![Sample email subject line: You've been invited to join radiologist-amanda-53841.netlify.com](https://www.netlifycms.org/img/email-subject.png?raw=true) -2. Wait for the deployment to complete, then click the link to accept the invite. Your site will open with a prompt to create a password. - !["Complete your signup" modal on the Kaldi coffee site](https://www.netlifycms.org/img/create-password.png?raw=true) -3. Enter a password, sign in, and you’ll go to the CMS. (For future visits, you can go straight to `/admin/`.) - -Try adding and editing posts, or changing the content of the Products page. When you save, the changes are pushed immediately to your Git repository, triggering a build on Netlify, and updating the content on your site. Check out the configuration code by visiting your site repo. - -## More paths to explore - -* To see how to integrate Netlify CMS into an existing project, go to [Add to your site](/docs/add-to-your-site/). -* Check out other sites using Netlify CMS (or share your own!) on the [Examples](/docs/examples/) page. -* If you’d like to add more CMS editors or change how they log in to your site, read up on [Netlify Identity service](https://www.netlify.com/docs/identity). \ No newline at end of file diff --git a/website/content/docs/test-backend.md b/website/content/docs/test-backend.md deleted file mode 100644 index fdb9b077..00000000 --- a/website/content/docs/test-backend.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: Test -group: Accounts -weight: 50 ---- - -You can use the `test-repo` backend to try out Netlify CMS without connecting to a Git repo. With this backend, you can write and publish content normally, but any changes will disappear when you reload the page. This backend powers the Netlify CMS [demo site](https://cms-demo.netlify.com/). - -**Note:** The `test-repo` backend can't access your local file system, nor does it connect to a Git repo, thus you won't see any existing files while using it. - -To enable this backend, add the following lines to your Netlify CMS `config.yml` file: - -```yaml -backend: - name: test-repo -``` diff --git a/website/content/docs/uploadcare.md b/website/content/docs/uploadcare.md deleted file mode 100644 index 79d8dde3..00000000 --- a/website/content/docs/uploadcare.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Uploadcare -group: Media -weight: 30 ---- -Uploadcare is a sleek service that allows you to upload files without worrying about maintaining a growing collection — more of an asset store than a library. Just upload when you need to, and the files are hosted on their CDN. They provide image processing controls from simple cropping and rotation to filters and face detection, and a lot more. You can check out Uploadcare's full feature set on their [website](https://uploadcare.com/). - -The Uploadcare media library integration for Netlify CMS allows you to use Uploadcare as your media handler within the CMS itself. It's available by default as of our 2.1.0 release, and works in tandem with the existing file and image widgets, so using it only requires creating an Uploadcare account and updating your Netlify CMS configuration. - -**Please make sure that Netlify CMS is updated to 2.1.0 or greater before proceeding.** - -## Creating an Uploadcare Account - -You can [sign up](https://uploadcare.com/accounts/signup/) for a free Uploadcare account to get started. Once you've signed up, go to your dashboard, select a project, and then select "API keys" from the menu on the left. The public key on the API keys page will be needed in your Netlify CMS configuration. For more info on getting your API key, visit their [walkthrough](https://uploadcare.com/docs/keys/). - -## Updating Netlify CMS Configuration - -The next and final step is updating your Netlify CMS configuration file: - -1. Add a `media_library` property at the same level as `media_folder`, with an object as it's value. -2. In the `media_library` object, add the name of the media player under `name`. -3. Add a `config` object under name with a `publicKey` property with your Uploadcare public key as it's value. - -Your `config.yml` should now include something like this (except with a real API key): - -```yaml -media_library: - name: uploadcare - config: - publicKey: YOUR_UPLOADCARE_PUBLIC_KEY -``` - -Once you've finished updating your Netlify CMS configuration, the Uploadcare widget will appear when using the image or file widgets. - -**Note:** The Netlify CMS media library extensions for Uploadcare are not included in `netlify-cms-app`. If you're using `netlify-cms-app`, you'll need to [register the media libraries yourself](https://www.netlifycms.org/blog/2019/07/netlify-cms-gatsby-plugin-4-0-0#using-media-libraries-with-netlify-cms-app). - -## Configuring the Uploadcare Widget - -The Uploadcare widget can be configured with settings that are outlined [in their docs](https://uploadcare.com/docs/file_uploads/widget/options/). The widget itself accepts configuration through global variables and data properties on HTML elements, but with Netlify CMS you can pass configuration options directly through your `config.yml`. - -**Note:** all default values described in Uploadcare's documentation also apply in the Netlify CMS integration, except for `previewStep`, which is set to `true`. This was done because the preview step provides helpful information like upload status, and provides access to image editing controls. This option can be disabled through the configuration options below. - -### Global configuration - -Global configuration, which is meant to affect the Uploadcare widget at all times, can be provided as seen above, under the primary `media_library` property. Settings applied here will affect every instance of the Uploadcare widget. - -## Field configuration - -Configuration can also be provided for individual fields that use the media library. The structure is very similar to the global configuration, except the settings are added to an individual `field`. For example: - -```yaml - ... - fields: - name: cover - label: Cover Image - widget: image - media_library: - config: - multiple: true - previewStep: false -``` - -## Integration settings - -There are several settings that control the behavior of integration with the widget. - -* `autoFilename` (`boolean`) - specify whether to add a filename to the end of the url. Example: `http://ucarecdn.com/:uuid/filename.png` -* `defaultOperations` (`string`) - specify a string added at the end of the url. This could be useful to apply a set of CDN operations to each image, for example resizing or compression. All the possible operations are listed [here](https://uploadcare.com/docs/api_reference/cdn/). - -```yaml -media_library: - name: uploadcare - config: - publicKey: YOUR_UPLOADCARE_PUBLIC_KEY - settings: - autoFilename: true - defaultOperations: '/resize/800x600/' -``` diff --git a/website/content/docs/widgets.md b/website/content/docs/widgets.md deleted file mode 100644 index 439409fc..00000000 --- a/website/content/docs/widgets.md +++ /dev/null @@ -1,28 +0,0 @@ ---- -title: Widgets -group: Fields -weight: 10 ---- - -Widgets define the data type and interface for entry fields. Netlify CMS comes with several built-in widgets. Click the widget names in the sidebar to jump to specific widget details. We’re always adding new widgets, and you can also [create your own](../custom-widgets)! - -Widgets are specified as collection fields in the Netlify CMS `config.yml` file. Note that [YAML syntax](https://en.wikipedia.org/wiki/YAML#Basic_components) allows lists and objects to be written in block or inline style, and the code samples below include a mix of both. - -To see working examples of all of the built-in widgets, try making a 'Kitchen Sink' collection item on the [CMS demo site](https://cms-demo.netlify.com). (No login required: click the login button and the CMS will open.) You can refer to the demo [configuration code](https://github.com/netlify/netlify-cms/blob/master/dev-test/config.yml) to see how each field was configured. - -## Common widget options - -The following options are available on all fields: - -- `required`: specify as `false` to make a field optional; defaults to `true` -- `hint`: optionally add helper text directly below a widget. Useful for including instructions. Accepts markdown for bold, italic, strikethrough, and links. -- `pattern`: add field validation by specifying a list with a [regex pattern](https://regexr.com/) and an error message; more extensive validation can be achieved with [custom widgets](../custom-widgets/#advanced-field-validation) -- **Example:** - ```yaml - label: "Title" - name: "title" - widget: "string" - pattern: ['.{12,}', "Must have at least 12 characters"] - ``` - -## Default widgets diff --git a/website/content/docs/widgets/boolean.md b/website/content/docs/widgets/boolean.md deleted file mode 100644 index 30b71349..00000000 --- a/website/content/docs/widgets/boolean.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -title: boolean -label: "Boolean" ---- - -The boolean widget translates a toggle switch input to a true/false value. - -- **Name:** `boolean` -- **UI:** toggle switch -- **Data type:** boolean -- **Options:** - - `default`: accepts `true` or `false`; defaults to `false` when `required` is set to `false` -- **Example:** - ```yaml - - {label: "Draft", name: "draft", widget: "boolean", default: true} - ``` diff --git a/website/content/docs/widgets/code.md b/website/content/docs/widgets/code.md deleted file mode 100644 index 01ee267e..00000000 --- a/website/content/docs/widgets/code.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -title: code -label: 'Code' ---- - -The code widget provides a code editor (powered by [Codemirror](https://codemirror.net)) with optional syntax awareness. Can output the raw code value or an object with the selected language and the raw code value. - -- **Name:** `code` -- **UI:** code editor -- **Data type:** string -- **Options:** - - `default_language`: optional; default language to use - - `allow_language_selection`: optional; defaults to `false`: allows syntax to be changed - - `keys`: optional; sets key names for code and lang if outputting an object; defaults to `{ code: 'code', lang: 'lang' }` - - `output_code_only`: set to `true` to output the string value only, defaults to `false` - -- **Example:** - ```yaml - - label: 'Code' - name: 'code' - widget: 'code' - ``` diff --git a/website/content/docs/widgets/color.md b/website/content/docs/widgets/color.md deleted file mode 100644 index 97495c79..00000000 --- a/website/content/docs/widgets/color.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -label: 'Color' -title: color ---- - -The color widget translates a color picker to a color string. - -- **Name:** `color` -- **UI:** color picker -- **Data type:** string -- **Options:** - - `default`: accepts a string; defaults to an empty string. Sets the default value - - `allowInput`: accepts a boolean, defaults to `false`. Allows manual editing of the color input value - - `enableAlpha`: accepts a boolean, defaults to `false`. Enables Alpha editing -- **Example:** - ```yaml - - { label: 'Color', name: 'color', widget: 'color' } - ``` -- **Example:** - ```yaml - - { label: 'Color', name: 'color', widget: 'color', enableAlpha: true, allowInput: true } - ``` diff --git a/website/content/docs/widgets/date.md b/website/content/docs/widgets/date.md deleted file mode 100644 index 948ec64c..00000000 --- a/website/content/docs/widgets/date.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: date -label: 'Date' ---- - -_**Deprecation notice**: the date widget has been deprecated and will be removed in the next major release. Please use the datetime widget instead._ - -The date widget translates a date picker input to a date string. For saving date and time together, use the datetime widget. - -- **Name:** `date` -- **UI:** date picker -- **Data type:** Moment.js-formatted date string -- **Options:** - - `default`: accepts a date string, or an empty string to accept blank input; otherwise defaults to current date - - `format`: optional; accepts Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/); defaults to raw Date object (if supported by output format) - - `date_format`: optional; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format. - - `time_format`: optional; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format, `false` hides time-picker. Defaults to false. -- **Example:** - ```yaml - - label: 'Birthdate' - name: 'birthdate' - widget: 'date' - default: '' - format: 'MMM Do YY' - ``` diff --git a/website/content/docs/widgets/datetime.md b/website/content/docs/widgets/datetime.md deleted file mode 100644 index 5ab6c5eb..00000000 --- a/website/content/docs/widgets/datetime.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -title: datetime -label: "DateTime" ---- - -The datetime widget translates a datetime picker to a datetime string. - -- **Name:** `datetime` -- **UI:** datetime picker -- **Data type:** Moment.js-formatted datetime string -- **Options:** - - `default`: accepts a datetime string, or an empty string to accept blank input; otherwise defaults to current datetime - - `format`: sets storage format; accepts Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/); defaults to raw Date object (if supported by output format) - - `date_format`: sets date display format in UI; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format. - - `time_format`: sets time display format in UI; boolean or Moment.js [tokens](https://momentjs.com/docs/#/parsing/string-format/). If `true` use default locale format, `false` hides time-picker. - - `picker_utc`: _(default: `false`)_ when set to `true`, the datetime picker will display times in UTC. When `false`, the datetime picker will display times in the user's local timezone. When using date-only formats, it can be helpful to set this to `true` so users in all timezones will see the same date in the datetime picker. -- **Example:** - ```yaml - - label: "Start time" - name: "start" - widget: "datetime" - default: "" - date_format: "DD.MM.YYYY" # e.g. 24.12.2021 - time_format: "HH:mm" # e.g. 21:07 - format: "LLL" - picker_utc: false - ``` diff --git a/website/content/docs/widgets/file.md b/website/content/docs/widgets/file.md deleted file mode 100644 index 3df31c7d..00000000 --- a/website/content/docs/widgets/file.md +++ /dev/null @@ -1,31 +0,0 @@ ---- -title: file -label: File ---- -The file widget allows editors to upload a file or select an existing one from the media library. The path to the file will be saved to the field as a string. - -* **Name:** `file` -* **UI:** file picker button opens media gallery -* **Data type:** file path string -* **Options:** - - * `default`: accepts a file path string; defaults to null - * `media_library`: media library settings to apply when a media library is opened by the - current widget - - * `allow_multiple`: *(default: `true`)* when set to `false`, prevents multiple selection for any media library extension, but must be supported by the extension in use - * `config`: a configuration object that will be passed directly to the media library being - used - available options are determined by the library - * `media_folder` (Beta): file path where uploaded files will be saved specific to this control. Paths can be relative to a collection folder (e.g. `files` will add the file to a sub-folder in the collection folder) or absolute with reference to the base of the repo which needs to begin with `/` (e.g `/static/files` will save uploaded files to the `static` folder in a sub folder named `files`) - * `choose_url`: *(default: `true`)* when set to `false`, the "Insert from URL" button will be hidden -* **Example:** - - ```yaml - - label: "Manual PDF" - name: "manual_pdf" - widget: "file" - default: "/uploads/general-manual.pdf" - media_library: - config: - multiple: true - ``` diff --git a/website/content/docs/widgets/hidden.md b/website/content/docs/widgets/hidden.md deleted file mode 100644 index 3fe738b1..00000000 --- a/website/content/docs/widgets/hidden.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -label: "Hidden" -title: hidden ---- - -Hidden widgets do not display in the UI. In folder collections that allow users to create new items, you will often want to set a default for hidden fields, so they will be set without requiring an input. - -- **Name:** `hidden` -- **UI:** none -- **Data type:** any valid data type -- **Options:** - - `default`: accepts any valid data type; recommended for collections that allow adding new items -- **Example:** - ```yaml - - {label: "Layout", name: "layout", widget: "hidden", default: "blog"} - ``` diff --git a/website/content/docs/widgets/image.md b/website/content/docs/widgets/image.md deleted file mode 100644 index d95072bb..00000000 --- a/website/content/docs/widgets/image.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: image -label: Image ---- -The image widget allows editors to upload an image or select an existing one from the media library. The path to the image file will be saved to the field as a string. - -* **Name:** `image` -* **UI:** file picker button opens media gallery allowing image files (jpg, jpeg, webp, gif, png, bmp, tiff, svg) only; displays selected image thumbnail -* **Data type:** file path string -* **Options:** - - * `default`: accepts a file path string; defaults to null - * `media_library`: settings to apply when a media library is opened by the - current widget - * `allow_multiple`: *(default: `true`)* when set to `false`, multiple selection will be disabled even if the media library extension supports it - * `config`: a configuration object passed directly to the media library; check the documentation of your media library extension for available `config` options - * `media_folder` (Beta): file path where uploaded images will be saved specific to this control. Paths can be relative to a collection folder (e.g. `images` will add the image to a sub-folder in the collection folder) or absolute with reference to the base of the repo which needs to begin with `/` (e.g `/static/images` will save uploaded images to the `static` folder in a sub folder named `images`) - * `choose_url`: *(default: `true`)* when set to `false`, the "Insert from URL" button will be hidden -* **Example:** - -```yaml - - label: "Featured Image" - name: "thumbnail" - widget: "image" - choose_url: true - default: "/uploads/chocolate-dogecoin.jpg" - media_library: - config: - multiple: true -``` diff --git a/website/content/docs/widgets/list.md b/website/content/docs/widgets/list.md deleted file mode 100644 index aa1d89a1..00000000 --- a/website/content/docs/widgets/list.md +++ /dev/null @@ -1,128 +0,0 @@ ---- -title: list -label: List ---- -The list widget allows you to create a repeatable item in the UI which saves as a list of widget values. map a user-provided string with a comma delimiter into a list. You can choose any widget as a child of a list widget—even other lists. - -* **Name:** `list` -* **UI:** without any `fields` specified, the list widget defaults to a text input for entering comma-separated values; with `fields` specified, the list widget contains a repeatable child widget, with controls for adding, deleting, and re-ordering the repeated widgets. -* **Data type:** list of widget values -* **Options:** - - * `default`: you may specify a list of strings to populate the basic text - field, or an array of list items for lists using the `fields` option. If no - default is declared when using `field` or `fields`, will default to a single - list item using the defaults on the child widgets - * `allow_add`: `false` hides the button to add additional items - * `collapsed`: when `true`, the entries collapse by default - * `summary`: specify the label displayed on collapsed entries - * `minimize_collapsed`: when `true`, collapsing the list widget will hide all of it's entries instead of showing summaries - * `label_singular`: the text to show on the add button - * `field`: a single widget field to be repeated - * `fields`: a nested list of multiple widget fields to be included in each repeatable iteration - * `max`: maximum number of items in the list - * `min`: minimum number of items in the list - * `add_to_top`: when `true`, new entries will be added to the top of the list -* **Example** (`field`/`fields` not specified): - -```yaml -- label: "Tags" - name: "tags" - widget: "list" - default: ["news"] -``` - -* **Example** (`allow_add` marked `false`): - -```yaml -- label: "Tags" - name: "tags" - widget: "list" - allow_add: false - default: ["news"] -``` - -* **Example** (with `field`): - -```yaml -- label: "Gallery" - name: "galleryImages" - widget: "list" - summary: '{{fields.image}}' - field: {label: Image, name: image, widget: image} -``` - -* **Example** (with `fields`): - -```yaml -- label: "Testimonials" - name: "testimonials" - widget: "list" - summary: '{{fields.quote}} - {{fields.author.name}}' - fields: - - {label: Quote, name: quote, widget: string, default: "Everything is awesome!"} - - label: Author - name: author - widget: object - fields: - - {label: Name, name: name, widget: string, default: "Emmet"} - - {label: Avatar, name: avatar, widget: image, default: "/img/emmet.jpg"} -``` - -* **Example** (with `default`): - -```yaml -- label: "Gallery" - name: "galleryImages" - widget: "list" - fields: - - { label: "Source", name: "src", widget: "string" } - - { label: "Alt Text", name: "alt", widget: "string" } - default: - - { src: "/img/tennis.jpg", alt: "Tennis" } - - { src: "/img/footbar.jpg", alt: "Football" } -``` - -* **Example** (`collapsed` marked `false`): - -```yaml -- label: "Testimonials" - name: "testimonials" - collapsed: false - widget: "list" - fields: - - {label: Quote, name: quote, widget: string, default: "Everything is awesome!"} - - {label: Author, name: author, widget: string } -``` - -* **Example** (`minimize_collapsed` marked `true`): - -```yaml -- label: "Testimonials" - name: "testimonials" - minimize_collapsed: true - widget: "list" - fields: - - {label: Quote, name: quote, widget: string, default: "Everything is awesome!"} - - {label: Author, name: author, widget: string } -``` - -* **Example** (with `max` & `min`): - -```yaml -- label: "Tags" - name: "tags" - widget: "list" - max: 3 - min: 1 - default: ["news"] -``` - -* **Example** (`add_to_top` marked `true`): - -```yaml -- label: "Tags" - name: "tags" - widget: "list" - add_to_top: true -``` \ No newline at end of file diff --git a/website/content/docs/widgets/map.md b/website/content/docs/widgets/map.md deleted file mode 100644 index eb4b2bf6..00000000 --- a/website/content/docs/widgets/map.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -title: map -label: Map ---- -The map widget allows you to edit spatial data using an interactive map. Spatial data for a single piece of geometry saves as a GeoJSON string in WGS84 projection. - -* **Name:** `map` -* **UI:** interactive map -* **Data type:** GeoJSON string -* **Options:** - - * `decimals`: accepts a number to specify precision of saved coordinates; defaults to 7 decimals - * `default`: accepts a GeoJSON string containing a single geometry; defaults to an empty string - * `type`: accepts one string value of `Point`, `LineString` or `Polygon`; defaults to `Point` -* **Example:** - - ```yaml - - {label: "Location", name: "location", widget: "map" } - ``` \ No newline at end of file diff --git a/website/content/docs/widgets/markdown.md b/website/content/docs/widgets/markdown.md deleted file mode 100644 index defc51f3..00000000 --- a/website/content/docs/widgets/markdown.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -title: markdown -label: Markdown ---- -The markdown widget provides a full fledged text editor allowing users to format text with features such as headings and blockquotes. Users can change their editing view with a handy toggle button. - -*Please note:* If you want to use your markdown editor to fill a markdown file contents after its frontmatter, you'll have to name the field `body` so the CMS recognizes it and saves the file accordingly. - -* **Name:** `markdown` -* **UI:** full text editor -* **Data type:** markdown -* **Options:** - - * `default`: accepts markdown content - * `minimal`: accepts a boolean value, `false` by default. Sets the widget height to minimum possible. - * `buttons`: an array of strings representing the formatting buttons to display (all shown by default). Buttons include: `bold`, `italic`, `code`, `link`, `heading-one`, `heading-two`, `heading-three`, `heading-four`, `heading-five`, `heading-six`, `quote`, `bulleted-list`, and `numbered-list`. - * `editor_components`: an array of strings representing the names of editor components to display (all shown by default). Netlify CMS includes `image` and `code-block` editor components by default, and custom components may be [created and registered](/docs/custom-widgets/#registereditorcomponent). - * `modes`: an array of strings representing the names of allowed editor modes. Possible modes are `raw` and `rich_text`. A toggle button appears in the toolbar when more than one mode is available. - * `sanitize_preview`: accepts a boolean value, `false` by default. Sanitizes markdown preview to prevent XSS attacks - might alter the preview content. -* **Example:** - - ```yaml - - { label: 'Blog post content', name: 'body', widget: 'markdown' } - ``` - -This would render as: - -![Markdown widget example](/img/widgets-markdown.png) - -*Please note:* The markdown widget outputs a raw markdown string. Your static site generator may or may not render the markdown to HTML automatically. Consult with your static site generator's documentation for more information about rendering markdown. diff --git a/website/content/docs/widgets/number.md b/website/content/docs/widgets/number.md deleted file mode 100644 index e0ea666e..00000000 --- a/website/content/docs/widgets/number.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -label: "Number" -title: number ---- - -The number widget uses an HTML number input, saving the value as a string, integer, or floating point number. - -- **Name:** `number` -- **UI:** HTML [number input](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/number) -- **Data type:** string by default; configured by `value_type` option -- **Options:** - - `default`: accepts string or number value; defaults to empty string - - `value_type`: accepts `int` or `float`; any other value results in saving as a string - - `min`: accepts a number for minimum value accepted; unset by default - - `max`: accepts a number for maximum value accepted; unset by default - - `step`: accepts a number for stepping up/down values in the input; 1 by default -- **Example:** - ```yaml - - label: "Puppy Count" - name: "puppies" - widget: "number" - default: 2 - value_type: "int" - min: 1 - max: 101 - step: 2 - ``` diff --git a/website/content/docs/widgets/object.md b/website/content/docs/widgets/object.md deleted file mode 100644 index a45b3315..00000000 --- a/website/content/docs/widgets/object.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -title: object -label: Object ---- -The object widget allows you to group multiple widgets together, nested under a single field. You can choose any widget as a child of an object widget—even other objects. - -* **Name:** `object` -* **UI:** a field containing one or more child widgets -* **Data type:** list of child widget values -* **Options:** - - * `default`: you can set defaults within each sub-field's configuration - * `collapsed`: if added and labeled `true`, collapse the widget's content by default - * `summary`: specify the label displayed when the object is collapsed - * `fields`: (**required**) a nested list of widget fields to include in your widget -* **Example:** - - ```yaml - - label: "Profile" - name: "profile" - widget: "object" - summary: '{{fields.name}}: {{fields.birthdate}}' - fields: - - {label: "Public", name: "public", widget: "boolean", default: true} - - {label: "Name", name: "name", widget: "string"} - - label: "Birthdate" - name: "birthdate" - widget: "date" - default: "" - format: "MM/DD/YYYY" - - label: "Address" - name: "address" - widget: "object" - collapsed: true - fields: - - {label: "Street Address", name: "street", widget: "string"} - - {label: "City", name: "city", widget: "string"} - - {label: "Postal Code", name: "post-code", widget: "string"} - ``` diff --git a/website/content/docs/widgets/relation.md b/website/content/docs/widgets/relation.md deleted file mode 100644 index 0bc656b7..00000000 --- a/website/content/docs/widgets/relation.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -title: relation -label: Relation ---- -The relation widget allows you to reference items from another collection. It provides a search input with a list of entries from the collection you're referencing, and the list automatically updates with matched entries based on what you've typed. - -* **Name:** `relation` -* **UI:** text input with search result dropdown -* **Data type:** data type of the value pulled from the related collection item -* **Options:** - - * `collection`: (**required**) name of the referenced collection (string) - * `value_field`: (**required**) name of the field from the referenced collection whose value will be stored for the relation. For nested fields, separate each subfield with a `.` (e.g. `name.first`). For list fields use a wildcard `*` to target all list items (e.g. `categories.*`). - * `search_fields`: (**required**) list of one or more names of fields in the referenced collection to search for the typed value. Syntax to reference nested fields is similar to that of *value_field*. - * `file`: allows referencing a specific file when the referenced collection is a files collection (string) - * `display_fields`: list of one or more names of fields in the referenced collection that will render in the autocomplete menu of the control. Defaults to `value_field`. Syntax to reference nested fields is similar to that of *value_field*. - * `default`: accepts any widget data type; defaults to an empty string - * `multiple` : accepts a boolean, defaults to `false` - * `min`: minimum number of items; ignored if **multiple** is `false` - * `max`: maximum number of items; ignored if **multiple** is `false` - * `options_length`: accepts integer to override number of options presented to user. Defaults to `20`. -* **Referencing a folder collection example** (assuming a separate "authors" collection with "name" and "twitterHandle" fields with subfields "first" and "last" for the "name" field): - -```yaml -- label: "Post Author" - name: "author" - widget: "relation" - collection: "authors" - search_fields: ["name.first", "twitterHandle"] - value_field: "name.first" - display_fields: ["twitterHandle", "followerCount"] -``` - -The generated UI input will search the authors collection by name and twitterHandle, and display each author's handle and follower count. On selection, the author's name is saved for the field. - -* **String templates example** (assuming a separate "authors" collection with "name" and "twitterHandle" fields with subfields "first" and "last" for the "name" field): - -```yaml -- label: "Post Author" - name: "author" - widget: "relation" - collection: "authors" - search_fields: ['name.first'] - value_field: "{{slug}}" - display_fields: ["{{twitterHandle}} - {{followerCount}}"] -``` - -The generated UI input will search the authors collection by name, and display each author's handle and follower count. On selection, the author entry slug is saved for the field. - -* **Referencing a file collection list field example** (assuming a separate "relation_files" collection with a file named "cities" with a list field "cities" with subfields "name" and "id"): - -```yaml -- label: "City" - name: "city" - widget: "relation" - collection: "relation_files" - file: "cities" - search_fields: ["cities.*.name"] - display_fields: ["cities.*.name"] - value_field: "cities.*.id" -``` - -The generated UI input will search the cities file by city name, and display each city's name. On selection, the city id is saved for the field. \ No newline at end of file diff --git a/website/content/docs/widgets/select.md b/website/content/docs/widgets/select.md deleted file mode 100644 index 5377cc51..00000000 --- a/website/content/docs/widgets/select.md +++ /dev/null @@ -1,79 +0,0 @@ ---- -title: select -label: Select ---- -The select widget allows you to pick a string value from a dropdown menu. - -* **Name:** `select` -* **UI:** select input -* **Data type:** string or array -* **Options:** - - * `default`: `options` must contain any default values - - * string values: accepts a string; defaults to an empty string. Accepts an array of strings and defaults to an empty array with `multiple: true` enabled. - * object with `label` and `value` fields: accepts an object with `label` and `value` field or an array of such objects when `multiple: true` is enable. Defaults to no value - * `options`: (**required**) there are two ways to list of options for the dropdown menu: - - * string values: the dropdown displays the value directly - * object with `label` and `value` fields: the label displays in the dropdown; the value saves in the file - * `multiple`: accepts a boolean; defaults to `false` - * `min`: minimum number of items; ignored if **multiple** is `false` - * `max`: maximum number of items; ignored if **multiple** is `false` - -* **Example** (options as strings): - -```yaml -- label: "Align Content" - name: "align" - widget: "select" - options: ["left", "center", "right"] -``` - -Selecting the `center` option, will save the value as: - -```yaml -align: "center" -``` - -* **Example** (options as objects): - -```yaml -- label: "City" - name: "airport-code" - widget: "select" - options: - - { label: "Chicago", value: "ORD" } - - { label: "Paris", value: "CDG" } - - { label: "Tokyo", value: "HND" } -``` - -Selecting the `Chicago` option, will save the value as: - -```yaml -airport-code: "ORD" -``` - -* **Example** (multiple): - -```yaml -- label: "Tags" - name: "tags" - widget: "select" - multiple: true - options: ["Design", "UX", "Dev"] - default: ["Design"] -``` - -* **Example** (min/max): - -```yaml -- label: "Tags" - name: "tags" - widget: "select" - multiple: true - min: 1 - max: 3 - options: ["Design", "UX", "Dev"] - default: ["Design"] -``` diff --git a/website/content/docs/widgets/string.md b/website/content/docs/widgets/string.md deleted file mode 100644 index fdffbfd4..00000000 --- a/website/content/docs/widgets/string.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -label: "String" -title: string ---- - -The string widget translates a basic text input to a string value. For larger textarea inputs, use the text widget. - -- **Name:** `string` -- **UI:** text input -- **Data type:** string -- **Options:** - - `default`: accepts a string; defaults to an empty string -- **Example:** - ```yaml - - {label: "Title", name: "title", widget: "string"} - ``` diff --git a/website/content/docs/widgets/text.md b/website/content/docs/widgets/text.md deleted file mode 100644 index 46f287e5..00000000 --- a/website/content/docs/widgets/text.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -label: "Text" -title: text ---- - -The text widget takes a multiline text field and saves it as a string. For shorter text inputs, use the string widget. - -- **Name:** `text` -- **UI:** HTML textarea -- **Data type:** string -- **Options:** - - `default`: accepts a string; defaults to an empty string -- **Example:** - ```yaml - - {label: "Description", name: "description", widget: "text"} - ``` diff --git a/website/content/docs/writing-style-guide.md b/website/content/docs/writing-style-guide.md deleted file mode 100644 index 63998b03..00000000 --- a/website/content/docs/writing-style-guide.md +++ /dev/null @@ -1,260 +0,0 @@ ---- -title: Writing Style Guide -weight: 30 -group: Contributing ---- - -# Netlify CMS Style Guide -_Adapted from the [Kubernetes Style Guide](https://kubernetes.io/docs/contribute/style/style-guide)_ - -## Documentation Formatting Standards - -### Use angle brackets for placeholders - -Use angle brackets for placeholders. Tell the reader what a placeholder represents. - -1. Display information about a cli command: - -```bash -npm install -``` - -where `` is the name of a package. - -### Use bold for user interface elements - -Do: Click **Save**. - -Don't: Click "Save". -_____ - -Do: Select **Log Out**. - -Don't: Select 'Log Out'. -_____ - -### Use italics to define or introduce new terms - -Do: A _collection_ is a set of entries … - -Don't: A "collection" is a set of entries … -_____ - -Do: These components form the _control pane_. - -Don't: These components form the **control pane**. -_____ - -### Use code style for filenames, directories, and paths - -Do: Open the `config.yaml` file. - -Don't: Open the config.yaml file. -_____ - -Do: Go to the `/docs/guides` directory. - -Don't: Go to the /docs/guides directory. -_____ - -Do: Open the `/admin/index.html` file. - -Don't: Open the /admin/index.html file. -_____ - -### Use the international standard for punctuation inside quotes - -Do: Branch names begin with "cms". - -Don't: Branch names begin with "stage." -_____ - -Do: The copy is called a "fork". - -Don't: The copy is called a "fork." -_____ - -## Inline code formatting - -### Use code style for inline code and commands - -For inline code in an HTML document, use the `` tag. In a Markdown document, use the backtick (`). - -Do: The `yarn start` command starts the development server. - -Don't: The "yarn start" command starts the development server. -_____ - -Do: For a production build, use `yarn build`. - -Don't: For a production build, use "yarn build". -_____ - -Do: Enclose code samples with triple backticks. `(```)` - -Don't:Enclose code samples with any other syntax. -_____ - -### Use code style for object field names - -Do: Set the value of the `media_folder` field in the configuration file. - -Don't: Set the value of the "media_folder" field in the configuration file. -_____ - -Do: The value of the `name` field is a string. - -Don't: The value of the "name" field is a string. -_____ - -### Use normal style for string and integer field values - -For field values of type string or integer, use normal style without quotation marks. - -Do: Set the value of `publish_mode` to editorial_workflow. - -Don't: Set the value of `imagePullPolicy` to "Always". -_____ - -Do: Set the value of `image` to nginx:1.8. - -Don't: Set the value of `image` to `nginx:1.8`. -_____ - -Do: Set the value of the `replicas` field to 2. - -Don't: Set the value of the `replicas` field to 2. -_____ - -## Code snippet formatting - -### Don’t include the command prompt - -Do: yarn start - -Don't: $ yarn start - -## Content best practices - -This section contains suggested best practices for clear, concise, and consistent content. - -### Use present tense - -Do: This command starts a proxy. - -Don't: This command will start a proxy. - -Exception: Use future or past tense if it is required to convey the correct meaning. - -### Use active voice - -Do: You can explore the API using a browser. - -Don't: The API can be explored using a browser. -_____ - -Do: The YAML file specifies the collection name. - -Don't: The collection name is specified in the YAML file. -_____ - -Exception: Use passive voice if active voice leads to an awkward construction. - -### Use simple and direct language - -Use simple and direct language. Avoid using unnecessary phrases, such as saying “please.” - -Do: To create an entry, … - -Don't: In order to create an entry, … -_____ - -Do: See the configuration file. - -Don't: Please see the configuration file. -_____ - -Do: View the fields. - -Don't: With this next command, we'll view the fields. -_____ - -### Address the reader as “you” - -Do: You can create a Deployment by … - -Don't: We'll create a Deployment by … -_____ - -Do: In the preceding output, you can see… - -Don't: In the preceding output, we can see … - -### Avoid Latin phrases - -Prefer English terms over Latin abbreviations. - -Do: For example, … - -Don't: e.g., … -_____ - -Do: That is, … - -Don't: i.e., … -_____ - -Exception: Use “etc.” for et cetera. - -## Patterns to avoid - -### Avoid using “we” - -Using “we” in a sentence can be confusing, because the reader might not know whether they’re part of the “we” you’re describing. - -Do: Version 1.4 includes … - -Don't: In version 1.4, we have added … -_____ - -Do: Netlify CMS provides a new feature for … - -Don't: We provide a new feature … -_____ - -Do: This page teaches you how to use Widgets. - -Don't: In this page, we are going to learn about Widgets. -_____ - -### Avoid jargon and idioms - -Some readers speak English as a second language. Avoid jargon and idioms to help them understand better. - -Do: Internally - -Don't: Under the hood, … -_____ - -Do: Create a new cluster. - -Don't: Turn up a new cluster. -_____ - -### Avoid statements about the future - -Avoid making promises or giving hints about the future. If you need to talk about an alpha feature, put the text under a heading that identifies it as alpha information. - -### Avoid statements that will soon be out of date - -Avoid words like “currently” and “new.” A feature that is new today will not be new in a few months. - -Do: In version 1.4, … - -Don't: In the current version, … -_____ - -Do: The Federation feature provides … - -Don't: The new Federation feature provides … -_____ diff --git a/website/content/pages/community.md b/website/content/pages/community.md deleted file mode 100644 index 60f5d042..00000000 --- a/website/content/pages/community.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -title: Community -headline: Help us build the CMS of the future. -subhead: Get support, give support, and find out what's new through the channels below. -sections: - - title: support - channels: - - title: Netlify CMS Slack - description: Live community chat for all things Netlify CMS. - url: /chat - - title: Netlify Community - description: Ask and answer questions on the Netlify CMS channel of the Netlify community forum. - url: https://community.netlify.com/c/netlify-cms - - title: GitHub Issues - description: Report bugs, request features, and comment on existing issues. - url: https://github.com/netlify/netlify-cms/issues - - title: Stack Overflow - description: Secondary forum. Questions should be tagged `netlify-cms`. - url: https://stackoverflow.com/questions/tagged/netlify-cms - - title: development - channels: - - title: Priorities - description: Priority issues board on the Netlify CMS GitHub repo. - url: https://github.com/netlify/netlify-cms/projects/7 ---- diff --git a/website/data/.keep b/website/data/.keep deleted file mode 100755 index e69de29b..00000000 diff --git a/website/data/docs.yml b/website/data/docs.yml deleted file mode 100644 index 168f6f02..00000000 --- a/website/data/docs.yml +++ /dev/null @@ -1,11 +0,0 @@ -styleoverrides: '/docs.css' -headline: Netlify builds, deploys, and hosts your front end. -bottomcta: - hook: Want to get started quick? - btns: - - type: primary - btntext: View our Templates - linksto: https://app.netlify.com/signup/templates - - type: secondary - btntext: Read our Tutorials - linksto: /tags/tutorial/ diff --git a/website/data/global.yaml b/website/data/global.yaml deleted file mode 100644 index e5addedc..00000000 --- a/website/data/global.yaml +++ /dev/null @@ -1,6 +0,0 @@ -footer: - buttons: - - name: "Twitter" - url: "https://twitter.com/netlifycms" - - name: "GitHub" - url: "https://github.com/netlify/netlify-cms" diff --git a/website/data/landing.yaml b/website/data/landing.yaml deleted file mode 100644 index b53e38ad..00000000 --- a/website/data/landing.yaml +++ /dev/null @@ -1,41 +0,0 @@ -hero: - headline: "Open source content management for your Git workflow" - subhead: "Use Netlify CMS with any static site generator for a faster and more flexible web project" - devfeatures: - - feature: "Static + content management = ♥" - description: "Get the speed, security, and scalability of a static site, while still providing a convenient editing interface for content." - - feature: "An integrated part of your Git workflow" - description: "Content is stored in your Git repository alongside your code for easier versioning, multi-channel publishing, and the option to handle content updates directly in Git." - - feature: "An extensible CMS built on React" - description: "Netlify CMS is built as a single-page React app. Create custom-styled previews, UI widgets, and editor plugins or add backends to support different Git platform APIs." - -cta: - primaryhook: "Getting started is simple and free." - primary: "Choose a template that’s pre-configured with a static site generator and deploys to a global CDN in one click." - button: "[Get started](/docs/start-with-a-template/)" - -editors: - hook: "A CMS that developers and content editors can agree on" - intro: "You get to implement modern front end tools to deliver a faster, safer, and more scalable site. Editors get a friendly UI and intuitive workflow that meets their content management requirements." - features: - - feature: "Editor-friendly user interface" - description: "The web-based app includes rich-text editing, real-time preview, and drag-and-drop media uploads." - imgpath: "feature-editor.svg" - - feature: "Intuitive workflow for content teams" - description: "Writers and editors can easily manage content from draft to review to publish across any number of custom content types." - imgpath: "feature-workflow.svg" - - feature: "Instant access without GitHub account" - description: "With [Git Gateway](/docs/git-gateway-backend/#git-gateway-with-netlify-identity), you can add CMS access for any team member — even if they don’t have a GitHub account. " - imgpath: "feature-access.svg" - -community: - hook: "Supported by a growing community" - features: - - feature: "Built on the Jamstack" - description: "Netlify CMS is based on client-side JavaScript, reusable APIs and prebuilt Markup. Compared to server-side CMS like WordPress, this means better performance, higher security, lower cost of scaling, and a better developer experience. You can learn more about the Jamstack on [jamstack.org](https://jamstack.org)." - - feature: "Support when you need it" - description: "Get up and running with comprehensive [documentation](/docs) and templates or work through difficult problems in our [community chat](https://netlifycms.org/chat)." - - feature: "A community-driven project you can help evolve" - description: "Netlify CMS is built by a community of more than 100 contributors — and you can help. Read the [contributing guide](/docs/contributor-guide) to join in." - contributors: "Made possible by awesome contributors" - diff --git a/website/data/notifications.yml b/website/data/notifications.yml deleted file mode 100644 index 8da2d8e3..00000000 --- a/website/data/notifications.yml +++ /dev/null @@ -1,40 +0,0 @@ -notifications: - - loud: true - message: Register to join us online for our next community dev meeting, every - other Wednesday at 9am-10am PT! - published: false - title: Netlify CMS Development Planning Sessions Promo - url: https://www.eventbrite.com/e/netlify-cms-planning-session-bi-weekly-tickets-35794058994 - - loud: true - message: We have a community chat - join now to ask questions and discuss the - project with other devs! - published: false - title: Chat shoutout - url: https://netlifycms.org/chat - - loud: true - message: Netlify CMS now supports GitLab! - published: false - title: GitLab announcement - url: /blog/2018/06/netlify-cms-now-supports-gitlab-as-a-backend/ - - loud: true - message: Announcing 2.0 - Bitbucket support and monorepo architecture! - published: false - title: 2.0 announcement - url: /blog/2018/07/netlify-cms-2-0-launches-with-bitbucket-support-and-a-new-monorepo-architecture - - loud: true - message: 2.1.0 release is out with external media library support! - published: false - title: 2.1.0 - external media libraries - url: /blog/2018/09/netlify-cms-2-1-0-adds-external-media-support-with-uploadcare - - loud: true - message: Learn more about the Jamstack at JAMstack Conf, San Francisco — 29-30 - October, 2018 - published: false - title: JAMStack_conf 2018 - url: https://jamstackconf.com/ - - loud: false - message: "Netlify stands in solidarity with the Black community. Make a - donation. Netlify will match it. #BlackLivesMatter" - published: false - title: Donate now - url: http://www.netlify.com/donation-matching/ diff --git a/website/data/updates.yml b/website/data/updates.yml deleted file mode 100644 index 30a689cc..00000000 --- a/website/data/updates.yml +++ /dev/null @@ -1,296 +0,0 @@ -updates: - - date: 2020-05-19T22:30:55.101Z - version: 2.10.49 - description: Improved search, relation widget for file collections, improvements - and bugfixes - - date: 2020-05-04T22:31:09.983Z - version: 2.10.48 - description: String template support in relation widget, more data access for - widget controls, bugfixes - - date: 2020-04-21T22:31:10.664Z - version: 2.10.47 - description: Improve caching, bugfix - - date: 2020-03-19T18:39:47.538Z - version: 2.10.33 - description: Bugfixes - - date: 2020-03-13T18:39:27.187Z - version: 2.10.32 - description: Add Catalan UI translation - - date: 2020-03-12T20:58:33.994Z - version: 2.10.31 - description: Lazy loading for large directories in GitHub, bugfixes - - date: 2020-03-03T21:00:34.318Z - version: 2.10.30 - description: Field defaults via query string, proxy backend as middleware, bugfixes - - date: 2020-02-27T21:00:33.890Z - version: 2.10.29 - description: Preserve non-configured fields, open authoring bugfixes - - date: 2020-02-25T22:11:47.613Z - description: Fix workflow PR label migrations - version: 2.10.28 - - date: 2020-02-25T22:12:09.753Z - description: GitHub backend improvements, reintroduce workflow PR labels, bugfixes - version: 2.10.27 - - date: 2020-02-22T05:00:00.000Z - description: Revert editorial workflow labels for GitHub - version: 2.10.26 - - date: 2020-02-05 - description: Local development support (beta), unpublish hook, bugfixes - version: 2.10.17 - - date: 2020-01-31 - description: prepublish/postpublish hooks, min/max select widget validation - version: 2.10.16 - - date: 2020-01-30 - description: bugfixes - version: 2.10.15 - - date: 2020-01-28 - description: bugfixes - version: 2.10.14 - - date: 2020-01-26 - description: fix multiple image field issue - version: 2.10.13 - - date: 2020-01-23 - description: fix Git Gateway/GitHub issues - version: 2.10.12 - - date: 2020-01-22 - description: fix image widget overflow - version: 2.10.11 - - date: 2020-01-22 - description: support dynamic (templated) media_folder/path_folder config - version: 2.10.10 - - date: 2020-01-21 - description: Git LFS support fixes, other backend fixes - version: 2.10.9 - - date: 2020-01-16 - description: Bugfixes - version: 2.10.8 - - date: 2020-01-15 - description: Bugfixes - version: 2.10.7 - - date: 2020-01-14 - description: Editorial workflow for GitLab and Bitbucket 🎉🎉 - version: 2.10.6 - - date: 2020-01-14 - description: Collection level media_folder, multiline shortcodes, max file size - validation - version: 2.10.5 - - date: 2020-01-09 - description: Bugfixes - version: 2.10.4 - - date: 2020-01-07 - description: Bundle assets with content, bugfixes - version: 2.10.3 - - date: 2019-12-20 - description: Fix incomplete previous release - version: 2.10.2 - - date: 2019-12-19 - description: Fix select and relation widgets not showing dropdown - version: 2.10.1 - - date: 2019-12-18 - description: Open Authoring, content bundles, code editor, and lots of bugfixes - version: 2.10.0 - - date: 2019-07-24 - description: Fix collection view search - version: 2.9.7 - - date: 2019-07-11 - description: Fix default values in list widgets - version: 2.9.6 - - date: 2019-06-28 - description: Fix entry loading for GitLab - version: 2.9.5 - - date: 2019-06-26 - description: Reference nested fields in relation widget, validate simple lists, bugfixes - version: 2.9.4 - - date: 2019-06-18 - description: Fix new entries error for non-GitHub backends - version: 2.9.3 - - date: 2019-06-14 - description: Match any char with shortcode/editor component patterns, bugfixes - version: 2.9.2 - - date: 2019-04-10 - description: Entry card customization, Bitbucket implicit auth, fix image - previews, other bugfixes - version: 2.9.1 - - date: 2019-03-29 - description: Add netlify-cms-app package with external deps, fix breaking - preview templates - version: 2.9.0 - - date: 2019-03-22 - description: Add es module builds, fix large media binary output - version: 2.8.0 - - date: 2019-03-21 - description: Standalone UMD builds with externalized dependencies for all - extension packages - version: 2.7.0 - - date: 2019-03-11 - description: Fix Cloudinary multiselect, preview pane and config fixes, other - improvements - version: 2.6.1 - - date: 2019-03-07 - description: Add entry recovery after error, fix large media GitHub URL output, - other fixes - version: 2.6.0 - - date: 2019-02-28 - description: Fix previews of GitHub images - version: 2.5.1 - - date: 2019-02-26 - description: Netlify Large Media support, multi-select relation widget, and more - version: 2.5.0 - - date: 2019-02-12 - description: Fix empty number widget values, accept explicit fields in slug template - version: 2.4.2 - - date: 2019-02-09T00:08:11.159Z - description: Bugfixes - version: 2.4.1 - - date: 2019-02-08T22:27:39.913Z - description: Deploy preview links, map widget, and nested field validation - version: 2.4.0 - url: https://www.netlifycms.org/blog/2019/02/netlify-cms-2-4-0 - - date: 2019-01-10 - description: Fix missing entry labels for file collections - version: 2.3.3 - - date: 2018-12-26 - description: Bugfixes, list widget variable types in beta - version: 2.3.2 - - date: 2018-12-11 - description: Bugfixes - version: 2.3.1 - - date: 2018-12-04 - description: Cloudinary support, multi-select in select widget - version: 2.3.0 - - date: 2018-11-29 - description: Date display formatting, lots of bugfixes - version: 2.2.1 - - date: 2018-11-12 - description: Custom identifier fields, custom logo on auth page, bugfixes - version: 2.2.0 - - date: 2018-10-09T13:57:04.203Z - description: Bugfixes - version: 2.1.3 - - date: 2018-09-17T16:49:32.506Z - description: Fix editorial workflow for Git Gateway - version: 2.1.2 - - date: 2018-09-06T16:48:08.594Z - description: Provide empty cms.css file to ease 2.x migration - version: 2.1.1 - - date: 2018-09-06T18:48:13.703Z - description: External media library support 🎉🎉 - version: 2.1.0 - - date: 2018-08-27 - description: Fix sortable list bugs in the editor - version: 2.0.11 - - date: 2018-08-24 - description: Editor hints, GitLab images and Markdown editor fixes, plus other bugs - version: 2.0.10 - - date: 2018-08-07 - description: Backend, workflow, and relation widget fixes/improvements - version: 2.0.9 - - date: 2018-08-01 - description: Fix workflow publishing - version: 2.0.8 - - date: 2018-08-01 - description: Fix uploads in backends, fix workflow, other bugfixes - version: 2.0.7 - - date: 2018-07-28 - description: Fix backends - version: 2.0.6 - - date: 2018-07-27 - description: Fix Git Gateway, other bugfixes - version: 2.0.5 - - date: 2018-07-26 - description: Bitbucket support! - version: 2.0.0 - - date: 2018-07-21 - description: Fix multipart extension support for GitLab - version: 1.9.4 - - date: 2018-07-03 - description: Fix numbers in TOML output. - version: 1.9.3 - - date: 2018-06-15 - description: Fix test-repo crash. - version: 1.9.2 - - date: 2018-06-14 - description: Fix GitLab Implicit OAuth - version: 1.9.1 - - date: 2018-06-12 - description: GitLab support is here!!! 🎉🎉🎉 - version: 1.9.0 - - date: 2018-05-25 - description: Fix markdown widget styling. - version: 1.8.4 - - date: 2018-05-25 - description: Dependency updates. - version: 1.8.3 - - date: 2018-05-24 - description: Fix failure to save/publish. - version: 1.8.2 - - date: 2018-05-23 - description: Allow upload of files larger than 1MB to GitHub, prevent - unintentional file overwrites. - version: 1.8.1 - - date: 2018-05-16 - description: Customizable relation widget display fields, squash merges for - editorial workflow, perf improvements. - version: 1.8.0 - - date: 2018-04-24 - description: Allow custom auth endpoint, bug fixes. - version: 1.7.0 - - date: 2018-04-19 - description: " Markdown toolbar customization, manual date widget entry, bug fixes." - version: 1.6.0 - - date: 2018-04-11 - description: New time based slug placeholders, set config.yml URL with <link>. - version: 1.5.0 - - date: 2018-03-29 - description: More control over filenames, lots of bugfixes, and new beta features! - version: 1.4.0 - - date: 2018-03-06 - description: Fixes styling issues - version: 1.3.5 - - date: 2018-03-06 - description: Fixes editorial workflow entry failure. - version: 1.3.4 - - date: 2018-03-06 - description: Fixes load failure - version: 1.3.3 - - date: 2018-03-06 - description: Fixes date widget default format, collection load failure when entry fails. - version: 1.3.2 - - date: 2018-03-03 - description: Fixes editorial workflow failure for unknown collections. - version: 1.3.1 - - date: 2018-02-27 - description: Multi-part extensions, e.g. "en.md", a11y improvements in the - editor, and bugfixes. - version: 1.3.0 - - date: 2018-02-21 - description: Fixes ES5 transpiling. - version: 1.2.2 - - date: 2018-02-21 - description: Allows label_singular config for collections and lists and distinct - frontmatter delimiters. - version: 1.2.1 - - date: 2018-02-13 - description: Adds support for multiple frontmatter formats and custom - delimiters, UI improvements. - version: "1.2" - - date: 2018-01-25 - description: You can now register external backends and we improved metadata handling. - version: "1.1" - - date: 2018-01-23 - description: Fixes various UI bugs and adds expand / collapse functionality to - the object widget. - version: 1.0.4 - - date: 2018-12-19 - description: Small bug fix release. - version: 1.0.3 - - date: 2018-12-07 - description: Small bug fix release. - version: 1.0.2 - - date: 2018-12-07 - description: Small bug fix release. - version: 1.0.1 - - date: 2018-12-07 - description: The first major release of Netlify CMS with an all-new UI, revamped - documentation and much more. - version: 1.0.0 diff --git a/website/gatsby-browser.js b/website/gatsby-browser.js deleted file mode 100644 index 54c19635..00000000 --- a/website/gatsby-browser.js +++ /dev/null @@ -1,9 +0,0 @@ -// Make scroll behavior of internal links smooth -exports.onClientEntry = () => { - const SmoothScroll = require('smooth-scroll'); - new SmoothScroll('a[href*="#"]', { - offset() { - return document.querySelector('#header').offsetHeight; - }, - }); -}; diff --git a/website/gatsby-config.js b/website/gatsby-config.js deleted file mode 100644 index f3d1f481..00000000 --- a/website/gatsby-config.js +++ /dev/null @@ -1,76 +0,0 @@ -const fs = require('fs'); -const yaml = require('js-yaml'); - -const pkg = require('./package.json'); - -const staticConfig = yaml.load(fs.readFileSync('./site.yml', 'utf8')); - -module.exports = { - siteMetadata: { - title: 'Netlify CMS | Open-Source Content Management System', - description: 'Open source content management for your Git workflow', - siteUrl: pkg.homepage, - menu: staticConfig.menu, - }, - plugins: [ - { - resolve: 'gatsby-plugin-manifest', - options: { - name: 'NetlifyCMS', - short_name: 'NetlifyCMS', - start_url: '/', - background_color: '#ffffff', - theme_color: '#ffffff', - display: 'standalone', - icon: 'static/img/favicon/icon-512x512.png', - }, - }, - { - resolve: 'gatsby-source-filesystem', - options: { - path: `${__dirname}/content`, - name: 'content', - }, - }, - { - resolve: 'gatsby-source-filesystem', - options: { - path: `${__dirname}/data`, - name: 'data', - }, - }, - { - resolve: 'gatsby-transformer-remark', - options: { - // prettier-ignore - plugins: [ - 'gatsby-remark-autolink-headers', - { - resolve: "gatsby-remark-external-links", - options: { - target: "_blank", - rel: "noopener noreferrer" - } - }, - { - resolve: 'gatsby-remark-prismjs', - options: { - noInlineHighlight: true, - }, - }, - ], - }, - }, - 'gatsby-transformer-yaml', - 'gatsby-transformer-json', - 'gatsby-plugin-emotion', - 'gatsby-plugin-react-helmet', - 'gatsby-plugin-catch-links', - { - resolve: 'gatsby-plugin-netlify-cms', - options: { - modulePath: `${__dirname}/src/cms/cms.js`, - }, - }, - ], -}; diff --git a/website/gatsby-node.js b/website/gatsby-node.js deleted file mode 100644 index 0369cb1a..00000000 --- a/website/gatsby-node.js +++ /dev/null @@ -1,104 +0,0 @@ -const path = require('path'); -const { createFilePath } = require('gatsby-source-filesystem'); - -exports.createPages = async ({ graphql, actions }) => { - const { createPage } = actions; - - const docPage = path.resolve('./src/templates/doc-page.js'); - const blogPost = path.resolve('./src/templates/blog-post.js'); - - // get all markdown with a frontmatter path field and title - const allMarkdown = await graphql(` - { - allMarkdownRemark(filter: { frontmatter: { title: { ne: null } } }) { - edges { - node { - fields { - slug - } - frontmatter { - title - } - } - } - } - } - `); - - if (allMarkdown.errors) { - console.error(allMarkdown.errors); // eslint-disable-line no-console - throw Error(allMarkdown.errors); - } - - allMarkdown.data.allMarkdownRemark.edges.forEach(({ node }) => { - const { slug } = node.fields; - - let template = docPage; - - if (slug.includes('blog/')) { - template = blogPost; - } - - createPage({ - path: slug, - component: template, - context: { - slug, - }, - }); - }); -}; - -function pad(n) { - return n >= 10 ? n : `0${n}`; -} - -exports.onCreateNode = ({ node, actions, getNode }) => { - const { createNodeField } = actions; - - if (node.internal.type === 'MarkdownRemark') { - const value = createFilePath({ node, getNode }); - const { relativePath } = getNode(node.parent); - - let slug = value; - - if (relativePath.includes('blog/')) { - const date = new Date(node.frontmatter.date); - const year = date.getFullYear(); - const month = date.getMonth() + 1; - const filename = path.basename(relativePath, '.md'); - slug = `/blog/${year}/${pad(month)}/${filename}`; - - createNodeField({ - node, - name: 'date', - value: date.toJSON(), - }); - } - - // used for doc posts - createNodeField({ - node, - name: 'slug', - value: slug, - }); - - // used to create GitHub edit link - createNodeField({ - node, - name: 'path', - value: relativePath, - }); - } -}; - -exports.onCreateWebpackConfig = ({ actions }) => { - actions.setWebpackConfig({ - resolve: { - extensions: ['.ts', '.tsx', '.js', '.json'], - alias: { - moment$: 'moment/moment.js', - }, - }, - }); -}; diff --git a/website/netlify.toml b/website/netlify.toml deleted file mode 100644 index 7c0c6eba..00000000 --- a/website/netlify.toml +++ /dev/null @@ -1,8 +0,0 @@ -[build] - base = "website/" - command = "yarn install && yarn lint && yarn build" - publish = "dist/" - - [build.environment] - YARN_FLAGS = "--frozen-lockfile" - YARN_VERSION = "1.22.4" diff --git a/website/package.json b/website/package.json deleted file mode 100644 index d458dc86..00000000 --- a/website/package.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "name": "netlify-cms-site", - "version": "1.0.0", - "description": "Netlify CMS documentation website built with Gatsby", - "scripts": { - "start": "gatsby develop", - "build": "gatsby build && rm -rf dist && mv public dist", - "lint": "markdownlint 'content/docs/**/*.md'", - "copy:contribs": "cp ../.all-contributorsrc data/contributors.json", - "prepare": "npm run copy:contribs", - "reset": "rm -rf .cache" - }, - "author": "", - "homepage": "https://www.netlifycms.org/", - "license": "MIT", - "dependencies": { - "@emotion/cache": "11.10.3", - "@emotion/react": "11.10.4", - "@emotion/styled": "11.10.4", - "dayjs": "^1.8.23", - "emotion-theming": "^10.0.27", - "gatsby": "3.14.6", - "gatsby-plugin-catch-links": "3.14.0", - "gatsby-plugin-emotion": "^4.0.0", - "gatsby-plugin-manifest": "3.14.0", - "gatsby-plugin-netlify-cms": "5.14.0", - "gatsby-plugin-react-helmet": "4.14.0", - "gatsby-remark-autolink-headers": "4.11.0", - "gatsby-remark-external-links": "^0.0.4", - "gatsby-remark-prismjs": "5.11.0", - "gatsby-source-filesystem": "3.14.0", - "gatsby-transformer-json": "3.14.0", - "gatsby-transformer-remark": "4.11.0", - "gatsby-transformer-yaml": "3.14.0", - "js-yaml": "^4.0.0", - "lodash": "^4.17.15", - "moment": "^2.24.0", - "netlify-cms-app": "^2.15.72", - "prismjs": "^1.21.0", - "react": "^17.0.1", - "react-dom": "^17.0.1", - "react-github-btn": "^1.1.1", - "react-helmet": "^6.0.0", - "react-markdown": "^6.0.0", - "smooth-scroll": "^16.1.2" - }, - "devDependencies": { - "babel-plugin-prismjs": "^2.0.1", - "babel-preset-gatsby": "^1.0.0", - "eslint": "^7.4.0", - "eslint-plugin-import": "^2.20.1", - "markdownlint-cli": "^0.31.0" - }, - "private": true -} diff --git a/website/site.yml b/website/site.yml deleted file mode 100644 index b8177f56..00000000 --- a/website/site.yml +++ /dev/null @@ -1,22 +0,0 @@ -menu: - docs: - - name: Intro - title: Intro to Netlify CMS - - name: Accounts - title: Account Settings - - name: Configuration - title: Configuring your Site - - name: Media - title: Media - - name: Workflow - title: Workflow - - name: Collections - title: Collections - - name: Fields - title: Fields - - name: Guides - title: Platform Guides - - name: Customization - title: Customizing Netlify CMS - - name: Contributing - title: Community diff --git a/website/src/cms/cms.js b/website/src/cms/cms.js deleted file mode 100644 index f87dfb51..00000000 --- a/website/src/cms/cms.js +++ /dev/null @@ -1,140 +0,0 @@ -import React from 'react'; -import CMS from 'netlify-cms-app'; -import dayjs from 'dayjs'; -import Prism from 'prismjs'; -import { CacheProvider } from '@emotion/react'; -import createCache from '@emotion/cache'; - -import BlogPostTemplate from '../components/blog-post-template'; -import { LayoutTemplate as Layout } from '../components/layout'; -import DocsTemplate from '../components/docs-template'; -import WidgetDoc from '../components/widget-doc'; -import WhatsNew from '../components/whats-new'; -import Notification from '../components/notification'; -import Community from '../components/community'; -import siteConfig from '../../site.yml'; - -let emotionCache; -function getEmotionCache() { - const previewPaneIframe = document.querySelector('iframe[class*="PreviewPaneFrame"]'); - const previewPaneHeadEl = previewPaneIframe.contentWindow.document.querySelector('head'); - if (!emotionCache || emotionCache.sheet.container !== previewPaneHeadEl) { - emotionCache = createCache({ container: previewPaneHeadEl }); - } - return emotionCache; -} - -function PreviewContainer({ children, highlight }) { - return ( - - {highlight ? {children} : children} - - ); -} - -class Highlight extends React.Component { - constructor(props) { - super(props); - this.ref = React.createRef(); - } - - highlight() { - setTimeout(() => { - if (this.ref.current) { - Prism.highlightAllUnder(this.ref.current); - } - }); - } - - componentDidMount() { - this.highlight(); - } - - componentDidUpdate() { - this.highlight(); - } - - render() { - return
    {this.props.children}
    ; - } -} - -function BlogPostPreview({ entry, widgetFor }) { - const data = entry.get('data'); - return ( - - - - ); -} - -function CommunityPreview({ entry }) { - const { title, headline, subhead, sections } = entry.get('data').toJS(); - return ( - - - - ); -} - -function DocsPreview({ entry, widgetFor }) { - return ( - - - - ); -} - -function WidgetDocPreview({ entry, widgetFor }) { - return ( - - - - ); -} - -function ReleasePreview({ entry }) { - return ( - - ({ - version: release.get('version'), - date: dayjs(release.get('date')).format('MMMM D, YYYY'), - description: release.get('description'), - })) - .toJS()} - /> - - ); -} - -function NotificationPreview({ entry }) { - return ( - - {entry - .getIn(['data', 'notifications']) - .filter(notif => notif.get('published')) - .map((notif, idx) => ( - - {notif.get('message')} - - ))} - - ); -} - -CMS.registerPreviewTemplate('blog', BlogPostPreview); -siteConfig.menu.docs.forEach(group => { - CMS.registerPreviewTemplate(`docs_${group.name}`, DocsPreview); -}); -CMS.registerPreviewTemplate('widget_docs', WidgetDocPreview); -CMS.registerPreviewTemplate('releases', ReleasePreview); -CMS.registerPreviewTemplate('notifications', NotificationPreview); -CMS.registerPreviewTemplate('community', CommunityPreview); diff --git a/website/src/components/blog-post-template.js b/website/src/components/blog-post-template.js deleted file mode 100644 index bb18ed54..00000000 --- a/website/src/components/blog-post-template.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react'; -import { css } from '@emotion/react'; - -import Container from './container'; -import Markdown from './markdown'; -import MetaInfo from './meta-info'; -import Page from './page'; - -export default function BlogPostTemplate({ title, author, date, body, html }) { - return ( - - -

    - {title} -

    - - by {author} on {date} - - -
    -
    - ); -} diff --git a/website/src/components/button.js b/website/src/components/button.js deleted file mode 100644 index 1fda50e9..00000000 --- a/website/src/components/button.js +++ /dev/null @@ -1,34 +0,0 @@ -import { css } from '@emotion/react'; -import styled from '@emotion/styled'; - -import theme from '../theme'; - -// prettier-ignore -const Button = styled.button` - display: inline-block; - background-image: linear-gradient(0deg, #97bf2f 14%, #c9fa4b 94%); - color: ${theme.colors.darkGray}; - border-radius: ${theme.radii[1]}; - font-size: ${theme.fontsize[3]}; - font-weight: 700; - padding: ${theme.space[2]} ${theme.space[3]}; - border: 2px solid ${theme.colors.darkGreen}; - cursor: pointer; - - ${p => p.block && css` - display: block; - width: 100%; - `}; - - ${p => p.outline && css` - background: none; - font-weight: 500; - `}; - - ${p => p.active && css` - background: ${theme.colors.darkGreen}; - color: white; - `}; -`; - -export default Button; diff --git a/website/src/components/chat-button.js b/website/src/components/chat-button.js deleted file mode 100644 index fd37c775..00000000 --- a/website/src/components/chat-button.js +++ /dev/null @@ -1,20 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; - -const ChatLink = styled.a` - z-index: 100; - position: fixed; - bottom: 10px; - right: 10px; - cursor: pointer; -`; - -function ChatButton() { - return ( - - - - ); -} - -export default ChatButton; diff --git a/website/src/components/community-channels-list.js b/website/src/components/community-channels-list.js deleted file mode 100644 index 5b8b22b7..00000000 --- a/website/src/components/community-channels-list.js +++ /dev/null @@ -1,59 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; - -import theme from '../theme'; - -const StyledCommunityChannelsList = styled.ul` - margin-left: 0; - - li { - list-style-type: none; - margin-bottom: 24px; - } - - a { - display: block; - font-weight: inherit; - position: relative; - - &:focus, - &:active, - &:hover { - &:before { - display: block; - } - } - - &:before { - display: none; - content: ''; - position: absolute; - width: 3px; - height: 100%; - background-color: ${theme.colors.darkGreen}; - left: -16px; - } - } - - p { - color: ${theme.colors.gray}; - margin-bottom: 0; - } -`; - -function CommunityChannelsList({ channels }) { - return ( - - {channels.map(({ title, description, url }, idx) => ( -
  • - - {title} -

    {description}

    -
    -
  • - ))} -
    - ); -} - -export default CommunityChannelsList; diff --git a/website/src/components/community.js b/website/src/components/community.js deleted file mode 100644 index ffe334e0..00000000 --- a/website/src/components/community.js +++ /dev/null @@ -1,55 +0,0 @@ -import React from 'react'; -import { css } from '@emotion/react'; - -import Markdownify from './markdownify'; -import PageHero from './page-hero'; -import HeroTitle from './hero-title'; -import Lead from './lead'; -import Container from './container'; -import SectionLabel from './section-label'; -import Page from './page'; -import Grid from './grid'; -import CommunityChannelsList from './community-channels-list'; -import theme from '../theme'; - -function Community({ headline, subhead, sections }) { - return ( - <> - -
    - - - - - - -
    -
    - - - - -
    - {sections.map(({ title: sectionTitle, channels }, channelIdx) => ( - - {sectionTitle} - - - ))} -
    -
    -
    -
    - - ); -} - -export default Community; diff --git a/website/src/components/container.js b/website/src/components/container.js deleted file mode 100644 index bd9c5f9f..00000000 --- a/website/src/components/container.js +++ /dev/null @@ -1,32 +0,0 @@ -import styled from '@emotion/styled'; -import { css } from '@emotion/react'; - -import { mq } from '../utils'; -import theme from '../theme'; - -const Container = styled.div` - margin-left: auto; - margin-right: auto; - max-width: 1280px; - padding-left: ${theme.space[4]}; - padding-right: ${theme.space[4]}; - - ${p => - p.size === 'sm' && - css` - max-width: 800px; - `}; - - ${p => - p.size === 'md' && - css` - max-width: 1024px; - `}; - - ${mq[3]} { - padding-left: ${theme.space[5]}; - padding-right: ${theme.space[5]}; - } -`; - -export default Container; diff --git a/website/src/components/docs-nav.js b/website/src/components/docs-nav.js deleted file mode 100644 index cf2339f9..00000000 --- a/website/src/components/docs-nav.js +++ /dev/null @@ -1,101 +0,0 @@ -import React, { useState } from 'react'; -import { Link } from 'gatsby'; -import styled from '@emotion/styled'; - -import Button from './button'; -import TableOfContents from './table-of-contents'; -import { mq } from '../utils'; -import theme from '../theme'; - -const Menu = styled.nav` - margin-bottom: ${theme.space[5]}; -`; - -const MenuBtn = styled(Button)` - ${mq[1]} { - display: none; - } -`; - -const MenuContent = styled.div` - display: ${p => (p.isOpen ? 'block' : 'none')}; - background: white; - padding: ${theme.space[3]}; - - ${mq[1]} { - display: block; - background: transparent; - padding: 0; - } -`; - -const MenuSection = styled.div` - margin-bottom: ${theme.space[3]}; -`; - -const SectionTitle = styled.h3` - font-size: ${theme.fontsize[4]}; - margin-bottom: ${theme.space[2]}; -`; - -const SectionList = styled.ul``; - -const MenuItem = styled.li``; - -const NavLink = styled(Link)` - display: block; - /* font-weight: $regular; */ - font-size: ${theme.fontsize[3]}; - color: ${theme.colors.gray}; - line-height: ${theme.lineHeight[1]}; - text-transform: capitalize; - transition: color 0.2s ease; - padding: ${theme.space[2]} 0; - - &.active { - color: ${theme.colors.darkGreen}; - font-weight: bold; - } - - &:hover { - color: ${theme.colors.darkGreen}; - } -`; - -function DocsNav({ items, location }) { - const [isMenuOpen, setMenuOpen] = useState(false); - - function toggleMenu() { - setMenuOpen(isOpen => !isOpen); - } - - return ( - - - {isMenuOpen ? × : } {isMenuOpen ? 'Hide' : 'Show'}{' '} - Navigation - - - {items.map(item => ( - - {item.title} - - {item.group.edges.map(({ node }) => ( - - - {node.frontmatter.title} - - {location.pathname === node.fields.slug && } - - ))} - - - ))} - - - ); -} - -export default DocsNav; - -export { NavLink }; diff --git a/website/src/components/docs-template.js b/website/src/components/docs-template.js deleted file mode 100644 index 5fb66396..00000000 --- a/website/src/components/docs-template.js +++ /dev/null @@ -1,42 +0,0 @@ -import React from 'react'; - -import Container from './container'; -import SidebarLayout from './sidebar-layout'; -import EditLink from './edit-link'; -import Widgets from './widgets'; -import Markdown from './markdown'; -import DocsNav from './docs-nav'; - -function DocsSidebar({ docsNav, location }) { - return ( - - ); -} - -export default function DocsTemplate({ - title, - filename, - body, - html, - showWidgets, - widgets, - showSidebar, - docsNav, - location, - group, -}) { - return ( - - }> -
    - {filename && } -

    {title}

    - - {showWidgets && } -
    -
    -
    - ); -} diff --git a/website/src/components/docsearch.js b/website/src/components/docsearch.js deleted file mode 100644 index 92427789..00000000 --- a/website/src/components/docsearch.js +++ /dev/null @@ -1,56 +0,0 @@ -import React, { useState, useEffect, memo } from 'react'; -import styled from '@emotion/styled'; - -import theme from '../theme'; -import searchIcon from '../img/search.svg'; - -const SearchForm = styled.form` - > span { - width: 100%; - } -`; - -const SearchField = styled.input` - color: white; - font-size: ${theme.fontsize[3]}; - border-radius: ${theme.radii[1]}; - background-color: rgba(255, 255, 255, 0.1); - background-image: url(${searchIcon}); - background-repeat: no-repeat; - background-position: ${theme.space[2]} 50%; - border: 0; - appearance: none; - width: 100%; - padding: ${theme.space[2]}; - padding-left: 30px; - outline: 0; -`; - -function DocSearch() { - const [enabled, setEnabled] = useState(true); - - useEffect(() => { - if (window.docsearch) { - window.docsearch({ - apiKey: '08d03dc80862e84c70c5a1e769b13019', - indexName: 'netlifycms', - inputSelector: '#algolia-search', - debug: false, // Set debug to true if you want to inspect the dropdown - }); - } else { - setEnabled(false); - } - }, []); - - if (!enabled) { - return null; - } - - return ( - - - - ); -} - -export default memo(DocSearch); diff --git a/website/src/components/edit-link.js b/website/src/components/edit-link.js deleted file mode 100644 index 557a0e97..00000000 --- a/website/src/components/edit-link.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import { css } from '@emotion/react'; - -function EditLink({ collection, filename }) { - return ( - - ); -} - -export default EditLink; diff --git a/website/src/components/event-box.js b/website/src/components/event-box.js deleted file mode 100644 index 24b1abc3..00000000 --- a/website/src/components/event-box.js +++ /dev/null @@ -1,125 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import moment from 'moment'; -import styled from '@emotion/styled'; - -import Markdownify from './markdownify'; -import theme from '../theme'; - -const Root = styled.div` - text-align: center; - background: ${theme.colors.darkerGray}; - background-image: linear-gradient( - -17deg, - ${theme.colors.darkerGray} 17%, - ${theme.colors.darkGray} 94% - ); - border-radius: 8px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - padding: 24px; - padding-top: 40px; - max-width: 446px; -`; - -const Title = styled.h2` - font-size: 36px; - color: white; -`; - -const Cal = styled.div` - border-radius: 8px; - overflow: hidden; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.5); - margin: 24px auto; - max-width: 250px; -`; - -const Month = styled.div` - background: ${theme.colors.green}; - color: ${theme.colors.gray}; - font-weight: bold; - text-transform: uppercase; - letter-spacing: 4px; - font-size: 14px; - padding: 8px; -`; - -const Day = styled.div` - font-size: 104px; - line-height: 1.3; - font-weight: bold; - color: white; - border: 1px solid ${theme.colors.gray}; - border-top: none; - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; -`; - -const CalDates = styled.p` - color: white; - font-weight: bold; - font-size: ${theme.fontsize[4]}; - margin-bottom: ${theme.space[3]}; -`; - -const CalCta = styled.div``; - -function EventBox({ title, cta }) { - const [loading, setLoading] = useState(true); - const [eventDate, setEventDate] = useState(''); - - useEffect(() => { - const eventbriteToken = 'C5PX65CJBVIXWWLNFKLO'; - const eventbriteOrganiser = '14281996019'; - - const url = `https://www.eventbriteapi.com/v3/events/search/?token=${eventbriteToken}&organizer.id=${eventbriteOrganiser}&expand=venue%27`; - - fetch(url) - .then(res => res.json()) - .then(data => { - const eventDate = data.events[0].start.utc; - - setEventDate(eventDate); - setLoading(false); - }) - .catch(err => { - console.log(err); // eslint-disable-line no-console - // TODO: set state to show error message - - setLoading(false); - }); - }, []); - - const eventDateMoment = moment(eventDate); - - const offset = eventDateMoment.isDST() ? -7 : -8; - const month = eventDateMoment.format('MMMM'); - const day = eventDateMoment.format('DD'); - const datePrefix = eventDateMoment.format('dddd, MMMM Do'); - const dateSuffix = eventDateMoment.utcOffset(offset).format('h a'); - - const ellip = ; - - return ( - - {title} - - {loading ? 'loading' : month} - {loading ? ellip : day} - - - {loading ? ( - ellip - ) : ( - - {datePrefix} at {dateSuffix} PT - - )} - - - - - - ); -} - -export default EventBox; diff --git a/website/src/components/features.js b/website/src/components/features.js deleted file mode 100644 index c432f4d8..00000000 --- a/website/src/components/features.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; - -import Markdownify from './markdownify'; -import theme from '../theme'; - -const Box = styled.div` - margin-bottom: ${theme.space[5]}; - - img { - margin-bottom: ${theme.space[3]}; - margin-left: -${theme.space[2]}; - } -`; - -const Title = styled.h3` - color: ${p => (p.kind === 'light' ? theme.colors.white : theme.colors.gray)}; - font-size: ${theme.fontsize[4]}; -`; - -const Text = styled.p` - font-size: 18px; - a { - font-weight: 700; - } -`; - -function FeatureItem({ feature, description, imgpath, kind }) { - return ( - - {imgpath && } - - <Markdownify source={feature} /> - - - - - - ); -} - -function Features({ items, kind }) { - return items.map(item => ); -} - -export default Features; diff --git a/website/src/components/footer.js b/website/src/components/footer.js deleted file mode 100644 index 3d249699..00000000 --- a/website/src/components/footer.js +++ /dev/null @@ -1,97 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; - -import Container from './container'; -import theme from '../theme'; -import { mq } from '../utils'; - -const Root = styled.footer` - background: white; - padding-top: ${theme.space[4]}; - padding-bottom: ${theme.space[5]}; -`; - -const FooterGrid = styled.div` - text-align: center; - - ${mq[2]} { - display: flex; - align-items: center; - text-align: left; - } -`; - -const FooterButtons = styled.div` - margin-bottom: ${theme.space[3]}; - ${mq[2]} { - margin-bottom: 0; - } -`; - -const SocialButton = styled.a` - display: inline-block; - padding: ${theme.space[1]} ${theme.space[3]}; - background-color: ${theme.colors.lightishGray}; - color: white; - font-weight: 700; - font-size: ${theme.fontsize[2]}; - border-radius: ${theme.radii[1]}; - margin-right: ${theme.space[2]}; - - &:active, - &:hover { - background-color: ${theme.colors.darkGreen}; - } -`; - -const Info = styled.div` - font-size: ${theme.fontsize[1]}; - color: ${theme.colors.gray}; - opacity: 0.5; - - ${mq[2]} { - padding-left: ${theme.space[4]}; - } - - a { - font-weight: 700; - color: ${theme.colors.gray}; - } -`; - -function Footer({ buttons }) { - return ( - - - - - {buttons.map(btn => ( - - {btn.name} - - ))} - - -

    - - Distributed under MIT License - {' '} - ·{' '} - - Code of Conduct - -

    -
    -
    -
    -
    - ); -} - -export default Footer; diff --git a/website/src/components/github-button.js b/website/src/components/github-button.js deleted file mode 100644 index d00b0e47..00000000 --- a/website/src/components/github-button.js +++ /dev/null @@ -1,32 +0,0 @@ -import React, { PureComponent } from 'react'; - -class GitHubStarButton extends PureComponent { - async componentDidMount() { - const gitHubButtonModule = await import('github-buttons/dist/react'); - - this.GitHubButton = gitHubButtonModule.default; - - this.forceUpdate(); - } - - render() { - const GitHubButton = this.GitHubButton; - - if (!GitHubButton) { - return null; - } - - return ( - - Star - - ); - } -} - -export default GitHubStarButton; diff --git a/website/src/components/grid.js b/website/src/components/grid.js deleted file mode 100644 index 6ae93e0e..00000000 --- a/website/src/components/grid.js +++ /dev/null @@ -1,14 +0,0 @@ -import styled from '@emotion/styled'; - -import { mq } from '../utils'; -import theme from '../theme'; - -const Grid = styled.div` - ${mq[2]} { - display: grid; - grid-template-columns: repeat(${p => p.cols}, 1fr); - grid-gap: ${theme.space[7]}; - } -`; - -export default Grid; diff --git a/website/src/components/header.js b/website/src/components/header.js deleted file mode 100644 index 67d6777b..00000000 --- a/website/src/components/header.js +++ /dev/null @@ -1,244 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { Link, graphql, StaticQuery } from 'gatsby'; -import styled from '@emotion/styled'; -import { css } from '@emotion/react'; -import GitHubButton from 'react-github-btn'; - -import Container from './container'; -import Notifications from './notifications'; -import DocSearch from './docsearch'; -import logo from '../img/netlify-cms-logo.svg'; -import searchIcon from '../img/search.svg'; -import theme from '../theme'; -import { mq } from '../utils'; - -const StyledHeader = styled.header` - background: ${theme.colors.darkerGray}; - padding-top: ${theme.space[3]}; - padding-bottom: ${theme.space[3]}; - transition: background 0.2s ease, padding 0.2s ease, box-shadow 0.2s ease; - - ${mq[2]} { - position: sticky; - top: 0; - width: 100%; - z-index: ${theme.zIndexes.header}; - - ${p => - !p.collapsed && - css` - background: #2a2c24; - padding-top: ${theme.space[5]}; - padding-bottom: ${theme.space[5]}; - `}; - - ${p => - p.hasNotifications && - css` - padding-top: 0; - `}; - } -`; - -const HeaderContainer = styled(Container)` - display: flex; - align-items: center; - flex-wrap: wrap; -`; - -const Logo = styled.div` - flex: 1 0 50%; - ${mq[1]} { - flex: 0 0 auto; - margin-right: ${theme.space[5]}; - } -`; - -const MenuActions = styled.div` - flex: 1 0 50%; - display: flex; - justify-content: flex-end; - ${mq[1]} { - display: none; - } -`; - -const MenuBtn = styled.button` - background: none; - border: 0; - color: white; - padding: ${theme.space[3]}; - font-size: ${theme.fontsize[4]}; - line-height: 1; -`; - -const SearchBtn = styled(MenuBtn)``; - -const ToggleArea = styled.div` - display: ${p => (p.open ? 'block' : 'none')}; - flex: 1; - width: 100%; - margin-top: ${theme.space[3]}; - - ${mq[1]} { - display: block; - width: auto; - margin-top: 0; - } -`; - -const SearchBox = styled(ToggleArea)` - ${mq[1]} { - flex: 1; - max-width: 200px; - margin-right: ${theme.space[3]}; - } -`; - -const Menu = styled(ToggleArea)` - ${mq[1]} { - flex: 0 0 auto; - margin-left: auto; - } -`; - -const MenuList = styled.ul` - ${mq[1]} { - display: flex; - justify-content: space-between; - align-items: center; - flex-wrap: wrap; - } -`; - -const MenuItem = styled.li` - margin-bottom: ${theme.space[3]}; - ${mq[1]} { - margin-bottom: 0; - - &:not(:last-child) { - margin-right: ${theme.space[3]}; - } - } -`; - -const NavLink = styled(Link)` - color: white; - text-decoration: none; - font-weight: 600; -`; - -const NOTIFS_QUERY = graphql` - query notifs { - file(relativePath: { regex: "/notifications/" }) { - childDataYaml { - notifications { - published - loud - message - url - } - } - } - } -`; - -function Header({ hasHeroBelow }) { - const [scrolled, setScrolled] = useState(false); - const [isNavOpen, setNavOpen] = useState(false); - const [isSearchOpen, setSearchOpen] = useState(false); - - useEffect(() => { - // TODO: use raf to throttle events - window.addEventListener('scroll', handleScroll); - - return () => { - window.removeEventListener('scroll', handleScroll); - }; - }, []); - - function handleScroll() { - const currentWindowPos = document.documentElement.scrollTop || document.body.scrollTop; - - const scrolled = currentWindowPos > 0; - - setScrolled(scrolled); - } - - function handleMenuBtnClick() { - setNavOpen(s => !s); - setSearchOpen(false); - } - - function handleSearchBtnClick() { - setSearchOpen(s => !s); - setNavOpen(false); - } - - return ( - - {data => { - const notifications = data.file.childDataYaml.notifications.filter( - notif => notif.published, - ); - const collapsed = !hasHeroBelow || scrolled; - const hasNotifications = notifications.length > 0; - return ( - - - - - - Netlify CMS logo - - - - - {isSearchOpen ? × : search} - - - {isNavOpen ? × : } - - - - - - - - - - Star - - - - Docs - - - Contributing - - - Community - - - Blog - - - - - - ); - }} - - ); -} - -export default Header; diff --git a/website/src/components/hero-title.js b/website/src/components/hero-title.js deleted file mode 100644 index f7bf9e32..00000000 --- a/website/src/components/hero-title.js +++ /dev/null @@ -1,17 +0,0 @@ -import styled from '@emotion/styled'; - -import theme from '../theme'; -import { mq } from '../utils'; - -const HeroTitle = styled.h1` - color: ${theme.colors.green}; - font-size: ${theme.fontsize[6]}; - margin-bottom: ${theme.space[1]}; - - ${mq[2]} { - font-size: ${theme.fontsize[7]}; - margin-bottom: ${theme.space[2]}; - } -`; - -export default HeroTitle; diff --git a/website/src/components/home-section.js b/website/src/components/home-section.js deleted file mode 100644 index 1080c8b7..00000000 --- a/website/src/components/home-section.js +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import styled from '@emotion/styled'; - -import Container from './container'; -import Page from './page'; -import theme from '../theme'; - -const Header = styled.header` - text-align: center; - padding-top: ${theme.space[7]}; - padding-bottom: ${theme.space[7]}; -`; - -const Title = styled.h2` - font-size: ${theme.fontsize[6]}; -`; - -const Text = styled.div` - max-width: 710px; - margin: 0 auto; -`; - -function HomeSection({ title, text, children, ...props }) { - return ( - - -
    - {title} - {text && {text}} -
    - {children} -
    -
    - ); -} - -export default HomeSection; diff --git a/website/src/components/layout.js b/website/src/components/layout.js deleted file mode 100644 index aa783c6b..00000000 --- a/website/src/components/layout.js +++ /dev/null @@ -1,69 +0,0 @@ -import React from 'react'; -import { Helmet } from 'react-helmet'; -import { graphql, StaticQuery } from 'gatsby'; -import { ThemeProvider } from 'emotion-theming'; - -import Header from './header'; -import Footer from './footer'; -import theme from '../theme'; - -const LAYOUT_QUERY = graphql` - query layoutQuery { - site { - siteMetadata { - title - description - } - } - footer: file(relativePath: { regex: "/global/" }) { - childDataYaml { - footer { - buttons { - url - name - } - } - } - } - } -`; - -export function LayoutTemplate({ children }) { - return ( - - {children} - - ); -} - -function Layout({ hasPageHero, children }) { - return ( - - {data => { - const { title, description } = data.site.siteMetadata; - - return ( - - - - - -
    - {children} -