{"id":16578035,"url":"https://github.com/glynnbird/couchshell","last_synced_at":"2025-07-03T07:06:06.974Z","repository":{"id":29448903,"uuid":"32985146","full_name":"glynnbird/couchshell","owner":"glynnbird","description":"A simple command-line shell that allows you to interact with CouchDB/Cloudant as if it were a Unix file system","archived":false,"fork":false,"pushed_at":"2024-07-30T14:57:04.000Z","size":311,"stargazers_count":28,"open_issues_count":2,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-04-22T09:23:44.726Z","etag":null,"topics":["cli","cloudant","couchdb","nodejs","shell"],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"polyglot-mark/salesforce-plugin","license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/glynnbird.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2015-03-27T12:36:15.000Z","updated_at":"2024-11-10T07:11:35.000Z","dependencies_parsed_at":"2024-10-27T11:27:32.717Z","dependency_job_id":"2522a679-53ac-495d-970a-058fad5133f2","html_url":"https://github.com/glynnbird/couchshell","commit_stats":{"total_commits":43,"total_committers":3,"mean_commits":"14.333333333333334","dds":0.06976744186046513,"last_synced_commit":"d71b905afa5c8b72d4ee2a170927091e94e2b113"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/glynnbird/couchshell","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glynnbird%2Fcouchshell","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glynnbird%2Fcouchshell/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glynnbird%2Fcouchshell/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glynnbird%2Fcouchshell/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/glynnbird","download_url":"https://codeload.github.com/glynnbird/couchshell/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/glynnbird%2Fcouchshell/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260722006,"owners_count":23052268,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","cloudant","couchdb","nodejs","shell"],"created_at":"2024-10-11T22:12:57.253Z","updated_at":"2025-07-03T07:06:06.951Z","avatar_url":"https://github.com/glynnbird.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# couchshell\n\n```\n   _____                 _      _____ _          _ _ \n  / ____|               | |    / ____| |        | | |\n | |     ___  _   _  ___| |__ | (___ | |__   ___| | |\n | |    / _ \\| | | |/ __| '_ \\ \\___ \\| '_ \\ / _ \\ | |\n | |___| (_) | |_| | (__| | | |____) | | | |  __/ | |\n  \\_____\\___/ \\__,_|\\___|_| |_|_____/|_| |_|\\___|_|_|\n                                                     \n```\n\nCouchshell is a command-line shell utility that allows you to interact with a CouchDB/Cloudant interface as if it were a Unix file system.\n\n* mkdir - create database\n* rmdir - remove database\n* cd - change database\n* ls/ll - list contents of database or list of databases\n* cat - show contents of document or datbase stats\n* echo - create document\n* rm - remove document\n* cp - copy a document or database\n* head - show first few documents from a database\n* touch - load and save a document\n* pwd - show the current database\n* tree - show revision history and conflicts from a document\n* du - show disk space usage of a database\n* fsck - remove conflicts from a document\n\n## Installation\n\n    npm install -g couchshell\n\n## Define the URL of your CouchDB/Cloudant server\n\nSet an environment variable called `COUCH_URL` which contains the URL of your CouchDB or Cloudant instance e.g.\n\n    export COUCH_URL=http://127.0.0.1:5984\n\nor \n\n    export COUCH_URL=https://myusername:mypassword@myhost.cloudant.com\n\n### IAM Authentication\n\nAlternatively, if you are using IAM authentication with IBM Cloudant, then supply two environment variables:\n\n- `COUCH_URL` - the URL of your Cloudant host e.g. `https://myhost.cloudant.com` (note absence of username and password in URL).\n- `IAM_API_KEY` - the IAM API KEY e.g. `ABC123515-151215`.\n\n## Starting couchshell\n\n    $ couchshell\n    Type \"help\" or press enter for a list of commands\n    \u003e\u003e\n\nYou now have access to your CouchDB server as if is a file system with databases represented as directories at the root level and documents as files inside the directories.\n\n\n## Create database (directory)\n\n    \u003e\u003e mkdir mydb\n  \n## Change directory\n\nWe can deal with a database by using the `cd` shell commmand:\n\n    \u003e\u003e cd mydb\n    mydb \u003e\u003e\n  \nOr return back to the home directory with\n\n    \u003e\u003e cd ..\n    \u003e\u003e  \n\n## View the contents of a directory\n\nWe can see the contents of a directory with `ls`:\n\n    \u003e\u003e ls\n    _replicator _users accidents anagrammer articles cache conference db10 feeds geoquiz geoquiz_stats houseprices\n    \u003e\u003e\n\nor `ll`:\n\n    \u003e\u003e ll\n    _replicator\n    _users\n    accidents\n    anagrammer\n    articles\n    cache\n    conference\n    db10\n    feeds\n    geoquiz\n    geoquiz_stats\n    houseprices\n    hp\n    mydb\n    nottage\n    pt_test\n    remote\n    test\n    \u003e\u003e\n\nAt the top level we see a list of databases. When we have `cd`'d to database, we see a list of documents:\n\n    geoquiz \u003e\u003e ll\n    _design/fetch\n    afghanistan\n    alabama\n    alaska\n    albania\n    algeria\n    angola\n    antarctica\n    argentina\n    arizona\n    geoquiz \n    \u003e\u003e\n\nWe can also add the starting letters of a document's id to narrow the list:\n\n    geoquiz \u003e\u003e ll do\n    dogger\n    dominican republic\n    dorset\n    dover\n    geoquiz \u003e\u003e\n\n## Viewing the contents of a database\n\nWhen at the top level, using `cat` shows a databases's stats:\n\n    \u003e\u003e cat geoquiz\n    {\"db_name\":\"geoquiz\",\"doc_count\":292,\"doc_del_count\":2,\"update_seq\":296,\"purge_seq\":0,\"compact_running\":false,\"disk_size\":2682993,\"data_size\":2634563,\"instance_start_time\":\"1427369661867062\",\"disk_format_version\":6,\"committed_update_seq\":296}\n    \u003e\u003e\n\nWhen inside a database, `cat` shows the contents of a document:\n\n    geoquiz \u003e\u003e cat dover\n    {\"_id\":\"dover\",\"_rev\":\"1-7ea98285628d4bb3203a0ef3b1f34247\",\"type\":\"Feature\",\"properties\":{\"name\":\"Dover\",\"group\":\"Shipping Forecast\"},\"geometry\":{\"type\":\"Polygon\",\"coordinates\":[[[0.439453125,50.83369767098071],[1.58203125,50.233151832472245],[1.494140625,50.84757295365389],[1.7578125,50.94458443495011],[2.48291015625,51.08282186160978],[2.9443359375,51.28940590271679],[1.3842773437499998,51.26191485308451],[1.29638671875,51.12421275782688],[1.03271484375,51.069016659603896],[0.9667968749999999,50.93073802371819],[0.791015625,50.958426723359935],[0.439453125,50.83369767098071]]]}}\n    geoquiz \u003e\u003e\n\n## Creating data\n\nThis is where the anaology of directories \u0026 files --\u003e databases \u0026 documents is stretched. We use the `echo` command to generate data:\n\n    testdb \u003e\u003e echo '{\"a\":1,\"b\":2,\"c\":\"three\"}'\n    {\"ok\":true,\"id\":\"996dfcc55a3676485a6223b09d00b958\",\"rev\":\"1-debc5c8de13e1f36787fe391da8191a6\"}\n    testdb \u003e\u003e\n\nor we can specify the id by piping to a 'file':\n\n    testdb \u003e\u003e echo '{\"a\":1,\"b\":2,\"c\":\"three\"}' \u003e mydoc\n    {\"ok\":true,\"id\":\"mydoc\",\"rev\":\"1-debc5c8de13e1f36787fe391da8191a6\"}\n    testdb \u003e\u003e\n  \n## Touching data\n\nYou can create a new empty document, or 'touch' an existing one (load it and save it) by using `touch`:\n\n    test \u003e\u003e touch moo\n    {\"ok\":true,\"id\":\"moo\",\"rev\":\"1-967a00dff5e02add41819138abb3284d\"}\n    test \u003e\u003e touch moo\n    {\"ok\":true,\"id\":\"moo\",\"rev\":\"2-7051cbe5c8faecd085a3fa619e6e6337\"}\n    test \u003e\u003e\n    \n## Deleting data\n\nWe can remove documents with `rm`:\n\n    testdb \u003e\u003e rm mydoc\n    {\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-c1b6d2ae1a60056eac56f1f440b7b593\"}\n    testdb \u003e\u003e \n\nor remove whole directories with `rmdir`:\n\n    \u003e\u003e rmdir test\n    {\"ok\":true}\n\n## Copying a document\n\nWhen inside a directory (database), we can copy a document with:\n\n    testdb \u003e\u003e cp doc1 doc2\n    {\"ok\":true,\"id\":\"doc2\",\"rev\":\"1-fda016d0fc74921c9b324b7aff5cbbdb\"}\n     \nIf the destination document is already there, we will get an error:\n\n    testdb \u003e\u003e cp doc1 doc2\n    409: Document update conflict.\n\n## Copying a database\n\nWhen at the top of the directory tree, we can replicate one database to another with the `cp` commnand\n\n    \u003e\u003e cp databasea databaseb\n    Replication scheduled:\n    {\"ok\":true,\"id\":\"30990d73131ad3674d3d778dbb461d85\",\"rev\":\"1-6bf28911ef8daa72ecc51762955e6f9a\"}\n\nReplication happens asynchronously. We can check on its progress by using `cat` with the name of the target database:\n\n    \u003e\u003e cat databaseb\n    {\"db_name\":\"crimea\",\"doc_count\":18500,\"doc_del_count\":0,\"update_seq\":18500,\"purge_seq\":0,\"compact_running\":false,\"disk_size\":12021880,\"data_size\":11890503,\"instance_start_time\":\"1427978103035439\",\"disk_format_version\":6,\"committed_update_seq\":18500}\n    \nWe can even replicate to and from a remote URL:\n\n    \u003e\u003e cp databasea https://myusername:mypassword@myhost.cloudant.com/databaseb\n    Replication scheduled:\n    {\"ok\":true,\"id\":\"30990d73131ad3674d3d778dbb461d85\",\"rev\":\"1-6bf28911ef8daa72ecc51762955e6f9a\"}\n    \n## Showing first few documents from a database\n\nWhen at the top of the directory tree, we can output the first ten of a database's documents with `head`:\n\n    \u003e\u003e head geoquiz\n    [{\"id\":\"_design/fetch\",\"key\":\"_design/fetch\",\"value\":{\"rev\":\"1-a15cb9ce7b3a4466eb369f882fb0b717\"}},{\"id\":\"afghanistan\",\"key\":\"afghanistan\",\"value\":{\"rev\":\"1-9558a91d8b99d812baead834644dbb20\"}},{\"id\":\"alabama\",\"key\":\"alabama\",\"value\":{\"rev\":\"1-dda5ed5297b54d709d5946e1ca64f30a\"}},{\"id\":\"alaska\",\"key\":\"alaska\",\"value\":{\"rev\":\"1-aaac41905347745378f8b53d4cb4c407\"}},{\"id\":\"albania\",\"key\":\"albania\",\"value\":{\"rev\":\"1-594d450b3d155ca7a30e8fb097f4cba7\"}},{\"id\":\"algeria\",\"key\":\"algeria\",\"value\":{\"rev\":\"1-1a3a846e82373946eb4ef6066993441a\"}},{\"id\":\"angola\",\"key\":\"angola\",\"value\":{\"rev\":\"1-251dc285ef7c60330041350fae377047\"}},{\"id\":\"antarctica\",\"key\":\"antarctica\",\"value\":{\"rev\":\"1-eb7b0d1b313034977a266bda6bf3eb54\"}},{\"id\":\"argentina\",\"key\":\"argentina\",\"value\":{\"rev\":\"1-7c562dcca2e94e922ecf22e200adad0b\"}},{\"id\":\"arizona\",\"key\":\"arizona\",\"value\":{\"rev\":\"1-c02750010054f7ff3a0aa420747ef3c7\"}}]\n\n\n##  Showing the revision history of a document\n\nWhen inside a database (directory), you can see a visualisation of the revision history with `tree`:\n\nA document with only one revision  will simply show it's id and revision token:\n\n    testdb \u003e\u003e tree 87c8882011c89970bbe077ac67003479\n    id = 87c8882011c89970bbe077ac67003479\n    └─ 1-e14063a7ba34a22b100284ce731ad6ac *\n\nA document with many conflicts on revision 1 will look like this:\n\n    testdb \u003e\u003e tree 87c8882011c89970bbe077ac67003479\n    id = 87c8882011c89970bbe077ac67003479\n    └─ 1\n       ├─ 1-100785dab5598961c8588790a810d37c\n       ├─ 1-1234cfba23d341a6d3916372a782fd65\n       ├─ 1-16d159e554c289d5848a3ca8854f9807\n       ├─ 1-1f10158068c458605d02ed0199ccd23b\n       ├─ 1-45b83b90c5112878ad1a961b3e7ccaee\n       ├─ 1-5e52a4558f111a53afe6ef72ee831af8\n       ├─ 1-6a74408eb56ad564c1d461c97e3c47dc\n       ├─ 1-6f49e763289e848f1650a94043a1e792\n       ├─ 1-93b0bd6be8d346e28f95584a972c4e24\n       └─ 1-94ec1c1571a5b00a5f0bf4121af1ddef *\n       \nAnd a more complicated revision history may look like this:\n\n    testdb \u003e\u003e tree 87c8882011c89970bbe077ac67003479\n    id = 87c8882011c89970bbe077ac67003479\n    ├─ 1-46d69249075d3c7edebff00bb1eab65e\n    ├─ 2-cc0b8b79af66fba84a8443484bff5160\n    ├─ 3-52d91622d40f174894c567cc1fcee2e3\n    ├─ 4\n    │  ├─ 4-5c58ab6c4a15f5b8b880994fa52dfa68\n    │  └─ 4-8171912e80397748fbde74cc09d42c6e\n    ├─ 5-edec47733ea830362a5913b7f6312fe6\n    └─ 6\n       ├─ 6-5f24a47d9c6cbd78261830ef179aebfd\n       └─ 6-f564b9850dca8e61019aeabdd5480f3f *\n   \nThe winning revision is marked with an asterisk.\n\n## Removing conflicts from a document\n\nWe can delete all conflicting revisions from a document (other than the winning revision) using `fsck \u003cid\u003e`:\n\n```\nmydb \u003e\u003e tree mydoc\nid = mydoc\n└─ 1\n    ├─ 1-1a0f63dc5b1e38a31c3a42dbb4afe3db\n    ├─ 1-5eb7c1177ad06bf192c3dacf776cf3d3\n    ├─ 1-7c1dafbec62feefc2f0e875aea2f6093\n    ├─ 1-94ec1c1571a5b00a5f0bf4121af1ddef\n    ├─ 1-95630339bde96adda2be19207c4772c8\n    ├─ 1-9d1d7a18212c0c74369208e4aef7fa13\n    ├─ 1-d2701441808e0caee7c394d77fbe7550\n    ├─ 1-da86decbdae0ef60ad41c33c12870860\n    ├─ 1-e91608e02ae31b5c6085d5ca17d964e2\n    └─ 1-f5401b77bb604d6f55c04a0e661f69d4 *\nmydb \u003e\u003e fsck mydoc [{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-96d4749bff11e619f31c3918671ec072\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-0720b0ca56a1918feb5fac5bc0f5f7f6\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-41e157d902abb4a9a84e8fcd905b17da\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-421cc57d13e5f922fcc91f52e0884d3b\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-da7d32f6a0201bf1509632d0f4b58359\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-ef061a6709fa93bbc92f07277b81990a\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-558011a4162d26bdcec71166556627c6\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-19ffd7f841ddf020b42151d17f0012cc\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-4d8e91ebc73462334b69a76610264799\"}]\nmydb \u003e\u003e tree mydoc\nid = mydoc\n└─ 1-f5401b77bb604d6f55c04a0e661f69d4 *\n```\n\nAll of the conflicting revisions are deleted in a single bulk operation. You see the response to the bulk operation. \n\nIf we want to keep a specific revision (that is not current winning revision), then we can do `fsck \u003cid\u003e \u003crev\u003e`:\n\n```\nmydb \u003e\u003e tree mydoc\nid = mydoc\n└─ 1\n    ├─ 1-16d5fd150971e97f6adec5e17f515594\n    ├─ 1-2d9097166eeaeffc5ae70346fea0b988\n    ├─ 1-32616223ff8de17ee8a1afbcccc05e8e\n    ├─ 1-36602b53bf2918b393b1bef3c7648767\n    ├─ 1-49dedfaefc6f706b609bc75958499a13\n    ├─ 1-94ec1c1571a5b00a5f0bf4121af1ddef\n    ├─ 1-9e9b49aff3c1b99dcfa01e6292053aa9\n    ├─ 1-a3eefcfb591f999b87284663a287d3b9\n    ├─ 1-a7f639949923d35e26974b3b81522116\n    └─ 1-a8f68832e5dd0acc1d24d099dceea335 *\nmydb \u003e\u003e fsck mydoc 1-999\nThe revision 1-999 does not exist in the document.\nmydb \u003e\u003e fsck mydoc 1-a7f639949923d35e26974b3b81522116\n[{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-a10f20dc2f70275e85c36305086e0ce8\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-5ab18477afda68b7320e490113d35e74\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-ef061a6709fa93bbc92f07277b81990a\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-8ad6479190c7144359198ac216215ef3\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-c6ca34d99535e5c451752adae33a0336\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-e5aa1fb11293c85c0f84d23e4a0c6ae0\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-875565098342b16627e54b7cd6044818\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-4b432cb9348e2e07c9165d10dbdb1139\"},{\"ok\":true,\"id\":\"mydoc\",\"rev\":\"2-b9fbc1a19742fac04d1d98db95fb7b43\"}]\nmydb \u003e\u003e tree mydoc\nid = mydoc\n└─ 1-a7f639949923d35e26974b3b81522116 *\nmydb \u003e\u003e \n```\n\n## Showing the disk usage of a database\n\nWhen at the top level, we can show the statistics of a database using `du \u003cdbname\u003e`:\n\n    \u003e\u003e du ebooks  \n    {\"db_name\":\"ebooks\",\"doc_count\":41,\"doc_del_count\":0,\"update_seq\":41,\"purge_seq\":0,\"compact_running\":false,\"disk_size\":163944,\"data_size\":13856,\"instance_start_time\":\"1445498614131939\",\"disk_format_version\":6,\"committed_update_seq\":41}\n\nSimilarly if we are inside a database, we can simply use `du`:\n\n    \u003e\u003e cd ebooks\n    ebooks \u003e\u003e du\n    {\"db_name\":\"ebooks\",\"doc_count\":41,\"doc_del_count\":0,\"update_seq\":41,\"purge_seq\":0,\"compact_running\":false,\"disk_size\":163944,\"data_size\":13856,\"instance_start_time\":\"1445498614131939\",\"disk_format_version\":6,\"committed_update_seq\":41}\n\n## Todo\n\n* force rmdir to require confirmation before deleting a database","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglynnbird%2Fcouchshell","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fglynnbird%2Fcouchshell","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fglynnbird%2Fcouchshell/lists"}