mirror of
https://github.com/simonw/datasette.git
synced 2026-07-13 02:54:44 +02:00
Compare commits
8 commits
main
...
asg017/cod
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
174099b707 | ||
|
|
cc1a24fb4f | ||
|
|
49f1660dcd | ||
|
|
b9716d4278 | ||
|
|
7e555b01f6 | ||
|
|
d12f0d2c59 | ||
|
|
28d811320b | ||
|
|
79f6ac3f47 |
21 changed files with 794 additions and 561 deletions
|
|
@ -85,6 +85,7 @@ from .views.special import (
|
|||
JumpView,
|
||||
InstanceSchemaView,
|
||||
DatabaseSchemaView,
|
||||
DatabaseEditorSchemaView,
|
||||
TableSchemaView,
|
||||
)
|
||||
from .views.table import (
|
||||
|
|
@ -2716,6 +2717,10 @@ class Datasette:
|
|||
DatabaseSchemaView.as_view(self),
|
||||
r"/(?P<database>[^\/\.]+)/-/schema(\.(?P<format>json|md))?$",
|
||||
)
|
||||
add_route(
|
||||
DatabaseEditorSchemaView.as_view(self),
|
||||
r"/(?P<database>[^\/\.]+)/-/editor-schema\.json$",
|
||||
)
|
||||
add_route(
|
||||
QueryParametersView.as_view(self),
|
||||
r"/(?P<database>[^\/\.]+)/-/query/parameters$",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
1
datasette/static/cm-editor.bundle.js
Normal file
1
datasette/static/cm-editor.bundle.js
Normal file
File diff suppressed because one or more lines are too long
|
|
@ -1,4 +1,5 @@
|
|||
import { EditorView, basicSetup } from "codemirror";
|
||||
import { Compartment } from "@codemirror/state";
|
||||
import { keymap } from "@codemirror/view";
|
||||
import { sql, SQLDialect } from "@codemirror/lang-sql";
|
||||
|
||||
|
|
@ -14,12 +15,25 @@ const SQLite = SQLDialect.define({
|
|||
operatorChars: "*+-%<>!=&|/~",
|
||||
identifierQuotes: '`"',
|
||||
specialVar: "@:?$",
|
||||
caseInsensitiveIdentifiers: true,
|
||||
});
|
||||
|
||||
// Builds the sql() extension from a {schema, defaultTable, defaultSchema} conf object
|
||||
function sqlExtension(conf) {
|
||||
return sql({
|
||||
dialect: SQLite,
|
||||
schema: conf.schema,
|
||||
defaultTable: conf.defaultTable,
|
||||
defaultSchema: conf.defaultSchema,
|
||||
});
|
||||
}
|
||||
|
||||
// Utility function from https://codemirror.net/docs/migration/
|
||||
export function editorFromTextArea(textarea, conf = {}) {
|
||||
// This could also be configured with a set of tables and columns for better autocomplete:
|
||||
// https://github.com/codemirror/lang-sql#user-content-sqlconfig.tables
|
||||
// Wraps the sql() extension so it can be swapped out later via view.updateSchema()
|
||||
// https://codemirror.net/examples/config/#dynamic-configuration
|
||||
let sqlCompartment = new Compartment();
|
||||
|
||||
let view = new EditorView({
|
||||
doc: textarea.value,
|
||||
extensions: [
|
||||
|
|
@ -45,16 +59,17 @@ export function editorFromTextArea(textarea, conf = {}) {
|
|||
// Meta-Enter from running
|
||||
basicSetup,
|
||||
EditorView.lineWrapping,
|
||||
sql({
|
||||
dialect: SQLite,
|
||||
schema: conf.schema,
|
||||
tables: conf.tables,
|
||||
defaultTableName: conf.defaultTableName,
|
||||
defaultSchemaName: conf.defaultSchemaName,
|
||||
}),
|
||||
sqlCompartment.of(sqlExtension(conf)),
|
||||
],
|
||||
});
|
||||
|
||||
// Allows callers (and plugins) to update the schema/defaultTable/defaultSchema
|
||||
// used for autocomplete after the editor has already been created.
|
||||
view.updateSchema = (conf2) =>
|
||||
view.dispatch({
|
||||
effects: sqlCompartment.reconfigure(sqlExtension(conf2)),
|
||||
});
|
||||
|
||||
// Idea taken from https://discuss.codemirror.net/t/resizing-codemirror-6/3265.
|
||||
// Using CSS resize: both and scheduling a measurement when the element changes.
|
||||
let editorDOM = view.contentDOM.closest(".cm-editor");
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
<script src="{{ static('sql-formatter-2.3.3.min.js') }}" defer></script>
|
||||
<script src="{{ static('cm-editor-6.0.1.bundle.js') }}"></script>
|
||||
<script src="{{ static('cm-editor.bundle.js') }}"></script>
|
||||
<style>
|
||||
.cm-editor {
|
||||
resize: both;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,9 @@
|
|||
if (sqlInput) {
|
||||
var editor = (window.editor = cm.editorFromTextArea(sqlInput, {
|
||||
schema,
|
||||
{% if default_table is defined and default_table %}
|
||||
defaultTable: {{ default_table|tojson }},
|
||||
{% endif %}
|
||||
}));
|
||||
if (sqlFormat) {
|
||||
sqlFormat.addEventListener("click", (ev) => {
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@
|
|||
{% endif %}
|
||||
|
||||
{% if query.sql and allow_execute_sql %}
|
||||
<p><a class="not-underlined" title="{{ query.sql }}" href="{{ urls.database(database) }}?{{ {'sql': query.sql}|urlencode|safe }}{% if query.params %}&{{ query.params|urlencode|safe }}{% endif %}">✎ <span class="underlined">View and edit SQL</span></a></p>
|
||||
<p><a class="not-underlined" title="{{ query.sql }}" href="{{ urls.database(database) }}?{{ {'sql': query.sql, '_table': table}|urlencode|safe }}{% if query.params %}&{{ query.params|urlencode|safe }}{% endif %}">✎ <span class="underlined">View and edit SQL</span></a></p>
|
||||
{% endif %}
|
||||
|
||||
<p class="export-links">This data as {% for name, url in renderers.items() %}<a href="{{ url }}">{{ name }}</a>{{ ", " if not loop.last }}{% endfor %}{% if display_rows %}, <a href="{{ url_csv }}">CSV</a> (<a href="#export">advanced</a>){% endif %}</p>
|
||||
|
|
|
|||
|
|
@ -36,7 +36,10 @@ from datasette.utils.asgi import AsgiFileDownload, NotFound, Response, Forbidden
|
|||
from datasette.plugins import pm
|
||||
|
||||
from .base import DatasetteError, View, stream_csv
|
||||
from .query_helpers import _ensure_stored_query_execution_permissions, _table_columns
|
||||
from .query_helpers import (
|
||||
_ensure_stored_query_execution_permissions,
|
||||
_editor_schema,
|
||||
)
|
||||
from .table_extras import (
|
||||
QueryExtraContext,
|
||||
resolve_query_extras,
|
||||
|
|
@ -201,7 +204,7 @@ class DatabaseView(View):
|
|||
"queries_count": queries_count,
|
||||
"allow_execute_sql": allow_execute_sql,
|
||||
"table_columns": (
|
||||
await _table_columns(datasette, database) if allow_execute_sql else {}
|
||||
await _editor_schema(datasette, database) if allow_execute_sql else {}
|
||||
),
|
||||
"metadata": await datasette.get_database_metadata(database),
|
||||
}
|
||||
|
|
@ -242,7 +245,7 @@ class DatabaseView(View):
|
|||
queries_count=queries_count,
|
||||
allow_execute_sql=allow_execute_sql,
|
||||
table_columns=(
|
||||
await _table_columns(datasette, database)
|
||||
await _editor_schema(datasette, database)
|
||||
if allow_execute_sql
|
||||
else {}
|
||||
),
|
||||
|
|
@ -454,6 +457,11 @@ class QueryContext(Context):
|
|||
"help": "Dictionary mapping table names to lists of column names, used to power SQL autocomplete."
|
||||
}
|
||||
)
|
||||
default_table: str = field(
|
||||
metadata={
|
||||
"help": "Name of the focal table for this query, if any - set when the query page was reached from a table-scoped context (such as the table page's 'View and edit SQL' link) so the SQL editor can complete that table's columns unprefixed. ``None`` otherwise, including for stored/canned queries."
|
||||
}
|
||||
)
|
||||
alternate_url_json: str = field(
|
||||
metadata={"help": "URL for alternate JSON version of this page"}
|
||||
)
|
||||
|
|
@ -713,6 +721,15 @@ class QueryView(View):
|
|||
# Create lookup dict for quick access
|
||||
allowed_dict = {r.child: r for r in allowed_tables_page.resources}
|
||||
|
||||
# If the request carries a ?_table= pointing at a real (visible) table
|
||||
# or view in this database, treat this as a table-scoped query - e.g.
|
||||
# arriving here via the "View and edit SQL" link on a table page - so
|
||||
# the SQL editor can offer that table's columns unprefixed. Anything
|
||||
# else (including stored/canned queries, which may reference more
|
||||
# than one table) leaves this as None.
|
||||
requested_table = request.args.get("_table")
|
||||
default_table = requested_table if requested_table in allowed_dict else None
|
||||
|
||||
# Are we a stored query?
|
||||
stored_query = None
|
||||
stored_query_write = False
|
||||
|
|
@ -1094,10 +1111,11 @@ class QueryView(View):
|
|||
datasette, database, request, rows, columns
|
||||
),
|
||||
table_columns=(
|
||||
await _table_columns(datasette, database)
|
||||
await _editor_schema(datasette, database)
|
||||
if allow_execute_sql
|
||||
else {}
|
||||
),
|
||||
default_table=default_table,
|
||||
columns=columns,
|
||||
renderers=renderers,
|
||||
url_csv=datasette.urls.path(
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ from .query_helpers import (
|
|||
_inserted_row_url,
|
||||
_json_or_form_payload,
|
||||
_prepare_execute_write,
|
||||
_editor_schema,
|
||||
_table_columns,
|
||||
_wants_json,
|
||||
)
|
||||
|
|
@ -266,6 +267,7 @@ class ExecuteWriteView(BaseView):
|
|||
write_template_tables = await _write_template_tables(
|
||||
self.ds, db, table_columns, hidden_table_names, request.actor
|
||||
)
|
||||
editor_schema = await _editor_schema(self.ds, db.name)
|
||||
write_template_operations = _write_template_operations(write_template_tables)
|
||||
write_create_table_template_sql = await _create_table_template_sql(
|
||||
self.ds, db, request.actor
|
||||
|
|
@ -328,7 +330,7 @@ class ExecuteWriteView(BaseView):
|
|||
"sql_parameter_name_prefix": SQL_PARAMETER_FORM_PREFIX,
|
||||
"execute_disabled": bool(execute_disabled_reason),
|
||||
"execute_disabled_reason": execute_disabled_reason,
|
||||
"table_columns": table_columns,
|
||||
"table_columns": editor_schema,
|
||||
"write_template_tables": write_template_tables,
|
||||
"write_template_operations": write_template_operations,
|
||||
"write_create_table_template_sql": write_create_table_template_sql,
|
||||
|
|
|
|||
|
|
@ -634,3 +634,92 @@ async def _table_columns(datasette, database_name):
|
|||
for view_name in await db.view_names():
|
||||
table_columns[view_name] = []
|
||||
return table_columns
|
||||
|
||||
|
||||
def _column_completion(name, type_):
|
||||
# A @codemirror/lang-sql Completion object for a single column. boost keeps
|
||||
# columns ranked above bare SQL keywords in the autocomplete popup.
|
||||
completion = {
|
||||
"label": name,
|
||||
"type": "property",
|
||||
"boost": 10,
|
||||
}
|
||||
if type_:
|
||||
completion["detail"] = type_
|
||||
return completion
|
||||
|
||||
|
||||
async def _schema_tables(datasette, database_name, *, include_hidden=True):
|
||||
"""
|
||||
Neutral introspection of a database's tables and views for SQL editors.
|
||||
|
||||
Returns an ordered list of dicts, one per table or view::
|
||||
|
||||
{"name": str, "view": bool,
|
||||
"columns": [{"name": str, "type": str}, ...]}
|
||||
|
||||
``type`` is the SQLite declared column type (empty string when the column
|
||||
has no declared type). Regular-table columns come from the internal
|
||||
``catalog_columns`` catalog; views are absent from that catalog so their
|
||||
columns are read directly via PRAGMA table_xinfo. Hidden tables (FTS shadow
|
||||
tables and the like) are excluded unless ``include_hidden`` is True. This is
|
||||
the shared, serialization-agnostic source for both ``_editor_schema`` (which
|
||||
maps it to lang-sql Completion objects) and the ``/-/editor-schema.json``
|
||||
endpoint (which emits it directly).
|
||||
"""
|
||||
internal_db = datasette.get_internal_database()
|
||||
result = await internal_db.execute(
|
||||
"select table_name, name, type from catalog_columns where database_name = ?",
|
||||
[database_name],
|
||||
)
|
||||
table_columns = {}
|
||||
for row in result.rows:
|
||||
table_columns.setdefault(row["table_name"], []).append(
|
||||
{"name": row["name"], "type": row["type"]}
|
||||
)
|
||||
db = datasette.get_database(database_name)
|
||||
hidden = set() if include_hidden else set(await db.hidden_table_names())
|
||||
tables = []
|
||||
for table_name, columns in table_columns.items():
|
||||
if table_name in hidden:
|
||||
continue
|
||||
tables.append({"name": table_name, "view": False, "columns": columns})
|
||||
# Views are not represented in catalog_columns, so pull their real columns
|
||||
# directly (PRAGMA table_xinfo works against views too).
|
||||
for view_name in await db.view_names():
|
||||
columns = [
|
||||
{"name": column.name, "type": column.type}
|
||||
for column in await db.table_column_details(view_name)
|
||||
]
|
||||
tables.append({"name": view_name, "view": True, "columns": columns})
|
||||
return tables
|
||||
|
||||
|
||||
async def _editor_schema(datasette, database_name):
|
||||
"""
|
||||
Build a lang-sql SQLNamespace for the CodeMirror SQL editor autocomplete.
|
||||
|
||||
Returns a dict keyed by table or view name. Table values are lists of
|
||||
Completion objects (one per column, carrying the column's SQLite type as
|
||||
``detail``). Views are wrapped in a ``{"self": Completion, "children": [...]}``
|
||||
container so the popup can label them as views while still completing their
|
||||
real columns. See @codemirror/lang-sql >= 6.6 SQLNamespace / Completion.
|
||||
"""
|
||||
schema = {}
|
||||
for table in await _schema_tables(datasette, database_name, include_hidden=True):
|
||||
completions = [
|
||||
_column_completion(column["name"], column["type"])
|
||||
for column in table["columns"]
|
||||
]
|
||||
if table["view"]:
|
||||
schema[table["name"]] = {
|
||||
"self": {
|
||||
"label": table["name"],
|
||||
"type": "class",
|
||||
"detail": "view",
|
||||
},
|
||||
"children": completions,
|
||||
}
|
||||
else:
|
||||
schema[table["name"]] = completions
|
||||
return schema
|
||||
|
|
|
|||
|
|
@ -1345,6 +1345,59 @@ class DatabaseSchemaView(SchemaBaseView):
|
|||
return await self.format_html_response(request, schemas)
|
||||
|
||||
|
||||
class DatabaseEditorSchemaView(BaseView):
|
||||
"""
|
||||
JSON introspection of a database's tables, views and columns shaped for SQL
|
||||
editor autocomplete consumers (the CodeMirror ``<datasette-sql-editor>``
|
||||
component and external clients such as datasette-paper).
|
||||
|
||||
Distinct from :class:`DatabaseSchemaView` (``/<db>/-/schema.json``), which
|
||||
returns the raw DDL as a SQL string gated on ``view-database`` alone. This
|
||||
endpoint returns a neutral structured payload and is gated on both
|
||||
``view-database`` and ``execute-sql`` — the same permissions as the inline
|
||||
editor schema handed to the SQL query page.
|
||||
"""
|
||||
|
||||
name = "database_editor_schema"
|
||||
has_json_alternate = False
|
||||
|
||||
async def get(self, request):
|
||||
from .query_helpers import _schema_tables
|
||||
|
||||
database_name = request.url_vars["database"]
|
||||
|
||||
# view-database is checked first so actors without it cannot
|
||||
# distinguish an existing database from a missing one, and a denied
|
||||
# request only ever leaks the permission action name, never table names.
|
||||
await self.ds.ensure_permission(
|
||||
action="view-database",
|
||||
resource=DatabaseResource(database=database_name),
|
||||
actor=request.actor,
|
||||
)
|
||||
if database_name not in self.ds.databases:
|
||||
headers = {}
|
||||
if self.ds.cors:
|
||||
add_cors_headers(headers)
|
||||
return Response.json(
|
||||
error_body("Database not found", 404), status=404, headers=headers
|
||||
)
|
||||
await self.ds.ensure_permission(
|
||||
action="execute-sql",
|
||||
resource=DatabaseResource(database=database_name),
|
||||
actor=request.actor,
|
||||
)
|
||||
|
||||
await self.ds.refresh_schemas()
|
||||
tables = await _schema_tables(self.ds, database_name, include_hidden=False)
|
||||
|
||||
headers = {}
|
||||
if self.ds.cors:
|
||||
add_cors_headers(headers)
|
||||
return Response.json(
|
||||
{"database": database_name, "tables": tables}, headers=headers
|
||||
)
|
||||
|
||||
|
||||
class TableSchemaView(SchemaBaseView):
|
||||
"""
|
||||
Displays schema for a specific table.
|
||||
|
|
|
|||
|
|
@ -434,13 +434,10 @@ Datasette bundles `CodeMirror <https://codemirror.net/>`__ for the SQL editing i
|
|||
|
||||
npm i codemirror @codemirror/lang-sql
|
||||
|
||||
* Build the bundle using the version number from package.json with::
|
||||
* Build the bundle with::
|
||||
|
||||
node_modules/.bin/rollup datasette/static/cm-editor-6.0.1.js \
|
||||
-f iife \
|
||||
-n cm \
|
||||
-o datasette/static/cm-editor-6.0.1.bundle.js \
|
||||
-p @rollup/plugin-node-resolve \
|
||||
-p @rollup/plugin-terser
|
||||
npm install && npm run build:codemirror
|
||||
|
||||
* Update the version reference in the ``codemirror.html`` template.
|
||||
This runs ``rollup -c`` against the ``rollup.config.mjs`` file at the root of the repository, which reads ``datasette/static/cm-editor.js`` and writes the bundled, minified output to ``datasette/static/cm-editor.bundle.js``. The bundle filename does not include the CodeMirror version number, so no template needs to be updated.
|
||||
|
||||
* Commit the rebuilt ``datasette/static/cm-editor.bundle.js`` - the bundle is checked into the repository.
|
||||
|
|
|
|||
|
|
@ -152,6 +152,62 @@ Values for named SQL parameters can be provided as additional query string param
|
|||
|
||||
The response uses the same default representation described above.
|
||||
|
||||
.. _json_api_editor_schema:
|
||||
|
||||
.. _DatabaseEditorSchemaView:
|
||||
|
||||
Schema for SQL editors
|
||||
----------------------
|
||||
|
||||
The ``/-/editor-schema.json`` endpoint returns a machine-readable description of
|
||||
a database's tables, views and columns, shaped for SQL editor autocomplete. It
|
||||
powers Datasette's own CodeMirror SQL editor and is available for external
|
||||
consumers such as embeddable editor components.
|
||||
|
||||
::
|
||||
|
||||
GET /<database>/-/editor-schema.json
|
||||
|
||||
Access requires both the :ref:`actions_view_database` and
|
||||
:ref:`actions_execute_sql` permissions for the database - the same gate as the
|
||||
inline editor schema on the SQL query page. A request that fails either check
|
||||
receives a ``403`` JSON error that does not reveal any table or column names.
|
||||
|
||||
The response is a neutral structure - a ``database`` name and a list of
|
||||
``tables``, each with a ``view`` flag (``true`` for SQL views) and a list of
|
||||
``columns`` carrying the SQLite declared ``type`` (an empty string when the
|
||||
column has no declared type):
|
||||
|
||||
.. code-block:: json
|
||||
|
||||
{
|
||||
"database": "fixtures",
|
||||
"tables": [
|
||||
{
|
||||
"name": "facetable",
|
||||
"view": false,
|
||||
"columns": [
|
||||
{"name": "pk", "type": "INTEGER"},
|
||||
{"name": "state", "type": "TEXT"}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "paginated_view",
|
||||
"view": true,
|
||||
"columns": [
|
||||
{"name": "content", "type": "TEXT"}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
Hidden tables - such as the shadow tables that back SQLite full-text search -
|
||||
are excluded from the response.
|
||||
|
||||
This endpoint is distinct from the :ref:`database schema endpoint <DatabaseSchemaView>`
|
||||
at ``/<database>/-/schema.json``, which returns the raw ``CREATE`` statements as
|
||||
a SQL string.
|
||||
|
||||
.. _json_api_shapes:
|
||||
|
||||
Different shapes
|
||||
|
|
|
|||
|
|
@ -168,6 +168,9 @@ The page for arbitrary SQL queries (/database/-/query?sql=...) and stored querie
|
|||
``db_is_immutable`` - ``bool``
|
||||
Boolean indicating if this database is immutable
|
||||
|
||||
``default_table`` - ``str``
|
||||
Name of the focal table for this query, if any - set when the query page was reached from a table-scoped context (such as the table page's 'View and edit SQL' link) so the SQL editor can complete that table's columns unprefixed. ``None`` otherwise, including for stored/canned queries.
|
||||
|
||||
``display_rows`` - ``list``
|
||||
List of result rows formatted for HTML display. Each row is a list of rendered cell values in the same order as ``columns``.
|
||||
|
||||
|
|
|
|||
741
package-lock.json
generated
741
package-lock.json
generated
|
|
@ -1,15 +1,16 @@
|
|||
{
|
||||
"name": "datasette",
|
||||
"lockfileVersion": 2,
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "datasette",
|
||||
"dependencies": {
|
||||
"@codemirror/lang-sql": "^6.3.3",
|
||||
"@codemirror/lang-sql": "^6.10.0",
|
||||
"@codemirror/state": "^6.7.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-terser": "^0.1.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror": "^6.0.2",
|
||||
"rollup": "^3.30.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
@ -17,175 +18,184 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@codemirror/autocomplete": {
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.2.tgz",
|
||||
"integrity": "sha512-+VzxrHWkuvSSt0fw4I57SULo/NMrLnNgm6JHrkbIYfDw9jZJNTruCwkv32TCqSeC8xIXhYWMuxawwr/xOoHr8w==",
|
||||
"version": "6.20.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.3.tgz",
|
||||
"integrity": "sha512-tlosUqb+3BbxCxZdu4tKeRghPFC+QM7q4X5YhKV2eCmPG+1r2F3f4AaSz5sCrFqUtX4Jh20VFTKecl16MgiV9g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.5.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@codemirror/view": "^6.17.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/commands": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.1.2.tgz",
|
||||
"integrity": "sha512-sO3jdX1s0pam6lIdeSJLMN3DQ6mPEbM4yLvyKkdqtmd/UDwhXA5+AwFJ89rRXm6vTeOXBsE5cAmlos/t7MJdgg==",
|
||||
"version": "6.10.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.10.4.tgz",
|
||||
"integrity": "sha512-Ryk9y9T0FFVF0cUGhAknveAyUOl/A1qReTFi+qPKtOh2Z9F4AUBz3XOrYD4ZEgZirdugVzHvd/2/Wcwy5OliTg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
"@codemirror/state": "^6.7.0",
|
||||
"@codemirror/view": "^6.27.0",
|
||||
"@lezer/common": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lang-sql": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.3.3.tgz",
|
||||
"integrity": "sha512-VNsHju8500fkiDyDU8jZyGQ8M0iXU0SmfeCoCeAYkACcEFlX63BOT8311pICXyw43VYRbS23w54RgSEQmixGjQ==",
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.10.0.tgz",
|
||||
"integrity": "sha512-6ayPkEd/yRw0XKBx5uAiToSgGECo/GY2NoJIHXIIQh1EVwLuKoU8BP/qK0qH5NLXAbtJRLuT73hx7P9X34iO4w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/common": "^1.2.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/language": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.3.1.tgz",
|
||||
"integrity": "sha512-MK+G1QKaGfSEUg9YEFaBkMBI6j1ge4VMBPZv9fDYotw7w695c42x5Ba1mmwBkesYnzYFBfte6Hh9TDcKa6xORQ==",
|
||||
"version": "6.12.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.12.4.tgz",
|
||||
"integrity": "sha512-1q4PaT+o6PbgpkJt4Q8Fv5XJxTy4FUZ4MWETtyiDw3J0Pyr9E2vqcKL+k9wcvjNTIsauxvE7OfmWj3FRPHQ76A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@codemirror/view": "^6.23.0",
|
||||
"@lezer/common": "^1.5.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/lint": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.1.0.tgz",
|
||||
"integrity": "sha512-mdvDQrjRmYPvQ3WrzF6Ewaao+NWERYtpthJvoQ3tK3t/44Ynhk8ZGjTSL9jMEv8CgSMogmt75X8ceOZRDSXHtQ==",
|
||||
"version": "6.9.7",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.9.7.tgz",
|
||||
"integrity": "sha512-28/+iWLYxKxsvGYhSYL7zaCZqLz5+FFFDq9tVsvGv9kv8RY4fFAchJ5WX9M3YrrRlTIsECjsXPqeNgnSmNP2dg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@codemirror/view": "^6.42.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/search": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.2.3.tgz",
|
||||
"integrity": "sha512-V9n9233lopQhB1dyjsBK2Wc1i+8hcCqxl1wQ46c5HWWLePoe4FluV3TGHoZ04rBRlGjNyz9DTmpJErig8UE4jw==",
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.7.1.tgz",
|
||||
"integrity": "sha512-uMe5UO6PamJtSHrXhhHOzSX3ReWtiJrva6GnPMwSOrZtiExb5X5eExhr2OUZQVvdxPsKpY3Ro2mFbQadpPWmHA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@codemirror/view": "^6.37.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/state": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.4.tgz",
|
||||
"integrity": "sha512-g+3OJuRylV5qsXuuhrc6Cvs1NQluNioepYMM2fhnpYkNk7NgX+j0AFuevKSVKzTDmDyt9+Puju+zPdHNECzCNQ=="
|
||||
"version": "6.7.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.7.1.tgz",
|
||||
"integrity": "sha512-9QzNDgE4EYDnAHfrTlR2lwiPciiOymLtwKK+8yHQzCc7GXhAP9xdEbEJFy2IWB1j9UGUl9BsgMmTo/ImA02T7A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@marijn/find-cluster-break": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@codemirror/view": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.5.1.tgz",
|
||||
"integrity": "sha512-xBKP8N3AXOs06VcKvIuvIQoUlGs7Hb78ftJWahLaRX909jKPMgGxR5XjvrawzTTZMSTU3DzdjDNPwG6fPM/ypQ==",
|
||||
"version": "6.43.6",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.43.6.tgz",
|
||||
"integrity": "sha512-EVunGSYN1wz1p75WY1s3Xg7t3i8Yol0kGZGizNdX9BUFgMFILYVe8/u6EVpo7Ff5PwbZuILb4QAq7IZoKzIEQA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/state": "^6.1.4",
|
||||
"style-mod": "^4.0.0",
|
||||
"@codemirror/state": "^6.7.0",
|
||||
"crelt": "^1.0.6",
|
||||
"style-mod": "^4.1.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"version": "0.3.13",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
|
||||
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
"@jridgewell/sourcemap-codec": "^1.5.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.24"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/resolve-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==",
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
|
||||
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"version": "0.3.11",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
|
||||
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
"@jridgewell/gen-mapping": "^0.3.5",
|
||||
"@jridgewell/trace-mapping": "^0.3.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
"version": "1.5.5",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
|
||||
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@jridgewell/trace-mapping": {
|
||||
"version": "0.3.17",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
|
||||
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
|
||||
"version": "0.3.31",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
|
||||
"integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/resolve-uri": "3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
||||
"@jridgewell/resolve-uri": "^3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.14"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/common": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.1.tgz",
|
||||
"integrity": "sha512-8TR5++Q/F//tpDsLd5zkrvEX5xxeemafEaek7mUp7Y+bI8cKQXdSqhzTOBaOogETcMOVr0pT3BBPXp13477ciw=="
|
||||
"version": "1.5.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.5.2.tgz",
|
||||
"integrity": "sha512-sxQE460fPZyU3sdc8lafxiPwJHBzZRy/udNFynGQky1SePYBdhkBl1kOagA9uT3pxR8K09bOrmTUqA9wb/PjSQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@lezer/highlight": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.2.tgz",
|
||||
"integrity": "sha512-CAun1WR1glxG9ZdOokTZwXbcwB7PXkIEyZRUMFBVwSrhTcogWq634/ByNImrkUnQhjju6xsIaOBIxvcRJtplXQ==",
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.2.3.tgz",
|
||||
"integrity": "sha512-qXdH7UqTvGfdVBINrgKhDsVTJTxactNNxLk7+UMwZhU13lMHaOBlJe9Vqp907ya56Y3+ed2tlqzys7jDkTmW0g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
"@lezer/common": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@lezer/lr": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.4.tgz",
|
||||
"integrity": "sha512-L/52/oMJBFXXx8qBYF4UgktLP2geQ/qn5Fd8+5L/mqlLLCB9+qdKktFAtejd9FdFMaFx6lrP5rmLz4sN3Kplcg==",
|
||||
"version": "1.4.10",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.4.10.tgz",
|
||||
"integrity": "sha512-rnCpTIBafOx4mRp43xOxDJbFipJm/c0cia/V5TiGlhmMa+wsSdoGmUN3w5Bqrks/09Q/D4tNAmWaT8p6NRi77A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@marijn/find-cluster-break": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.3.tgz",
|
||||
"integrity": "sha512-FY+MKLBoTsLNJF/eLWaOsXGdz6uh3Iu1axjPf6TUq92IYumcTcXWHoS747JARLkcdlJ/Waiaxc5wQfFO8jC6NA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@rollup/plugin-node-resolve": {
|
||||
"version": "15.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
||||
"integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
|
||||
"version": "15.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.1.tgz",
|
||||
"integrity": "sha512-tgg6b91pAybXHJQMAAwW9VuWBO6Thi+q7BCNARLwSqlmsHz0XYURtGvh/AuwSADXSI4h/2uHbs7s4FzlZDGSGA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-builtin-module": "^3.2.0",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
},
|
||||
|
|
@ -193,7 +203,7 @@
|
|||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.0||^3.0.0"
|
||||
"rollup": "^2.78.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
|
|
@ -205,6 +215,7 @@
|
|||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.1.0.tgz",
|
||||
"integrity": "sha512-N2KK+qUfHX2hBzVzM41UWGLrEmcjVC37spC8R3c9mt3oEDFKh3N2e12/lLp9aVSt86veR0TQiCNQXrm8C6aiUQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"terser": "^5.15.1"
|
||||
},
|
||||
|
|
@ -221,19 +232,20 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.4.0.tgz",
|
||||
"integrity": "sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
"picomatch": "^4.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0"
|
||||
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"rollup": {
|
||||
|
|
@ -242,19 +254,22 @@
|
|||
}
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
||||
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz",
|
||||
"integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/acorn": {
|
||||
"version": "8.8.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
|
||||
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==",
|
||||
"version": "8.17.0",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz",
|
||||
"integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==",
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
},
|
||||
|
|
@ -265,23 +280,14 @@
|
|||
"node_modules/buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/codemirror": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||
"version": "6.0.2",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.2.tgz",
|
||||
"integrity": "sha512-VhydHotNW5w1UGK0Qj96BwSk/Zqbp9WbnyK2W/eVMv4QyF41INRGpjUhFJY7/uDNuudSc33a/PKr4iDqRduvHw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
|
|
@ -295,31 +301,45 @@
|
|||
"node_modules/commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
|
||||
"integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.7.tgz",
|
||||
"integrity": "sha512-aK6BbWfhf4U/wCcLHKPJl/xa6VkVstRaPywWtMKGwuOLc/wZTyQYuoxgvZnNsBvv7Kg3YTBQYYBCggcviQczuA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
|
||||
"integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
|
|
@ -329,41 +349,36 @@
|
|||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4.0"
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-builtin-module": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
|
||||
"integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz",
|
||||
"integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"builtin-modules": "^3.3.0"
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
|
||||
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
|
||||
"version": "2.16.2",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz",
|
||||
"integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
"hasown": "^2.0.3"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
|
|
@ -372,28 +387,31 @@
|
|||
"node_modules/is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
|
||||
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
|
||||
"version": "4.0.5",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz",
|
||||
"integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/prettier": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"version": "3.9.5",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.5.tgz",
|
||||
"integrity": "sha512-/FVl766LpUfB5vXgCYOYa0MeV/441Ia99AeICQIQFTY/Nw0roZwULcXpku5i1/m5kt/baz+s4Zogspd839HSMg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
|
|
@ -407,17 +425,22 @@
|
|||
}
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
|
||||
"version": "1.22.12",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz",
|
||||
"integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.9.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"is-core-module": "^2.16.1",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"resolve": "bin/resolve"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
|
|
@ -426,6 +449,8 @@
|
|||
"version": "3.30.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz",
|
||||
"integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
|
|
@ -441,6 +466,7 @@
|
|||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
|
@ -449,20 +475,23 @@
|
|||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/style-mod": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
|
||||
"version": "4.1.3",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.1.3.tgz",
|
||||
"integrity": "sha512-i/n8VsZydrugj3Iuzll8+x/00GH2vnYsk1eomD8QiRrSAeW6ItbCQDtfXCeJHd0iwiNagqjQkvpvREEPtW3IoQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
|
|
@ -471,12 +500,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/terser": {
|
||||
"version": "5.15.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
|
||||
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
|
||||
"version": "5.49.0",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.49.0.tgz",
|
||||
"integrity": "sha512-SNiDnXyHSrxVcIOtVbULzcTmniUiwcV7Nwdyj1twVubeTmbjoa8p69KKDpfkdoOavuM4/GRm1+ykI8qqnavHoA==",
|
||||
"license": "BSD-2-Clause",
|
||||
"dependencies": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"@jridgewell/source-map": "^0.3.3",
|
||||
"acorn": "^8.15.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
},
|
||||
|
|
@ -488,361 +518,10 @@
|
|||
}
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
|
||||
"integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg=="
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/autocomplete": {
|
||||
"version": "6.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.3.2.tgz",
|
||||
"integrity": "sha512-+VzxrHWkuvSSt0fw4I57SULo/NMrLnNgm6JHrkbIYfDw9jZJNTruCwkv32TCqSeC8xIXhYWMuxawwr/xOoHr8w==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.5.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/commands": {
|
||||
"version": "6.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/commands/-/commands-6.1.2.tgz",
|
||||
"integrity": "sha512-sO3jdX1s0pam6lIdeSJLMN3DQ6mPEbM4yLvyKkdqtmd/UDwhXA5+AwFJ89rRXm6vTeOXBsE5cAmlos/t7MJdgg==",
|
||||
"requires": {
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/lang-sql": {
|
||||
"version": "6.3.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lang-sql/-/lang-sql-6.3.3.tgz",
|
||||
"integrity": "sha512-VNsHju8500fkiDyDU8jZyGQ8M0iXU0SmfeCoCeAYkACcEFlX63BOT8311pICXyw43VYRbS23w54RgSEQmixGjQ==",
|
||||
"requires": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/language": {
|
||||
"version": "6.3.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/language/-/language-6.3.1.tgz",
|
||||
"integrity": "sha512-MK+G1QKaGfSEUg9YEFaBkMBI6j1ge4VMBPZv9fDYotw7w695c42x5Ba1mmwBkesYnzYFBfte6Hh9TDcKa6xORQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"@lezer/common": "^1.0.0",
|
||||
"@lezer/highlight": "^1.0.0",
|
||||
"@lezer/lr": "^1.0.0",
|
||||
"style-mod": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@codemirror/lint": {
|
||||
"version": "6.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/lint/-/lint-6.1.0.tgz",
|
||||
"integrity": "sha512-mdvDQrjRmYPvQ3WrzF6Ewaao+NWERYtpthJvoQ3tK3t/44Ynhk8ZGjTSL9jMEv8CgSMogmt75X8ceOZRDSXHtQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"@codemirror/search": {
|
||||
"version": "6.2.3",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/search/-/search-6.2.3.tgz",
|
||||
"integrity": "sha512-V9n9233lopQhB1dyjsBK2Wc1i+8hcCqxl1wQ46c5HWWLePoe4FluV3TGHoZ04rBRlGjNyz9DTmpJErig8UE4jw==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0",
|
||||
"crelt": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"@codemirror/state": {
|
||||
"version": "6.1.4",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/state/-/state-6.1.4.tgz",
|
||||
"integrity": "sha512-g+3OJuRylV5qsXuuhrc6Cvs1NQluNioepYMM2fhnpYkNk7NgX+j0AFuevKSVKzTDmDyt9+Puju+zPdHNECzCNQ=="
|
||||
},
|
||||
"@codemirror/view": {
|
||||
"version": "6.5.1",
|
||||
"resolved": "https://registry.npmjs.org/@codemirror/view/-/view-6.5.1.tgz",
|
||||
"integrity": "sha512-xBKP8N3AXOs06VcKvIuvIQoUlGs7Hb78ftJWahLaRX909jKPMgGxR5XjvrawzTTZMSTU3DzdjDNPwG6fPM/ypQ==",
|
||||
"requires": {
|
||||
"@codemirror/state": "^6.1.4",
|
||||
"style-mod": "^4.0.0",
|
||||
"w3c-keyname": "^2.2.4"
|
||||
}
|
||||
},
|
||||
"@jridgewell/gen-mapping": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz",
|
||||
"integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==",
|
||||
"requires": {
|
||||
"@jridgewell/set-array": "^1.0.1",
|
||||
"@jridgewell/sourcemap-codec": "^1.4.10",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/resolve-uri": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz",
|
||||
"integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w=="
|
||||
},
|
||||
"@jridgewell/set-array": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz",
|
||||
"integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw=="
|
||||
},
|
||||
"@jridgewell/source-map": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
|
||||
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
|
||||
"requires": {
|
||||
"@jridgewell/gen-mapping": "^0.3.0",
|
||||
"@jridgewell/trace-mapping": "^0.3.9"
|
||||
}
|
||||
},
|
||||
"@jridgewell/sourcemap-codec": {
|
||||
"version": "1.4.14",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz",
|
||||
"integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw=="
|
||||
},
|
||||
"@jridgewell/trace-mapping": {
|
||||
"version": "0.3.17",
|
||||
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz",
|
||||
"integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==",
|
||||
"requires": {
|
||||
"@jridgewell/resolve-uri": "3.1.0",
|
||||
"@jridgewell/sourcemap-codec": "1.4.14"
|
||||
}
|
||||
},
|
||||
"@lezer/common": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/common/-/common-1.0.1.tgz",
|
||||
"integrity": "sha512-8TR5++Q/F//tpDsLd5zkrvEX5xxeemafEaek7mUp7Y+bI8cKQXdSqhzTOBaOogETcMOVr0pT3BBPXp13477ciw=="
|
||||
},
|
||||
"@lezer/highlight": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/highlight/-/highlight-1.1.2.tgz",
|
||||
"integrity": "sha512-CAun1WR1glxG9ZdOokTZwXbcwB7PXkIEyZRUMFBVwSrhTcogWq634/ByNImrkUnQhjju6xsIaOBIxvcRJtplXQ==",
|
||||
"requires": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@lezer/lr": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@lezer/lr/-/lr-1.2.4.tgz",
|
||||
"integrity": "sha512-L/52/oMJBFXXx8qBYF4UgktLP2geQ/qn5Fd8+5L/mqlLLCB9+qdKktFAtejd9FdFMaFx6lrP5rmLz4sN3Kplcg==",
|
||||
"requires": {
|
||||
"@lezer/common": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-node-resolve": {
|
||||
"version": "15.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.0.1.tgz",
|
||||
"integrity": "sha512-ReY88T7JhJjeRVbfCyNj+NXAG3IIsVMsX9b5/9jC98dRP8/yxlZdz7mHZbHk5zHr24wZZICS5AcXsFZAXYUQEg==",
|
||||
"requires": {
|
||||
"@rollup/pluginutils": "^5.0.1",
|
||||
"@types/resolve": "1.20.2",
|
||||
"deepmerge": "^4.2.2",
|
||||
"is-builtin-module": "^3.2.0",
|
||||
"is-module": "^1.0.0",
|
||||
"resolve": "^1.22.1"
|
||||
}
|
||||
},
|
||||
"@rollup/plugin-terser": {
|
||||
"version": "0.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/plugin-terser/-/plugin-terser-0.1.0.tgz",
|
||||
"integrity": "sha512-N2KK+qUfHX2hBzVzM41UWGLrEmcjVC37spC8R3c9mt3oEDFKh3N2e12/lLp9aVSt86veR0TQiCNQXrm8C6aiUQ==",
|
||||
"requires": {
|
||||
"terser": "^5.15.1"
|
||||
}
|
||||
},
|
||||
"@rollup/pluginutils": {
|
||||
"version": "5.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz",
|
||||
"integrity": "sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==",
|
||||
"requires": {
|
||||
"@types/estree": "^1.0.0",
|
||||
"estree-walker": "^2.0.2",
|
||||
"picomatch": "^2.3.1"
|
||||
}
|
||||
},
|
||||
"@types/estree": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.0.tgz",
|
||||
"integrity": "sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ=="
|
||||
},
|
||||
"@types/resolve": {
|
||||
"version": "1.20.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz",
|
||||
"integrity": "sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q=="
|
||||
},
|
||||
"acorn": {
|
||||
"version": "8.8.1",
|
||||
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz",
|
||||
"integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA=="
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz",
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ=="
|
||||
},
|
||||
"builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
"integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw=="
|
||||
},
|
||||
"codemirror": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/codemirror/-/codemirror-6.0.1.tgz",
|
||||
"integrity": "sha512-J8j+nZ+CdWmIeFIGXEFbFPtpiYacFMDR8GlHK3IyHQJMCaVRfGx9NT+Hxivv1ckLWPvNdZqndbr/7lVhrf/Svg==",
|
||||
"requires": {
|
||||
"@codemirror/autocomplete": "^6.0.0",
|
||||
"@codemirror/commands": "^6.0.0",
|
||||
"@codemirror/language": "^6.0.0",
|
||||
"@codemirror/lint": "^6.0.0",
|
||||
"@codemirror/search": "^6.0.0",
|
||||
"@codemirror/state": "^6.0.0",
|
||||
"@codemirror/view": "^6.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"crelt": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.5.tgz",
|
||||
"integrity": "sha512-+BO9wPPi+DWTDcNYhr/W90myha8ptzftZT+LwcmUbbok0rcP/fequmFYCw8NMoH7pkAZQzU78b3kYrlua5a9eA=="
|
||||
},
|
||||
"deepmerge": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz",
|
||||
"integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg=="
|
||||
},
|
||||
"estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w=="
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"optional": true
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"is-builtin-module": {
|
||||
"version": "3.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
|
||||
"integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
|
||||
"requires": {
|
||||
"builtin-modules": "^3.3.0"
|
||||
}
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.11.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
|
||||
"integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
},
|
||||
"is-module": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-module/-/is-module-1.0.0.tgz",
|
||||
"integrity": "sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g=="
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
"integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
|
||||
"integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA=="
|
||||
},
|
||||
"prettier": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
|
||||
"integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
|
||||
"requires": {
|
||||
"is-core-module": "^2.9.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "3.30.0",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.30.0.tgz",
|
||||
"integrity": "sha512-kQvGasUgN+AlWGliFn2POSajRQEsULVYFGTvOZmK06d7vCD+YhZztt70kGk3qaeAXeWYL5eO7zx+rAubBc55eA==",
|
||||
"requires": {
|
||||
"fsevents": "~2.3.2"
|
||||
}
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.21",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz",
|
||||
"integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==",
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"style-mod": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/style-mod/-/style-mod-4.0.0.tgz",
|
||||
"integrity": "sha512-OPhtyEjyyN9x3nhPsu76f52yUGXiZcgvsrFVtvTkyGRQJ0XK+GPc6ov1z+lRpbeabka+MYEQxOYRnt5nF30aMw=="
|
||||
},
|
||||
"supports-preserve-symlinks-flag": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
|
||||
"integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
|
||||
},
|
||||
"terser": {
|
||||
"version": "5.15.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
|
||||
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
|
||||
"requires": {
|
||||
"@jridgewell/source-map": "^0.3.2",
|
||||
"acorn": "^8.5.0",
|
||||
"commander": "^2.20.0",
|
||||
"source-map-support": "~0.5.20"
|
||||
}
|
||||
},
|
||||
"w3c-keyname": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.6.tgz",
|
||||
"integrity": "sha512-f+fciywl1SJEniZHD6H+kUO8gOnwIr7f4ijKA6+ZvJFjeGi1r4PDLl53Ayud9O/rk64RqgoQine0feoeOU0kXg=="
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"license": "MIT"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,14 +5,16 @@
|
|||
"prettier": "^3.0.0"
|
||||
},
|
||||
"scripts": {
|
||||
"build:codemirror": "rollup -c",
|
||||
"fix": "npm run prettier -- --write",
|
||||
"prettier": "prettier 'datasette/static/*[!.min|bundle].js'"
|
||||
},
|
||||
"dependencies": {
|
||||
"@codemirror/lang-sql": "^6.3.3",
|
||||
"@codemirror/lang-sql": "^6.10.0",
|
||||
"@codemirror/state": "^6.7.1",
|
||||
"@rollup/plugin-node-resolve": "^15.0.1",
|
||||
"@rollup/plugin-terser": "^0.1.0",
|
||||
"codemirror": "^6.0.1",
|
||||
"codemirror": "^6.0.2",
|
||||
"rollup": "^3.30.0"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
rollup.config.mjs
Normal file
12
rollup.config.mjs
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
import { nodeResolve } from "@rollup/plugin-node-resolve";
|
||||
import terser from "@rollup/plugin-terser";
|
||||
|
||||
export default {
|
||||
input: "datasette/static/cm-editor.js",
|
||||
output: {
|
||||
file: "datasette/static/cm-editor.bundle.js",
|
||||
format: "iife",
|
||||
name: "cm",
|
||||
},
|
||||
plugins: [nodeResolve(), terser()],
|
||||
};
|
||||
|
|
@ -284,6 +284,53 @@ async def test_query_page_with_no_sql(ds_client):
|
|||
assert 'class="rows-and-columns"' not in response.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_table_page_view_and_edit_sql_link_carries_table(ds_client):
|
||||
# The table page's "View and edit SQL" link should point at the query
|
||||
# page with a &_table= param identifying the focal table, so the SQL
|
||||
# editor can offer that table's columns unprefixed.
|
||||
response = await ds_client.get("/fixtures/facetable")
|
||||
assert response.status_code == 200
|
||||
soup = Soup(response.content, "html.parser")
|
||||
link = soup.find("span", string="View and edit SQL").find_parent("a")
|
||||
assert link is not None
|
||||
assert "_table=facetable" in link["href"]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_page_default_table_from_table_scoped_link(ds_client):
|
||||
# Following the table page's edit-SQL link should result in a query page
|
||||
# whose SQL editor is initialized with defaultTable set to that table.
|
||||
table_response = await ds_client.get("/fixtures/facetable")
|
||||
soup = Soup(table_response.content, "html.parser")
|
||||
href = soup.find("span", string="View and edit SQL").find_parent("a")["href"]
|
||||
response = await ds_client.get(href, follow_redirects=True)
|
||||
assert response.status_code == 200
|
||||
assert 'defaultTable: "facetable"' in response.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_page_no_default_table_without_table_scope(ds_client):
|
||||
# The plain database query page (no focal table) should not set
|
||||
# defaultTable at all.
|
||||
response = await ds_client.get("/fixtures/-/query?sql=select+1")
|
||||
assert response.status_code == 200
|
||||
assert "defaultTable" not in response.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_page_ignores_invalid_table_param(ds_client):
|
||||
# A ?_table= value that isn't a real table/view in this database should
|
||||
# not be reflected back into the page - and should not break execution
|
||||
# of the query itself (leading-underscore params are not treated as SQL
|
||||
# bind parameters unless they appear as :name in the SQL).
|
||||
response = await ds_client.get(
|
||||
"/fixtures/-/query?sql=select+1&_table=not_a_real_table"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
assert "defaultTable" not in response.text
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_query_csv_with_no_sql_is_400(ds_client):
|
||||
# https://github.com/simonw/datasette/issues/2743
|
||||
|
|
|
|||
|
|
@ -295,13 +295,24 @@ def test_execute_sql(config):
|
|||
# Extract the schema= portion of the JavaScript
|
||||
schema_json = schema_re.search(response_text).group(1)
|
||||
schema = json.loads(schema_json)
|
||||
assert set(schema["attraction_characteristic"]) == {"name", "pk"}
|
||||
assert schema["paginated_view"] == []
|
||||
assert {c["label"] for c in schema["attraction_characteristic"]} == {
|
||||
"name",
|
||||
"pk",
|
||||
}
|
||||
# Views are self/children containers carrying their real columns
|
||||
assert schema["paginated_view"]["self"]["detail"] == "view"
|
||||
assert {c["label"] for c in schema["paginated_view"]["children"]} == {
|
||||
"content",
|
||||
"content_extra",
|
||||
}
|
||||
assert form_fragment in response_text
|
||||
query_response = client.get("/fixtures/-/query?sql=select+1", cookies=cookies)
|
||||
assert query_response.status == 200
|
||||
schema2 = json.loads(schema_re.search(query_response.text).group(1))
|
||||
assert set(schema2["attraction_characteristic"]) == {"name", "pk"}
|
||||
assert {c["label"] for c in schema2["attraction_characteristic"]} == {
|
||||
"name",
|
||||
"pk",
|
||||
}
|
||||
assert (
|
||||
client.get("/fixtures/facet_cities?_where=id=3", cookies=cookies).status
|
||||
== 200
|
||||
|
|
|
|||
|
|
@ -94,6 +94,83 @@ async def test_queries_internal_table_schema():
|
|||
]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_rich_completions():
|
||||
from datasette.fixtures import TABLES
|
||||
from datasette.views.query_helpers import _editor_schema
|
||||
|
||||
ds = Datasette(memory=True)
|
||||
db = ds.add_memory_database("editor_schema")
|
||||
await ds.invoke_startup()
|
||||
await db.execute_write_script(TABLES)
|
||||
await ds.refresh_schemas()
|
||||
|
||||
schema = await _editor_schema(ds, "editor_schema")
|
||||
|
||||
# Tables are plain lists of Completion objects carrying type + boost
|
||||
attractions = schema["roadside_attractions"]
|
||||
assert isinstance(attractions, list)
|
||||
pk_completion = next(c for c in attractions if c["label"] == "pk")
|
||||
assert pk_completion == {
|
||||
"label": "pk",
|
||||
"type": "property",
|
||||
"boost": 10,
|
||||
"detail": "INTEGER",
|
||||
}
|
||||
# Every column completion is boosted above bare keywords
|
||||
assert all(c["boost"] == 10 and c["type"] == "property" for c in attractions)
|
||||
|
||||
# Views are wrapped in a self/children container labelled as a view
|
||||
view = schema["paginated_view"]
|
||||
assert view["self"] == {
|
||||
"label": "paginated_view",
|
||||
"type": "class",
|
||||
"detail": "view",
|
||||
}
|
||||
child_labels = [c["label"] for c in view["children"]]
|
||||
assert child_labels == ["content", "content_extra"]
|
||||
# Column type inherited from the underlying table flows through as detail;
|
||||
# the computed expression column has no declared type so carries no detail
|
||||
content = next(c for c in view["children"] if c["label"] == "content")
|
||||
assert content["detail"] == "TEXT"
|
||||
content_extra = next(c for c in view["children"] if c["label"] == "content_extra")
|
||||
assert "detail" not in content_extra
|
||||
|
||||
# Whole payload must be JSON-serializable
|
||||
json.dumps(schema)
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_database_page_editor_schema_permission_gated():
|
||||
import secrets
|
||||
from datasette.database import Database
|
||||
from datasette.fixtures import TABLES
|
||||
|
||||
async def schema_for(datasette):
|
||||
# Unique memory name so parallel instances don't share a backing DB
|
||||
name = f"editor_gated_{secrets.token_hex(8)}"
|
||||
db = datasette.add_database(
|
||||
Database(datasette, memory_name=name), name="editor_gated"
|
||||
)
|
||||
await datasette.invoke_startup()
|
||||
await db.execute_write_script(TABLES)
|
||||
await datasette.refresh_schemas()
|
||||
response = await datasette.client.get("/editor_gated.json")
|
||||
assert response.status_code == 200
|
||||
return response.json()["table_columns"]
|
||||
|
||||
# execute-sql allowed (default): rich schema is emitted
|
||||
allowed = await schema_for(Datasette(memory=True))
|
||||
assert isinstance(allowed["roadside_attractions"], list)
|
||||
assert allowed["paginated_view"]["self"]["detail"] == "view"
|
||||
|
||||
# execute-sql denied: no schema leak, empty dict
|
||||
denied = await schema_for(
|
||||
Datasette(memory=True, settings={"default_allow_sql": False})
|
||||
)
|
||||
assert denied == {}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_add_get_and_remove_query():
|
||||
ds = Datasette(memory=True)
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import json
|
||||
|
||||
import pytest
|
||||
import pytest_asyncio
|
||||
from datasette.app import Datasette
|
||||
|
|
@ -245,3 +247,165 @@ async def test_table_not_exists(schema_ds):
|
|||
response = await schema_ds.client.get("/schema_public_db/nonexistent/-/schema.md")
|
||||
assert response.status_code == 404
|
||||
assert "not found" in response.text.lower()
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# /<database>/-/editor-schema.json — neutral structured schema for SQL editors
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
|
||||
@pytest_asyncio.fixture(scope="module")
|
||||
async def editor_schema_ds():
|
||||
"""Datasette instance exercising the editor-schema endpoint.
|
||||
|
||||
- public db: tables + a view + an FTS table (hidden shadow tables)
|
||||
- private db: gated behind view-database (allow root only)
|
||||
- noexec db: view-database allowed for anyone, execute-sql denied
|
||||
"""
|
||||
ds = Datasette(
|
||||
config={
|
||||
"databases": {
|
||||
"editor_private_db": {"allow": {"id": "root"}},
|
||||
"editor_noexec_db": {
|
||||
# Everyone may view the database, but nobody may run SQL
|
||||
"allow_sql": {"id": "root"},
|
||||
},
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
public_db = ds.add_memory_database("editor_public_db")
|
||||
await public_db.execute_write(
|
||||
"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT)"
|
||||
)
|
||||
await public_db.execute_write(
|
||||
"CREATE TABLE posts (id INTEGER PRIMARY KEY, title TEXT, body TEXT)"
|
||||
)
|
||||
await public_db.execute_write(
|
||||
"CREATE VIEW recent_posts AS SELECT id, title FROM posts ORDER BY id DESC"
|
||||
)
|
||||
# An FTS table produces hidden shadow tables (users_fts_data, etc.)
|
||||
await public_db.execute_write(
|
||||
"CREATE VIRTUAL TABLE users_fts USING fts5(name, content=users)"
|
||||
)
|
||||
|
||||
private_db = ds.add_memory_database("editor_private_db")
|
||||
await private_db.execute_write(
|
||||
"CREATE TABLE secret_data (id INTEGER PRIMARY KEY, value TEXT)"
|
||||
)
|
||||
|
||||
noexec_db = ds.add_memory_database("editor_noexec_db")
|
||||
await noexec_db.execute_write(
|
||||
"CREATE TABLE locked (id INTEGER PRIMARY KEY, value TEXT)"
|
||||
)
|
||||
|
||||
await ds.invoke_startup()
|
||||
await ds.refresh_schemas()
|
||||
return ds
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_allowed_shape(editor_schema_ds):
|
||||
"""Authorized fetch returns tables, columns, types and views in the
|
||||
documented neutral shape."""
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_public_db/-/editor-schema.json"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert data["database"] == "editor_public_db"
|
||||
assert isinstance(data["tables"], list)
|
||||
|
||||
by_name = {t["name"]: t for t in data["tables"]}
|
||||
|
||||
# Regular table with columns + declared types
|
||||
users = by_name["users"]
|
||||
assert users["view"] is False
|
||||
assert users["columns"] == [
|
||||
{"name": "id", "type": "INTEGER"},
|
||||
{"name": "name", "type": "TEXT"},
|
||||
]
|
||||
|
||||
posts = by_name["posts"]
|
||||
assert posts["view"] is False
|
||||
assert {c["name"] for c in posts["columns"]} == {"id", "title", "body"}
|
||||
|
||||
# View is flagged and carries its real columns
|
||||
view = by_name["recent_posts"]
|
||||
assert view["view"] is True
|
||||
assert [c["name"] for c in view["columns"]] == ["id", "title"]
|
||||
|
||||
# Whole payload is JSON-serializable and every entry matches the shape
|
||||
for table in data["tables"]:
|
||||
assert set(table) == {"name", "view", "columns"}
|
||||
for column in table["columns"]:
|
||||
assert set(column) == {"name", "type"}
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_excludes_hidden_tables(editor_schema_ds):
|
||||
"""FTS shadow tables (hidden_table_names) must not appear."""
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_public_db/-/editor-schema.json"
|
||||
)
|
||||
assert response.status_code == 200
|
||||
names = {t["name"] for t in response.json()["tables"]}
|
||||
assert not any("_fts_" in name or name.endswith("_fts") for name in names), names
|
||||
# Sanity: the visible objects are still there
|
||||
assert {"users", "posts", "recent_posts"} <= names
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_denied_view_database_403_no_leak(editor_schema_ds):
|
||||
"""Anonymous user lacking view-database gets a 403 that leaks no names."""
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_private_db/-/editor-schema.json"
|
||||
)
|
||||
assert response.status_code == 403
|
||||
body = response.text
|
||||
assert "secret_data" not in body
|
||||
data = response.json()
|
||||
assert data["ok"] is False
|
||||
assert "secret_data" not in json.dumps(data)
|
||||
|
||||
# The permitted actor can read it
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_private_db/-/editor-schema.json", actor={"id": "root"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
names = {t["name"] for t in response.json()["tables"]}
|
||||
assert "secret_data" in names
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_denied_execute_sql_403_no_leak(editor_schema_ds):
|
||||
"""A viewer who lacks execute-sql gets a 403 with no schema data."""
|
||||
# Anonymous user may view editor_noexec_db but not run SQL against it
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_noexec_db/-/editor-schema.json"
|
||||
)
|
||||
assert response.status_code == 403
|
||||
data = response.json()
|
||||
assert data["ok"] is False
|
||||
assert "tables" not in data
|
||||
assert "locked" not in json.dumps(data)
|
||||
|
||||
# The actor granted execute-sql can read the schema
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/editor_noexec_db/-/editor-schema.json", actor={"id": "root"}
|
||||
)
|
||||
assert response.status_code == 200
|
||||
names = {t["name"] for t in response.json()["tables"]}
|
||||
assert "locked" in names
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_editor_schema_database_not_found(editor_schema_ds):
|
||||
"""A non-existent database returns a 404 JSON error."""
|
||||
response = await editor_schema_ds.client.get(
|
||||
"/nonexistent_db/-/editor-schema.json"
|
||||
)
|
||||
assert response.status_code == 404
|
||||
data = response.json()
|
||||
assert data["ok"] is False
|
||||
assert "not found" in data["error"].lower()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue