{"id":23763975,"url":"https://github.com/tomashubelbauer/apple-notes-database","last_synced_at":"2026-03-22T16:30:19.612Z","repository":{"id":191350442,"uuid":"684278525","full_name":"TomasHubelbauer/apple-notes-database","owner":"TomasHubelbauer","description":null,"archived":false,"fork":false,"pushed_at":"2023-09-04T16:30:23.000Z","size":43,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2024-12-31T22:13:57.545Z","etag":null,"topics":["apple-notes","apple-script"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TomasHubelbauer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2023-08-28T20:14:55.000Z","updated_at":"2024-05-05T08:45:20.000Z","dependencies_parsed_at":"2023-08-29T13:08:27.876Z","dependency_job_id":null,"html_url":"https://github.com/TomasHubelbauer/apple-notes-database","commit_stats":null,"previous_names":["tomashubelbauer/apple-notes-database"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fapple-notes-database","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fapple-notes-database/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fapple-notes-database/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TomasHubelbauer%2Fapple-notes-database/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TomasHubelbauer","download_url":"https://codeload.github.com/TomasHubelbauer/apple-notes-database/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239937698,"owners_count":19721484,"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":["apple-notes","apple-script"],"created_at":"2024-12-31T22:13:59.954Z","updated_at":"2026-03-22T16:30:17.366Z","avatar_url":"https://github.com/TomasHubelbauer.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Apple Notes Database\n\n[![Playwright Tests](https://github.com/TomasHubelbauer/apple-notes-database/actions/workflows/playwright.yml/badge.svg)](https://github.com/TomasHubelbauer/apple-notes-database/actions/workflows/playwright.yml)\n\nThis project is an experiment in using Apple Notes as a storage layer for a web\napplication.\n\nIt is not meant to be practical, it is a creative exercise.\n\n## Running\n\nRun `PORT=3000 node .` to run the server.\n\nThe UI is at `/` and allows listing notes and reading and writing notes by ID.\nThere is also a to-do list sample running at `/todo.html`.\n\n## Design\n\nEntity/type approximates a database table and is implemented using Apple Notes\nfolders.\n\nThere is an encompassing folder for the application named after `appName.js`.\n\n## API\n\n- `GET type` - list the IDs of entities of the given type\n\n  The ID can be any string of characters except for a line break and a comma.\n\n- `GET type/id` - get the content of the entity of the given type by its ID\n\n  The return value is a JSON object literal with string key-value pairs.\n\n- `POST type/id` - set the content of the entity of the given type by its ID\n\n  The expected body is of the same format as the corresponding GET method.\n  There is no return value.\n\n- `DELETE type/id` - delete the note of the given type.\n\n  There is no return value.\n\n## Testing\n\nThe app uses Playwright for E2E testing.\nRun the tests using `npm test`.\nThe test runner will start the app server itself.\n\n## To-Do\n\n### See if the Playwright browser download could be cached for say a week\n\nWe want to refresh it every once in a while, but every test run seems too much.\nLet's see if I can use the GitHub Actions cache to do this.\n\n### Switch the macOS image to macOS 12 while it is latest\n\nI got help making the AppleScript work for macOS 13:\nhttps://github.com/actions/runner-images/issues/8214\n\nThis image is in beta though.\nI should find a way to do this in macOS 12 and only switch to macOS 13 once it\nit latest.\n\n### Consider splitting `POST` and `PUT` into different endpoints\n\nMaybe I should respect the semantics for `POST` being for creating new items and\n`PUT` being for updating existing items and erroring if the item doesn't exist.\n\nIn this scenario, `POST` would be a single-component path of just `POST /type`\nand would automatically assign a unique ID or it could optionally have a\ntwo-component path variant `POST /type/id` with suggested ID (based on say a\nfriendly name) which would be checked for uniqueness.\n\n`PUT` would always require the ID: `PUT /type/id`.\n\n### Add support for ID-less multi-deletion on `DELETE /type`\n\nThis will bring parity to ID-less multi-retrival at `GET /type?full`.\nIt will be useful for building file-system-like experiences on top of the notes.\nIt should be accompanied with a method for creating a folder (different from\nindirectly via `GET /type` or `GET /type?full` through `ensureTypeFolder`) so\nthat the folder CRUD actions can be carried out end to end over the API.\n\n### Add a new app with multi-select support to demo the multi-deletion feature\n\nI need to test this feature more as well, it seems kind of unreliable and I had\ntrouble putting together the AppleScript for it.\nIn some versions which I attempted to make slicker I would get seemingly racy\nerrors, sometimes it would delete the notes successfully, sometimes it would\nerror with unhelpful vague error messages.\nThe current version when passed a set of IDs sometimes succeeds but doesn't\nactually seem to delete the notes?\nI might need to craft better AppleScript or add checks after the command with\nretry logic maybe?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomashubelbauer%2Fapple-notes-database","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftomashubelbauer%2Fapple-notes-database","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftomashubelbauer%2Fapple-notes-database/lists"}