{"html_url": "https://github.com/simonw/datasette/pull/1130#issuecomment-861497548", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1130", "id": 861497548, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTQ5NzU0OA==", "user": {"value": 3243482, "label": "abdusco"}, "created_at": "2021-06-15T13:27:48Z", "updated_at": "2021-06-15T13:27:48Z", "author_association": "CONTRIBUTOR", "body": "There's a workaround: https://css-tricks.com/css-fix-for-100vh-in-mobile-webkit/\r\n\r\nand a future fix: https://css-tricks.com/safari-15-new-ui-theme-colors-and-a-css-tricks-cameo/", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 756876238, "label": "Fix footer not sticking to bottom in short pages"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/269#issuecomment-861103967", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/269", "id": 861103967, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTEwMzk2Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-15T01:34:10Z", "updated_at": "2021-06-15T01:34:10Z", "author_association": "OWNER", "body": "SQLite doesn't have the concept of a boolean column, so there's not much I can do here: https://www.sqlite.org/datatype3.html#boolean_datatype", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919250621, "label": "bool type not supported"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/266#issuecomment-861103684", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/266", "id": 861103684, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTEwMzY4NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-15T01:33:13Z", "updated_at": "2021-06-15T01:33:13Z", "author_association": "OWNER", "body": "Dupe of #37", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913135723, "label": "Add some types, enforce with mypy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1377#issuecomment-861089794", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1377", "id": 861089794, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTA4OTc5NA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-15T00:53:29Z", "updated_at": "2021-06-15T00:53:29Z", "author_association": "OWNER", "body": "Potential hook names:\r\n\r\n- `skip_csrf(scope, datasette)`\r\n- ... I can't think of any other ones I would tolerate to be honest", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920884085, "label": "Mechanism for plugins to exclude certain paths from CSRF checks"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1377#issuecomment-861087949", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1377", "id": 861087949, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTA4Nzk0OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-15T00:49:19Z", "updated_at": "2021-06-15T00:49:19Z", "author_association": "OWNER", "body": "The new `skip_if_scope` mechanism in `asgi-csrf` https://github.com/simonw/asgi-csrf/issues/20 is designed to help here.\r\n\r\nNow I need to design a plugin hook that allows plugins to have an opinion on whether a specific `scope` should have CSRF skipped.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920884085, "label": "Mechanism for plugins to exclude certain paths from CSRF checks"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/64#issuecomment-861087651", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/64", "id": 861087651, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTA4NzY1MQ==", "user": {"value": 231498, "label": "khimaros"}, "created_at": "2021-06-15T00:48:37Z", "updated_at": "2021-06-15T00:48:37Z", "author_association": "NONE", "body": "@simonw -- i've created an omega-query that fetched most of what was interesting to me for a single user.\r\n\r\nfound by poking around in the \"Explorer\" tab in https://docs.github.com/en/graphql/overview/explorer\r\n\r\nnote: pagination is still required via `first` and `last` but it seems to allow unlimited history.\r\n\r\n```\r\nquery MyQuery {\r\n __typename\r\n user(login: \"\") {\r\n id\r\n pinnedItems(first: 100) {\r\n edges {\r\n node\r\n }\r\n }\r\n pullRequests(first: 100) {\r\n nodes {\r\n body\r\n title\r\n state\r\n createdAt\r\n }\r\n }\r\n createdAt\r\n issues(first: 100) {\r\n pageInfo {\r\n endCursor\r\n startCursor\r\n }\r\n nodes {\r\n title\r\n url\r\n createdAt\r\n body\r\n }\r\n }\r\n issueComments(first: 100) {\r\n edges {\r\n node {\r\n id\r\n updatedAt\r\n url\r\n body\r\n }\r\n }\r\n }\r\n repositories(first: 100) {\r\n nodes {\r\n createdAt\r\n description\r\n parent {\r\n name\r\n }\r\n pinnedIssues(first: 100) {\r\n edges {\r\n node {\r\n id\r\n }\r\n }\r\n }\r\n pinnedDiscussions(first: 100) {\r\n edges {\r\n node {\r\n id\r\n }\r\n }\r\n }\r\n }\r\n }\r\n starredRepositories(first: 100) {\r\n edges {\r\n node {\r\n id\r\n }\r\n }\r\n }\r\n }\r\n}\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920636216, "label": "feature: support \"events\""}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/64#issuecomment-861042050", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/64", "id": 861042050, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTA0MjA1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-14T22:45:42Z", "updated_at": "2021-06-14T22:45:42Z", "author_association": "MEMBER", "body": "I'm definitely interested in supporting events in this tool - see #14.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920636216, "label": "feature: support \"events\""}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/64#issuecomment-861041597", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/64", "id": 861041597, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTA0MTU5Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-14T22:44:54Z", "updated_at": "2021-06-14T22:44:54Z", "author_association": "MEMBER", "body": "Have you found a way to access events in GraphQL? I can only see way to access a timeline of events for a single issue or a single pull request. See also https://github.community/t/get-event-equivalent-for-v4/13600/2", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920636216, "label": "feature: support \"events\""}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/64#issuecomment-861035862", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/64", "id": 861035862, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MTAzNTg2Mg==", "user": {"value": 231498, "label": "khimaros"}, "created_at": "2021-06-14T22:29:20Z", "updated_at": "2021-06-14T22:29:20Z", "author_association": "NONE", "body": "it looks like the v4 GraphQL API is the only way to get data beyond 90 days from GitHub.\r\n\r\nthis is significant change, but may be worth considering in the future.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920636216, "label": "feature: support \"events\""}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/github-to-sqlite/issues/64#issuecomment-860895838", "issue_url": "https://api.github.com/repos/dogsheep/github-to-sqlite/issues/64", "id": 860895838, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDg5NTgzOA==", "user": {"value": 231498, "label": "khimaros"}, "created_at": "2021-06-14T18:23:21Z", "updated_at": "2021-06-14T21:37:35Z", "author_association": "NONE", "body": "i have a basic working version at https://github.com/khimaros/github-to-sqlite\r\n\r\nthis can be tested with `github-to-sqlite events.db khimaros/events`\r\n\r\ncaveat: the GitHub API doesn't seem to provide a complete history of events.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 920636216, "label": "feature: support \"events\""}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1375#issuecomment-860548546", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1375", "id": 860548546, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDU0ODU0Ng==", "user": {"value": 4068, "label": "frafra"}, "created_at": "2021-06-14T09:41:59Z", "updated_at": "2021-06-14T09:41:59Z", "author_association": "NONE", "body": "> There is a feature for this at the moment, but it's a little bit hidden: you can use `?_json=col` to tell\r\n> Datasette that you would like a specific column to be exported as nested JSON: https://docs.datasette.io/en/stable/json_api.html#special-json-arguments\r\n\r\nThanks :)\r\n \r\n> I considered trying to make this automatic - so it detects columns that appear to contain valid JSON and outputs them as nested objects - but the problem with that is that it can lead to inconsistent results - you might hit the API and find that not every column contains valid JSON (compared to the previous day) resulting in the API retuning string instead of the expected dictionary and breaking your code.\r\n\r\nIf a developer is not sure if the JSON fields are valid, but then retrieves and parse them, it should handle errors too. Handling inconsistent data is necessary due to the nature of SQLite. A global or dataset option to render the data as they have been defined (JSON, boolean, etc.) when requesting JSON could allow the user to download a regular JSON from the browser without having to rely on APIs. I would guess someone could just make a custom template with an extra JSON-parsed download button otherwise :)", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919508498, "label": "JSON export dumps JSON fields as TEXT"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1376#issuecomment-860230663", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1376", "id": 860230663, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDIzMDY2Mw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-13T15:39:37Z", "updated_at": "2021-06-13T15:39:37Z", "author_association": "OWNER", "body": "Actually it looks like there is a PR open already that addresses this: #1296 ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919822817, "label": "Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1375#issuecomment-860230385", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1375", "id": 860230385, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDIzMDM4NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-13T15:37:49Z", "updated_at": "2021-06-13T15:37:49Z", "author_association": "OWNER", "body": "There is a feature for this at the moment, but it's a little bit hidden: you can use `?_json=col` to tell\r\nDatasette that you would like a specific column to be exported as nested JSON: https://docs.datasette.io/en/stable/json_api.html#special-json-arguments\r\n\r\nI considered trying to make this automatic - so it detects columns that appear to contain valid JSON and outputs them as nested objects - but the problem with that is that it can lead to inconsistent results - you might hit the API and find that not every column contains valid JSON (compared to the previous day) resulting in the API retuning string instead of the expected dictionary and breaking your code.", "reactions": "{\"total_count\": 1, \"+1\": 1, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919508498, "label": "JSON export dumps JSON fields as TEXT"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1373#issuecomment-857684605", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1373", "id": 857684605, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NzY4NDYwNQ==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-06-09T13:15:31Z", "updated_at": "2021-06-13T15:34:07Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\n> Merging [#1373](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (d117ba7) into [main](https://codecov.io/gh/simonw/datasette/commit/03418ee037057aa85204f5a3feb2066cbb6a9b3e?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (03418ee) will **increase** coverage by `7.65%`.\n> The diff coverage is `93.29%`.\n\n> :exclamation: Current head d117ba7 differs from pull request most recent head 51ff366. Consider uploading reports for the commit 51ff366 to get more accurate results\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1373/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n```diff\n@@ Coverage Diff @@\n## main #1373 +/- ##\n==========================================\n+ Coverage 84.02% 91.68% +7.65% \n==========================================\n Files 28 34 +6 \n Lines 3774 4340 +566 \n==========================================\n+ Hits 3171 3979 +808 \n+ Misses 603 361 -242 \n```\n\n\n| [Impacted Files](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | Coverage \u0394 | |\n|---|---|---|\n| [datasette/inspect.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2luc3BlY3QucHk=) | `36.11% <\u00f8> (\u00f8)` | |\n| [datasette/plugins.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3BsdWdpbnMucHk=) | `82.35% <\u00f8> (\u00f8)` | |\n| [datasette/publish/common.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3B1Ymxpc2gvY29tbW9uLnB5) | `94.73% <\u00f8> (\u00f8)` | |\n| [datasette/cli.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2NsaS5weQ==) | `76.33% <70.64%> (+1.19%)` | :arrow_up: |\n| [datasette/filters.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2ZpbHRlcnMucHk=) | `94.35% <77.77%> (\u00f8)` | |\n| [datasette/database.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2RhdGFiYXNlLnB5) | `92.93% <89.28%> (\u00f8)` | |\n| [datasette/utils/asgi.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL2FzZ2kucHk=) | `90.98% <92.00%> (-0.95%)` | :arrow_down: |\n| [datasette/publish/heroku.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3B1Ymxpc2gvaGVyb2t1LnB5) | `87.73% <94.44%> (+1.13%)` | :arrow_up: |\n| [datasette/app.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL2FwcC5weQ==) | `95.73% <94.52%> (-0.27%)` | :arrow_down: |\n| [datasette/utils/\\_\\_init\\_\\_.py](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison#diff-ZGF0YXNldHRlL3V0aWxzL19faW5pdF9fLnB5) | `94.36% <94.53%> (+0.55%)` | :arrow_up: |\n| ... and [29 more](https://codecov.io/gh/simonw/datasette/pull/1373/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) | |\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Last update [e797565...51ff366](https://codecov.io/gh/simonw/datasette/pull/1373?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 916183914, "label": "Update trustme requirement from <0.8,>=0.7 to >=0.7,<0.9"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1376#issuecomment-860229397", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1376", "id": 860229397, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDIyOTM5Nw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-13T15:31:02Z", "updated_at": "2021-06-13T15:31:02Z", "author_association": "OWNER", "body": "Alternative fix would be to update that section of the documentation - if the container upgrade proves tricky I can fall back on that.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919822817, "label": "Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1376#issuecomment-860229226", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1376", "id": 860229226, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDIyOTIyNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-13T15:29:45Z", "updated_at": "2021-06-13T15:29:45Z", "author_association": "OWNER", "body": "Oh good catch - this is a SQLite version issue.\r\n\r\nThe `fixtures.db` file used on https://latest.datasette.io/ includes a generated column (for testing purposes) which is a feature added in SQLite 3.31.0 on 2020-01-22.\r\n\r\nhttps://latest.datasette.io/-/versions\r\n\r\nBut... it looks like the packaged Datasette Docker container doesn't have that SQLite version!\r\n\r\nI should fix that. I'm renaming this issue.\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919822817, "label": "Official Datasette Docker image should use SQLite >= 3.31.0 (for generated columns)"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/271#issuecomment-860142489", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/271", "id": 860142489, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDE0MjQ4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-13T02:53:06Z", "updated_at": "2021-06-13T02:53:06Z", "author_association": "OWNER", "body": "Looks like this is the problem: https://github.com/simonw/sqlite-utils/blob/b0f9d1e494c9891ce407e27b0f5c6deeea361d30/sqlite_utils/db.py#L1724-L1742\r\n\r\nNote how `set_cols = [col for col in all_columns if col not in pks] ` can potentially return an empty list if ALL of the columns are primary keys - but the next line of code that assigns `sql2` continues regardless, when it should instead be skipped if there are no columns in `set_cols`.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919702451, "label": "table.upsert_all() fails if input has a single column that should be a primary key"}, "performed_via_github_app": null} {"html_url": "https://github.com/dogsheep/twitter-to-sqlite/issues/57#issuecomment-860063190", "issue_url": "https://api.github.com/repos/dogsheep/twitter-to-sqlite/issues/57", "id": 860063190, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDA2MzE5MA==", "user": {"value": 232237, "label": "stiles"}, "created_at": "2021-06-12T14:46:44Z", "updated_at": "2021-06-12T14:46:44Z", "author_association": "NONE", "body": "I'm having the same issue (same versions of python and twitter-to-sqlite). It's the `user-timeline` command. Other commands are working. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 907645813, "label": "Error: Use either --since or --since_id, not both"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1286#issuecomment-860047794", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1286", "id": 860047794, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDA0Nzc5NA==", "user": {"value": 4068, "label": "frafra"}, "created_at": "2021-06-12T12:36:15Z", "updated_at": "2021-06-12T12:36:15Z", "author_association": "NONE", "body": "@mroswell That is a very nice solution. I wonder if custom classes, like `col-columnName-value` could be automatically added to cells when facets on such column are enabled, to allow custom styling without having to modify templates or add custom JavaScript code.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 849220154, "label": "Better default display of arrays of items"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/269#issuecomment-860031217", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/269", "id": 860031217, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDAzMTIxNw==", "user": {"value": 4068, "label": "frafra"}, "created_at": "2021-06-12T10:01:53Z", "updated_at": "2021-06-12T10:01:53Z", "author_association": "NONE", "body": "`sqlite-utils transform` does not allow setting the column type to boolean:\r\n```\r\nError: Invalid value for '--type': 'bool' is not one of 'INTEGER', 'TEXT', 'FLOAT', 'BLOB'.\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919250621, "label": "bool type not supported"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/270#issuecomment-860031071", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/270", "id": 860031071, "node_id": "MDEyOklzc3VlQ29tbWVudDg2MDAzMTA3MQ==", "user": {"value": 4068, "label": "frafra"}, "created_at": "2021-06-12T10:00:24Z", "updated_at": "2021-06-12T10:00:24Z", "author_association": "NONE", "body": "Sure, I am sorry if my message hasn't been clear enough. I am also a new user :)\r\n\r\nAt the beginning, I just call `sqlite-utils insert \"$db\" \"$table\" \"$jsonfile\"` to create the database. sqlite-utils convert JSON values into `TEXT`, when it tries to determine the schema automatically. I then try to transform the table to set `JSON` as type:\r\n\r\n```\r\nsqlite-utils transform species.sqlite species --type criteria json\r\nUsage: sqlite-utils transform [OPTIONS] PATH TABLE\r\nTry 'sqlite-utils transform --help' for help.\r\n\r\nError: Invalid value for '--type': 'json' is not one of 'INTEGER', 'TEXT', 'FLOAT', 'BLOB'.\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919314806, "label": "Cannot set type JSON"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/270#issuecomment-859986489", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/270", "id": 859986489, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTk4NjQ4OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-12T02:47:12Z", "updated_at": "2021-06-12T02:47:12Z", "author_association": "OWNER", "body": "Can you expand on what you'd like to change here? The library and CLI tool already allow JSON data to be stored in columns:\r\n\r\n- https://sqlite-utils.datasette.io/en/stable/cli.html#nested-json-values\r\n- https://sqlite-utils.datasette.io/en/stable/python-api.html#storing-json", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919314806, "label": "Cannot set type JSON"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/269#issuecomment-859940977", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/269", "id": 859940977, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTk0MDk3Nw==", "user": {"value": 4068, "label": "frafra"}, "created_at": "2021-06-11T22:33:08Z", "updated_at": "2021-06-11T22:33:08Z", "author_association": "NONE", "body": "`true` and `false` json values are cast to integer, which is not optimal.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919250621, "label": "bool type not supported"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/268#issuecomment-859898736", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/268", "id": 859898736, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTg5ODczNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-11T20:37:44Z", "updated_at": "2021-06-11T20:37:44Z", "author_association": "OWNER", "body": "From the prototype:\r\n```\r\n% sqlite-utils schema 24ways.db\r\nCREATE TABLE [articles] (\r\n [title] TEXT ,\r\n [contents] TEXT ,\r\n [year] TEXT ,\r\n [author] TEXT ,\r\n [author_slug] TEXT ,\r\n [published] TEXT ,\r\n [url] TEXT ,\r\n [topic] TEXT \r\n );\r\nCREATE VIRTUAL TABLE \"articles_fts\" USING FTS5 (\r\n title, author, contents,\r\n content=\"articles\"\r\n );\r\nCREATE TABLE 'articles_fts_data'(id INTEGER PRIMARY KEY, block BLOB);\r\nCREATE TABLE 'articles_fts_idx'(segid, term, pgno, PRIMARY KEY(segid, term)) WITHOUT ROWID;\r\nCREATE TABLE 'articles_fts_docsize'(id INTEGER PRIMARY KEY, sz BLOB);\r\nCREATE TABLE 'articles_fts_config'(k PRIMARY KEY, v) WITHOUT ROWID;\r\n% sqlite-utils schema 24ways.db | sqlite3 /tmp/boo.db\r\nError: near line 15: table 'articles_fts_data' already exists\r\nError: near line 16: table 'articles_fts_idx' already exists\r\nError: near line 17: table 'articles_fts_docsize' already exists\r\nError: near line 18: table 'articles_fts_config' already exists\r\n```\r\nThe problem here is that the `CREATE VIRTUAL TABLE \"articles_fts\"...` line causes those next four tables to be created - but that means that piping the output of this command into `sqlite3` in order to re-create those tables throws errors.\r\n\r\nI don't think this matters. I see this tool as more for introspection than for recreating table structures.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919181559, "label": "db.schema property and sqlite-utils schema command"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/268#issuecomment-859895540", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/268", "id": 859895540, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTg5NTU0MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-11T20:30:34Z", "updated_at": "2021-06-11T20:30:34Z", "author_association": "OWNER", "body": "You can currently see the `sql` on the CLI using:\r\n\r\n % sqlite-utils rows fixtures.db sqlite_master -c name -c sql\r\n name sql\r\n -------------------------------------------------------------- ----------------------------------------------------------------------------------------------------------------------------------------------------------------\r\n simple_primary_key CREATE TABLE simple_primary_key (\r\n id varchar(30) primary key,\r\n content text\r\n )\r\n sqlite_autoindex_simple_primary_key_1\r\n primary_key_multiple_columns CREATE TABLE primary_key_multiple_columns (\r\n id varchar(30) primary key,\r\n content text,\r\n content2 text\r\n )\r\n sqlite_autoindex_primary_key_multiple_columns_1\r\n primary_key_multiple_columns_explicit_label CREATE TABLE primary_key_multiple_columns_explicit_label (\r\n id varchar(30) primary key,\r\n content text,\r\n content2 text\r\n )\r\n sqlite_autoindex_primary_key_multiple_columns_explicit_label_1\r\n compound_primary_key CREATE TABLE compound_primary_key (\r\n pk1 varchar(30),\r\n pk2 varchar(30),\r\n content text,\r\n PRIMARY KEY (pk1, pk2)\r\n )\r\n sqlite_autoindex_compound_primary_key_1\r\n compound_three_primary_keys CREATE TABLE compound_three_primary_keys (\r\n pk1 varchar(30),\r\n pk2 varchar(30),\r\n pk3 varchar(30),\r\n content text,\r\n PRIMARY KEY (pk1, pk2, pk3)\r\n )\r\n sqlite_autoindex_compound_three_primary_keys_1\r\n foreign_key_references CREATE TABLE foreign_key_references (\r\n pk varchar(30) primary key,\r\n foreign_key_with_label varchar(30),\r\n foreign_key_with_no_label varchar(30),\r\n FOREIGN KEY (foreign_key_with_label) REFERENCES simple_primary_key(id),\r\n FOREIGN KEY (foreign_key_with_no_label) REFERENCES primary_key_multiple_columns(id)\r\n )\r\n sqlite_autoindex_foreign_key_references_1\r\n sortable CREATE TABLE sortable (\r\n pk1 varchar(30),\r\n pk2 varchar(30),\r\n content text,\r\n sortable integer,\r\n sortable_with_nulls real,\r\n sortable_with_nulls_2 real,\r\n text text,\r\n PRIMARY KEY (pk1, pk2)\r\n )\r\n sqlite_autoindex_sortable_1\r\n no_primary_key CREATE TABLE no_primary_key (\r\n content text,\r\n a text,\r\n b text,\r\n c text\r\n )\r\n 123_starts_with_digits CREATE TABLE [123_starts_with_digits] (\r\n content text\r\n )\r\n paginated_view CREATE VIEW paginated_view AS\r\n SELECT\r\n content,\r\n '- ' || content || ' -' AS content_extra\r\n FROM no_primary_key\r\n Table With Space In Name CREATE TABLE \"Table With Space In Name\" (\r\n pk varchar(30) primary key,\r\n content text\r\n )\r\n sqlite_autoindex_Table With Space In Name_1\r\n table/with/slashes.csv CREATE TABLE \"table/with/slashes.csv\" (\r\n pk varchar(30) primary key,\r\n content text\r\n )\r\n sqlite_autoindex_table/with/slashes.csv_1\r\n complex_foreign_keys CREATE TABLE \"complex_foreign_keys\" (\r\n pk varchar(30) primary key,\r\n f1 text,\r\n f2 text,\r\n f3 text,\r\n FOREIGN KEY (\"f1\") REFERENCES [simple_primary_key](id),\r\n FOREIGN KEY (\"f2\") REFERENCES [simple_primary_key](id),\r\n FOREIGN KEY (\"f3\") REFERENCES [simple_primary_key](id)\r\n )\r\n sqlite_autoindex_complex_foreign_keys_1\r\n custom_foreign_key_label CREATE TABLE \"custom_foreign_key_label\" (\r\n pk varchar(30) primary key,\r\n foreign_key_with_custom_label text,\r\n FOREIGN KEY (\"foreign_key_with_custom_label\") REFERENCES [primary_key_multiple_columns_explicit_label](id)\r\n )\r\n sqlite_autoindex_custom_foreign_key_label_1\r\n units CREATE TABLE units (\r\n pk integer primary key,\r\n distance int,\r\n frequency int\r\n )\r\n searchable CREATE TABLE searchable (\r\n pk integer primary key,\r\n text1 text,\r\n text2 text,\r\n [name with . and spaces] text\r\n )\r\n searchable_fts CREATE VIRTUAL TABLE \"searchable_fts\"\r\n USING FTS3 (text1, text2, [name with . and spaces], content=\"searchable\")\r\n searchable_fts_content CREATE TABLE 'searchable_fts_content'(docid INTEGER PRIMARY KEY, 'c0text1', 'c1text2', 'c2name with . and spaces', 'c3content')\r\n searchable_fts_segments CREATE TABLE 'searchable_fts_segments'(blockid INTEGER PRIMARY KEY, block BLOB)\r\n searchable_fts_segdir CREATE TABLE 'searchable_fts_segdir'(level INTEGER,idx INTEGER,start_block INTEGER,leaves_end_block INTEGER,end_block INTEGER,root BLOB,PRIMARY KEY(level, idx))\r\n sqlite_autoindex_searchable_fts_segdir_1\r\n select CREATE TABLE [select] (\r\n [group] text,\r\n [having] text,\r\n [and] text\r\n )\r\n facet_cities CREATE TABLE facet_cities (\r\n id integer primary key,\r\n name text\r\n )\r\n simple_view CREATE VIEW simple_view AS\r\n SELECT content, upper(content) AS upper_content FROM simple_primary_key\r\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919181559, "label": "db.schema property and sqlite-utils schema command"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/268#issuecomment-859894105", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/268", "id": 859894105, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTg5NDEwNQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-11T20:28:52Z", "updated_at": "2021-06-11T20:28:52Z", "author_association": "OWNER", "body": "Out of interest, here are the rows from that table where `sql` is `null`: https://latest.datasette.io/fixtures?sql=select%0D%0A++*%0D%0Afrom%0D%0A++sqlite_master%0D%0Awhere%0D%0A++sql+is+null\r\n\r\n```csv\r\ntype,name,tbl_name,rootpage,sql\r\nindex,sqlite_autoindex_simple_primary_key_1,simple_primary_key,3,\r\nindex,sqlite_autoindex_primary_key_multiple_columns_1,primary_key_multiple_columns,5,\r\nindex,sqlite_autoindex_primary_key_multiple_columns_explicit_label_1,primary_key_multiple_columns_explicit_label,7,\r\nindex,sqlite_autoindex_compound_primary_key_1,compound_primary_key,9,\r\nindex,sqlite_autoindex_compound_three_primary_keys_1,compound_three_primary_keys,11,\r\nindex,sqlite_autoindex_foreign_key_references_1,foreign_key_references,14,\r\nindex,sqlite_autoindex_sortable_1,sortable,16,\r\nindex,sqlite_autoindex_Table With Space In Name_1,Table With Space In Name,20,\r\nindex,sqlite_autoindex_table/with/slashes.csv_1,table/with/slashes.csv,22,\r\nindex,sqlite_autoindex_complex_foreign_keys_1,complex_foreign_keys,24,\r\nindex,sqlite_autoindex_custom_foreign_key_label_1,custom_foreign_key_label,26,\r\nindex,sqlite_autoindex_tags_1,tags,31,\r\nindex,sqlite_autoindex_searchable_tags_1,searchable_tags,34,\r\nindex,sqlite_autoindex_searchable_fts_segdir_1,searchable_fts_segdir,37,\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919181559, "label": "db.schema property and sqlite-utils schema command"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/268#issuecomment-859888469", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/268", "id": 859888469, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTg4ODQ2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-11T20:26:20Z", "updated_at": "2021-06-11T20:26:20Z", "author_association": "OWNER", "body": "`sqlite-utils schema data.db` could output the same thing to the console.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 919181559, "label": "db.schema property and sqlite-utils schema command"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1374#issuecomment-859572791", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1374", "id": 859572791, "node_id": "MDEyOklzc3VlQ29tbWVudDg1OTU3Mjc5MQ==", "user": {"value": 22429695, "label": "codecov[bot]"}, "created_at": "2021-06-11T13:12:58Z", "updated_at": "2021-06-11T13:12:58Z", "author_association": "NONE", "body": "# [Codecov](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) Report\n> Merging [#1374](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (0ef0dd5) into [main](https://codecov.io/gh/simonw/datasette/commit/cd7678fde65319d7b6955ce9f4678ba4b9e64b66?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison) (cd7678f) will **not change** coverage.\n> The diff coverage is `n/a`.\n\n[![Impacted file tree graph](https://codecov.io/gh/simonw/datasette/pull/1374/graphs/tree.svg?width=650&height=150&src=pr&token=eSahVY7kw1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n\n```diff\n@@ Coverage Diff @@\n## main #1374 +/- ##\n=======================================\n Coverage 91.68% 91.68% \n=======================================\n Files 34 34 \n Lines 4340 4340 \n=======================================\n Hits 3979 3979 \n Misses 361 361 \n```\n\n\n\n------\n\n[Continue to review full report at Codecov](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison)\n> `\u0394 = absolute (impact)`, `\u00f8 = not affected`, `? = missing data`\n> Powered by [Codecov](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Last update [cd7678f...0ef0dd5](https://codecov.io/gh/simonw/datasette/pull/1374?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Simon+Willison).\n", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 918730335, "label": "Bump black from 21.5b2 to 21.6b0"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/858#issuecomment-858831895", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/858", "id": 858831895, "node_id": "MDEyOklzc3VlQ29tbWVudDg1ODgzMTg5NQ==", "user": {"value": 56045588, "label": "rachelmarconi"}, "created_at": "2021-06-10T17:44:09Z", "updated_at": "2021-06-10T17:44:09Z", "author_association": "NONE", "body": "any fixes for that recursive issue with temp file? I get it using both heroku and cloudrun, although it seems to still publish and deploy fine", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 642388564, "label": "publish heroku does not work on Windows 10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/858#issuecomment-858813675", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/858", "id": 858813675, "node_id": "MDEyOklzc3VlQ29tbWVudDg1ODgxMzY3NQ==", "user": {"value": 56045588, "label": "rachelmarconi"}, "created_at": "2021-06-10T17:27:46Z", "updated_at": "2021-06-10T17:27:46Z", "author_association": "NONE", "body": "shell=True is added to line 56 (I guess it used to be 54) of heroku.py as detailed in the original issue. (for posterity)", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 642388564, "label": "publish heroku does not work on Windows 10"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1371#issuecomment-858099514", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1371", "id": 858099514, "node_id": "MDEyOklzc3VlQ29tbWVudDg1ODA5OTUxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-09T21:03:49Z", "updated_at": "2021-06-09T21:03:49Z", "author_association": "OWNER", "body": "I'll release these as an alpha straight away - it makes sense to have plugin hook changes available for people to test as alpha dependencies ASAP.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 915455228, "label": "Menu plugin hooks should include the request"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1370#issuecomment-857298526", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1370", "id": 857298526, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NzI5ODUyNg==", "user": {"value": 25778, "label": "eyeseast"}, "created_at": "2021-06-09T01:18:59Z", "updated_at": "2021-06-09T01:18:59Z", "author_association": "CONTRIBUTOR", "body": "I'm happy to grab some or all of these in this PR, if you want. ", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 914130834, "label": "Ensure db.path is a string before trying to insert into internal database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1370#issuecomment-857139881", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1370", "id": 857139881, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NzEzOTg4MQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-08T20:58:41Z", "updated_at": "2021-06-08T20:58:41Z", "author_association": "OWNER", "body": "We can remove a bunch of unnecessary `str(path)` calls too - this search finds a bunch of possible candidates: https://ripgrep.datasette.io/-/ripgrep?pattern=str%5C%28.*%28db%7Cpath%29&glob=datasette%2F**%2F*.py", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 914130834, "label": "Ensure db.path is a string before trying to insert into internal database"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/pull/1368#issuecomment-856182547", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1368", "id": 856182547, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjE4MjU0Nw==", "user": {"value": 2670795, "label": "brandonrobertz"}, "created_at": "2021-06-07T18:59:47Z", "updated_at": "2021-06-07T23:04:25Z", "author_association": "CONTRIBUTOR", "body": "Note that if we went with a \"update_metadata\" hook, the hook signature would look something like this (it would return nothing):\r\n\r\n```\r\nupdate_metadata(\r\n datasette=self, metadata=metadata, key=key, database=database, table=table,\r\n fallback=fallback\r\n)\r\n```\r\n\r\nThe Datasette function `_metadata_recursive_update(self, orig, updated)` would disappear into the plugins. Doing this, though, we'd lose the easy ability to make the local metadata.yaml immutable (since we'd no longer have the recursive update).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913865304, "label": "DRAFT: A new plugin hook for dynamic metadata"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/266#issuecomment-856231119", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/266", "id": 856231119, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjIzMTExOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T20:26:05Z", "updated_at": "2021-06-07T20:26:05Z", "author_association": "OWNER", "body": "https://github.com/python/cpython/blob/2ab27c4af4ddf7528e1375e77c787c7fbb09b5e6/Lib/typing.py#L2173-L2195\r\n\r\nIn Python 3.6 or higher can do this:\r\n\r\n```python\r\nclass Employee(NamedTuple):\r\n name: str\r\n id: int\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913135723, "label": "Add some types, enforce with mypy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1365#issuecomment-856212136", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1365", "id": 856212136, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjIxMjEzNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T19:54:04Z", "updated_at": "2021-06-07T19:54:04Z", "author_association": "OWNER", "body": "I've hit this one too. I agree, fixing this in Datasette itself is better than fixing it in the tests across multiple other projects.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913017577, "label": "pathlib.Path breaks internal schema"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1369#issuecomment-856208637", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1369", "id": 856208637, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjIwODYzNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T19:47:23Z", "updated_at": "2021-06-07T19:47:23Z", "author_association": "OWNER", "body": "No point in showing the IDs twice if the blue label doesn't differ from the gray ID", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913900374, "label": "Don't show foreign key IDs twice if no label"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1367#issuecomment-856160770", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1367", "id": 856160770, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjE2MDc3MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T18:22:33Z", "updated_at": "2021-06-07T18:22:33Z", "author_association": "OWNER", "body": "Here's why: https://github.com/simonw/datasette/blob/03ec71193b9545536898a4bc7493274fec48bdd7/datasette/static/app.css#L455-L458", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913823889, "label": "Navigation menu display bug"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1366#issuecomment-856147969", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1366", "id": 856147969, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjE0Nzk2OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T18:03:03Z", "updated_at": "2021-06-07T18:03:03Z", "author_association": "OWNER", "body": "Here's an example of a test that uses it. It's necessary because sometimes fixtures that create temporary directories break in unexpected ways:\r\n\r\nhttps://github.com/simonw/datasette/blob/0a7621f96f8ad14da17e7172e8a7bce24ef78966/tests/test_plugins.py#L658-L666", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913809802, "label": "Get rid of this `restore_working_directory` hack entirely"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1366#issuecomment-856147450", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1366", "id": 856147450, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NjE0NzQ1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T18:02:13Z", "updated_at": "2021-06-07T18:02:13Z", "author_association": "OWNER", "body": "The hack in question is this fixture, which I've been using in an ad-hoc manner to work around errors while running the tests: https://github.com/simonw/datasette/blob/030deb4b25cda842ff7129ab7c18550c44dd8379/tests/conftest.py#L62-L75\r\n\r\nI don't understand the underlying issue well enough to know how to get rid of it.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913809802, "label": "Get rid of this `restore_working_directory` hack entirely"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/sqlite-utils/issues/266#issuecomment-855611939", "issue_url": "https://api.github.com/repos/simonw/sqlite-utils/issues/266", "id": 855611939, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTYxMTkzOQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-07T06:07:41Z", "updated_at": "2021-06-07T06:07:41Z", "author_association": "OWNER", "body": "Looks like this is the way to do this:\r\n```python\r\nPoint = typing.NamedTuple(\r\n \"Point\", [('x', int), ('y', int)]\r\n)\r\n```", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 913135723, "label": "Add some types, enforce with mypy"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855430317", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855430317, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQzMDMxNw==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T17:07:48Z", "updated_at": "2021-06-06T17:07:48Z", "author_association": "OWNER", "body": "I guess I can offer a `disable_csp` setting so that people with complex custom templates aren't completely blocked from using them with Datasette, but maybe it would be better not to offer that? Or to offer it as a `datasette-insecure-csp` plugin instead?\r\n\r\nI like the idea of very actively encouraging CSP across all Datasette projects, but I'm nervous about making the software unusable for certain edge cases.\r\n\r\nMaybe require CSP and wait for someone to complain?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855429111", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855429111, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyOTExMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:59:05Z", "updated_at": "2021-06-06T17:00:15Z", "author_association": "OWNER", "body": "Twitter conversation: https://twitter.com/simonw/status/1401565566045806594\r\n\r\n@dracos provided some really useful code examples there:\r\n\r\n> We generate it here: https://github.com/mysociety/fixmystreet/blob/e9fec4e567e7148ed128816e5770c2963be51af6/perllib/FixMyStreet/Cobrand/Default.pm#L89-L90\r\nAnd use it e.g. https://github.com/mysociety/fixmystreet/blob/ba6788cd25d8f471a4e3308403607627b4d2f4f6/templates/web/base/common_header_tags.html or https://github.com/mysociety/fixmystreet/blob/cb4f2b96364d151988b5c664888468b25cc62240/templates/web/fixmystreet.com/header/css.html", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855428601", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855428601, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyODYwMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:55:33Z", "updated_at": "2021-06-06T16:55:33Z", "author_association": "OWNER", "body": "> No, because Vary header is about _request_ headers that cause the response to vary, not response headers.\r\n\r\nHah, of course! Thanks for the correction. So the nonce mechanism would actually be pretty great here, especially for the `extra_body_script()` hook.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855428296", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855428296, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyODI5Ng==", "user": {"value": 154364, "label": "dracos"}, "created_at": "2021-06-06T16:53:20Z", "updated_at": "2021-06-06T16:53:20Z", "author_association": "NONE", "body": "> Presumably this would also require adding Content-Security-Policy to the Vary header though, which will have a nasty effect on Cloudflare and Fastly and such like.\r\n\r\nNo, because Vary header is about *request* headers that cause the response to vary, not response headers.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855427396", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855427396, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyNzM5Ng==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:46:17Z", "updated_at": "2021-06-06T16:46:17Z", "author_association": "OWNER", "body": "Mind you, since that plugin hook looks like this:\r\n\r\n```python\r\n@hookimpl\r\ndef extra_body_script():\r\n return {\r\n \"module\": True,\r\n \"script\": \"console.log('Your JavaScript goes here...')\"\r\n }\r\n```\r\nHaving it calculate a sha256 hash wouldn't be difficult.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855426750", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855426750, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyNjc1MA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:41:30Z", "updated_at": "2021-06-06T16:44:49Z", "author_association": "OWNER", "body": "This is from the current `base.html` template: https://github.com/simonw/datasette/blob/030deb4b25cda842ff7129ab7c18550c44dd8379/datasette/templates/base.html#L62-L66\r\n\r\nWhich includes this: https://github.com/simonw/datasette/blob/030deb4b25cda842ff7129ab7c18550c44dd8379/datasette/templates/_close_open_menus.html#L1-L16\r\n\r\nThe `body_scripts` bit is for this `extra_body_script` plugin hook, which is the thing that will be the most affected by implementing CSP: https://docs.datasette.io/en/stable/plugin_hooks.html#extra-body-script-template-database-table-columns-view-name-request-datasette", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855426516", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855426516, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyNjUxNg==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:39:34Z", "updated_at": "2021-06-06T16:39:34Z", "author_association": "OWNER", "body": "The reason Datasette uses small inline scripts right now is to avoid the overhead of an extra HTTP request for a JavaScript file - but these are both inherently cachable and perform much better under HTTP/2 so that's likely a false optimization.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855426314", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855426314, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQyNjMxNA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T16:38:04Z", "updated_at": "2021-06-06T16:38:04Z", "author_association": "OWNER", "body": "The other option for inline scripts is the CSP nonce:\r\n\r\n Content-Security-Policy: script-src 'nonce-2726c7f26c'\r\n\r\nThen:\r\n\r\n \r\n\r\nSince an attacker can't guess what the nonce will be it prevents them from injecting their own script block - this seems easier to make available to plugins than a full hashing mechanism, just make `{{ csp_nonce() }}` available to the template.\r\n\r\nThat template function can then be smart enough to set a flag which Datasette uses to decide if the `script-src 'nonce-2726c7f26c'` policy should be sent or not.\r\n\r\nPresumably this would also require adding `Content-Security-Policy` to the `Vary` header though, which will have a nasty effect on Cloudflare and Fastly and such like.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855418899", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855418899, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQxODg5OQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T15:42:55Z", "updated_at": "2021-06-06T15:42:55Z", "author_association": "OWNER", "body": "Another consideration: testing that this works correctly could require adoption of a real browser test environment (probably Cypress or maybe Playwright) to execute tests that will fail if CSP is violated.", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855418698", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855418698, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQxODY5OA==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T15:41:24Z", "updated_at": "2021-06-06T15:41:24Z", "author_association": "OWNER", "body": "I think the best way to answer these questions is with some prototyping - of both Datasette and some of the existing JavaScript plugins.\r\n\r\nI can start with a `datasette-experimental-csp` plugin that sets the header (and could even run an optional report URI mechanism).", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855418401", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855418401, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQxODQwMQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T15:39:38Z", "updated_at": "2021-06-06T15:39:38Z", "author_association": "OWNER", "body": "The security benefit of forcing all JavaScript plugins to be written as CSP-friendly external scripts is very compelling though.\r\n\r\nOther plugin-heavy ecosystems such as WordPress have suffered greatly from insecurely written plugins - could this be a huge security win for the Datasette ecosystem generally?", "reactions": "{\"total_count\": 0, \"+1\": 0, \"-1\": 0, \"laugh\": 0, \"hooray\": 0, \"confused\": 0, \"heart\": 0, \"rocket\": 0, \"eyes\": 0}", "issue": {"value": 912864936, "label": "Consider using CSP to protect against future XSS"}, "performed_via_github_app": null} {"html_url": "https://github.com/simonw/datasette/issues/1362#issuecomment-855418065", "issue_url": "https://api.github.com/repos/simonw/datasette/issues/1362", "id": 855418065, "node_id": "MDEyOklzc3VlQ29tbWVudDg1NTQxODA2NQ==", "user": {"value": 9599, "label": "simonw"}, "created_at": "2021-06-06T15:37:11Z", "updated_at": "2021-06-06T15:37:11Z", "author_association": "OWNER", "body": "The easiest way to apply CSP is to remove all inline `