From a03adfd7a1582cf902770e04ab7842e823542cd1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Apr 2022 23:19:07 +0530 Subject: [PATCH 001/108] build(deps): bump minimist (#104) Bumps [minimist](https://github.com/substack/minimist) from 1.2.5 to 1.2.6. - [Release notes](https://github.com/substack/minimist/releases) - [Commits](https://github.com/substack/minimist/compare/1.2.5...1.2.6) --- updated-dependencies: - dependency-name: minimist dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../samples/express-opentelemetry/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json index b8eef198..f4eff450 100644 --- a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json @@ -2688,9 +2688,9 @@ } }, "node_modules/minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "node_modules/minipass": { "version": "2.9.0", @@ -6509,9 +6509,9 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" }, "minipass": { "version": "2.9.0", From 7ea8c4bd5eaaf3007dd2b057647e19b08d24210e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Apr 2022 23:20:42 +0530 Subject: [PATCH 002/108] build(deps): bump node-fetch (#109) Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7. - [Release notes](https://github.com/node-fetch/node-fetch/releases) - [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7) --- updated-dependencies: - dependency-name: node-fetch dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../express-opentelemetry/package-lock.json | 64 +++++++++++++++++-- 1 file changed, 58 insertions(+), 6 deletions(-) diff --git a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json index f4eff450..0b62556f 100644 --- a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json @@ -2830,11 +2830,22 @@ } }, "node_modules/node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dependencies": { + "whatwg-url": "^5.0.0" + }, "engines": { "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } } }, "node_modules/node-forge": { @@ -4242,6 +4253,11 @@ "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -4411,6 +4427,20 @@ "node": ">=6.0.0" } }, + "node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", @@ -6631,9 +6661,12 @@ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==" }, "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==" + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "requires": { + "whatwg-url": "^5.0.0" + } }, "node-forge": { "version": "0.10.0", @@ -7729,6 +7762,11 @@ "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=" }, + "tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=" + }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -7855,6 +7893,20 @@ "resolved": "https://registry.npmjs.org/walkdir/-/walkdir-0.4.1.tgz", "integrity": "sha512-3eBwRyEln6E1MSzcxcVpQIhRG8Q1jLvEqRmCZqS3dsfXEDR/AhOF4d+jHg1qvDCpYaVRZjENPQyrVxAkQqxPgQ==" }, + "webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha1-JFNCdeKnvGvnvIZhHMFq4KVlSHE=" + }, + "whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha1-lmRU6HZUYuN2RNNib2dCzotwll0=", + "requires": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "which": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", From 181a4c6f2ff64e81cb40a6edec51229a6879789c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 7 Apr 2022 23:21:41 +0530 Subject: [PATCH 003/108] build(deps): bump lodash (#111) Bumps [lodash](https://github.com/lodash/lodash) from 4.17.20 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.20...4.17.21) --- updated-dependencies: - dependency-name: lodash dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../samples/express-opentelemetry/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json index 0b62556f..fe4b74d3 100644 --- a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json @@ -2534,9 +2534,9 @@ } }, "node_modules/lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "node_modules/lodash.camelcase": { "version": "4.3.0", @@ -6424,9 +6424,9 @@ } }, "lodash": { - "version": "4.17.20", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.20.tgz", - "integrity": "sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.camelcase": { "version": "4.3.0", From e1d9a49b118410015010d8ab39dcd3336a46f7d7 Mon Sep 17 00:00:00 2001 From: Jose Luis Navarro Date: Tue, 12 Apr 2022 11:27:45 +0200 Subject: [PATCH 004/108] Add FastAPI support with an ASGI Middleware (#105) * Add FastAPI support with an ASGI Middleware * Fix PR comments --- python/sqlcommenter-python/README.md | 14 +++ .../google/cloud/sqlcommenter/fastapi.py | 99 +++++++++++++++++++ .../cloud/sqlcommenter/sqlalchemy/executor.py | 9 +- python/sqlcommenter-python/setup.py | 1 + .../tests/fastapi/__init__.py | 0 .../sqlcommenter-python/tests/fastapi/app.py | 29 ++++++ .../tests/fastapi/tests.py | 55 +++++++++++ .../tests/sqlalchemy/tests.py | 35 +++++++ 8 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py create mode 100644 python/sqlcommenter-python/tests/fastapi/__init__.py create mode 100644 python/sqlcommenter-python/tests/fastapi/app.py create mode 100644 python/sqlcommenter-python/tests/fastapi/tests.py diff --git a/python/sqlcommenter-python/README.md b/python/sqlcommenter-python/README.md index 306b25d3..ae9887fb 100644 --- a/python/sqlcommenter-python/README.md +++ b/python/sqlcommenter-python/README.md @@ -85,6 +85,20 @@ traceparent='00-5bd66ef5095369c7b0d1f8f4bd33716a-c532cb4098ac3dd2-01', tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/ ``` +#### FastAPI + +If you are using SQLAlchemy with FastAPI, add the middleware to get: framework, app_name, controller and route. + +```python +from fastapi import FastAPI +from google.cloud.sqlcommenter.fastapi import SQLCommenterMiddleware + +app = FastAPI() + +app.add_middleware(SQLCommenterMiddleware) +``` + + ### Psycopg2 Use the provided cursor factory to generate database cursors. All queries executed with such cursors will have the SQL comment prepended to them. diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py new file mode 100644 index 00000000..3013492a --- /dev/null +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py @@ -0,0 +1,99 @@ +#!/usr/bin/python +# +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import absolute_import + +try: + from typing import Optional + from asgiref.compatibility import guarantee_single_callable + from contextvars import ContextVar + import fastapi + from fastapi import FastAPI + from starlette.routing import Match, Route +except ImportError: + fastapi = None + +context = ContextVar("context", default={}) + + +def get_fastapi_info(): + """ + Get available info from the current FastAPI request, if we're in a + FastAPI request-response cycle. Else, return an empty dict. + """ + info = {} + if fastapi and context: + info = context.get() + return info + + +class SQLCommenterMiddleware: + """The ASGI application middleware. + This class is an ASGI middleware that augment SQL statements before execution, + with comments containing information about the code that caused its execution. + + Args: + app: The ASGI application callable to forward requests to. + """ + + def __init__(self, app): + self.app = guarantee_single_callable(app) + + async def __call__(self, scope, receive, send): + """The ASGI application + Args: + scope: An ASGI environment. + receive: An awaitable callable yielding dictionaries + send: An awaitable callable taking a single dictionary as argument. + """ + if scope["type"] not in ("http", "websocket"): + return await self.app(scope, receive, send) + + if not isinstance(scope["app"], FastAPI): + return await self.app(scope, receive, send) + + fastapi_app = scope["app"] + info = _get_fastapi_info(fastapi_app, scope) + token = context.set(info) + + try: + await self.app(scope, receive, send) + finally: + context.reset(token) + + +def _get_fastapi_info(fastapi_app: FastAPI, scope) -> dict: + info = { + "framework": 'fastapi:%s' % fastapi.__version__, + "app_name": fastapi_app.title, + } + + route = _get_fastapi_route(fastapi_app, scope) + if route: + info["controller"] = route.name + info["route"] = route.path + + return info + + +def _get_fastapi_route(fastapi_app: FastAPI, scope) -> Optional[Route]: + for route in fastapi_app.router.routes: + # Determine if any route matches the incoming scope, + # and return the route name if found. + match, child_scope = route.matches(scope) + if match == Match.FULL: + return child_scope["route"] + return None diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py index 6dec675f..9b0b962a 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py @@ -22,6 +22,7 @@ import sqlalchemy from google.cloud.sqlcommenter import generate_sql_comment +from google.cloud.sqlcommenter.fastapi import get_fastapi_info from google.cloud.sqlcommenter.flask import get_flask_info from google.cloud.sqlcommenter.opencensus import get_opencensus_values from google.cloud.sqlcommenter.opentelemetry import get_opentelemetry_values @@ -42,6 +43,12 @@ def BeforeExecuteFactory( 'db_framework': with_db_framework, } + def get_framework_info(): + info = get_flask_info() + if not info: + info = get_fastapi_info() + return info + def before_cursor_execute(conn, cursor, sql, parameters, context, executemany): data = dict( # TODO: Figure out how to retrieve the exact driver version. @@ -54,7 +61,7 @@ def before_cursor_execute(conn, cursor, sql, parameters, context, executemany): # folks using it in a web framework such as flask will # use it in unison with flask but initialize the parts disjointly, # unlike Django which uses ORMs directly as part of the framework. - data.update(get_flask_info()) + data.update(get_framework_info()) # Filter down to just the requested attributes. data = {k: v for k, v in data.items() if attributes.get(k)} diff --git a/python/sqlcommenter-python/setup.py b/python/sqlcommenter-python/setup.py index 1dbbe5ef..392acea4 100644 --- a/python/sqlcommenter-python/setup.py +++ b/python/sqlcommenter-python/setup.py @@ -37,6 +37,7 @@ def read_file(filename): extras_require={ 'django': ['django >= 1.11'], 'flask': ['flask'], + 'fastapi': ['fastapi'], 'psycopg2': ['psycopg2'], 'sqlalchemy': ['sqlalchemy'], 'opencensus': ['opencensus'], diff --git a/python/sqlcommenter-python/tests/fastapi/__init__.py b/python/sqlcommenter-python/tests/fastapi/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/python/sqlcommenter-python/tests/fastapi/app.py b/python/sqlcommenter-python/tests/fastapi/app.py new file mode 100644 index 00000000..e699ba46 --- /dev/null +++ b/python/sqlcommenter-python/tests/fastapi/app.py @@ -0,0 +1,29 @@ +from typing import Optional + +from fastapi import FastAPI, status +from fastapi.responses import JSONResponse +from starlette.exceptions import HTTPException as StarletteHTTPException + +from google.cloud.sqlcommenter.fastapi import SQLCommenterMiddleware, get_fastapi_info + +app = FastAPI(title="SQLCommenter") + +app.add_middleware(SQLCommenterMiddleware) + + +@app.get("/fastapi-info") +def fastapi_info(): + return get_fastapi_info() + + +@app.get("/items/{item_id}") +def read_item(item_id: int, q: Optional[str] = None): + return get_fastapi_info() + + +@app.exception_handler(StarletteHTTPException) +async def custom_http_exception_handler(request, exc): + return JSONResponse( + status_code=status.HTTP_404_NOT_FOUND, + content=get_fastapi_info(), + ) diff --git a/python/sqlcommenter-python/tests/fastapi/tests.py b/python/sqlcommenter-python/tests/fastapi/tests.py new file mode 100644 index 00000000..1c586e98 --- /dev/null +++ b/python/sqlcommenter-python/tests/fastapi/tests.py @@ -0,0 +1,55 @@ +#!/usr/bin/python +# +# Copyright 2019 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import json + +import fastapi +import pytest +from starlette.testclient import TestClient + +from google.cloud.sqlcommenter.fastapi import get_fastapi_info + +from .app import app + + +@pytest.fixture +def client(): + client = TestClient(app) + yield client + + +def test_get_fastapi_info_in_request_context(client): + expected = { + 'app_name': 'SQLCommenter', + 'controller': 'fastapi_info', + 'framework': 'fastapi:%s' % fastapi.__version__, + 'route': '/fastapi-info', + } + resp = client.get('/fastapi-info') + assert json.loads(resp.content.decode('utf-8')) == expected + + +def test_get_fastapi_info_in_404_error_context(client): + expected = { + 'app_name': 'SQLCommenter', + 'framework': 'fastapi:%s' % fastapi.__version__, + } + resp = client.get('/doesnt-exist') + assert json.loads(resp.content.decode('utf-8')) == expected + + +def test_get_fastapi_info_outside_request_context(client): + assert get_fastapi_info() == {} diff --git a/python/sqlcommenter-python/tests/sqlalchemy/tests.py b/python/sqlcommenter-python/tests/sqlalchemy/tests.py index 73d33d9c..c92b0b3c 100644 --- a/python/sqlcommenter-python/tests/sqlalchemy/tests.py +++ b/python/sqlcommenter-python/tests/sqlalchemy/tests.py @@ -126,3 +126,38 @@ def test_route_disabled(self, get_info): "SELECT 1; /*controller='c',framework='flask'*/", with_route=False, ) + + +class FastAPITests(SQLAlchemyTestCase): + fastapi_info = { + 'framework': 'fastapi', + 'controller': 'c', + 'route': '/', + } + + @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) + def test_all_data(self, get_info): + self.assertSQL( + "SELECT 1; /*controller='c',framework='fastapi',route='/'*/", + ) + + @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) + def test_framework_disabled(self, get_info): + self.assertSQL( + "SELECT 1; /*controller='c',route='/'*/", + with_framework=False, + ) + + @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) + def test_controller_disabled(self, get_info): + self.assertSQL( + "SELECT 1; /*framework='fastapi',route='/'*/", + with_controller=False, + ) + + @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) + def test_route_disabled(self, get_info): + self.assertSQL( + "SELECT 1; /*controller='c',framework='fastapi'*/", + with_route=False, + ) \ No newline at end of file From e790cbfc89cfdd5797b991269e151cd25e7f7316 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 22 Apr 2022 14:27:37 +0530 Subject: [PATCH 005/108] Laravel SQLCommenter (#113) Initial checkin of laravel-sqlcommenter (PHP). This PR contains the library code, few utilities and unit tests for utilities. In the next set of PRs, integration tests will be added. --- README.md | 2 + .../packages/sqlcommenter-laravel/README.md | 45 ++++++ .../sqlcommenter-laravel/composer.json | 37 +++++ .../src/Database/Connection.php | 137 +++++++++++++++++ .../src/Database/DatabaseServiceProvider.php | 48 ++++++ .../src/Database/MySqlConnection.php | 106 ++++++++++++++ .../src/Database/PostgresConnection.php | 95 ++++++++++++ .../src/Database/SQLiteConnection.php | 130 +++++++++++++++++ .../src/Database/SqlServerConnection.php | 138 ++++++++++++++++++ .../src/GoogleSqlCommenterServiceProvider.php | 49 +++++++ .../src/Opentelemetry.php | 32 ++++ .../sqlcommenter-laravel/src/Utils.php | 50 +++++++ .../src/config/google_sqlcommenter.php | 18 +++ .../tests/Unit/UtilsTest.php | 35 +++++ 14 files changed, 922 insertions(+) create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/DatabaseServiceProvider.php create mode 100755 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/MySqlConnection.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/PostgresConnection.php create mode 100755 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SQLiteConnection.php create mode 100755 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SqlServerConnection.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/GoogleSqlCommenterServiceProvider.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Opentelemetry.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/src/config/google_sqlcommenter.php create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php diff --git a/README.md b/README.md index 71662319..c885873e 100644 --- a/README.md +++ b/README.md @@ -16,3 +16,5 @@ Contains all the various `sqlcommenter-*` implementations. - [X] [Node.js](nodejs/sqlcommenter-nodejs/README.md) - [X] [Knex.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/README.md) - [X] [Sequelize.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/README.md) +- [X] Php + - [X] [Laravel](php/sqlcommenter-php/packages/sqlcommenter-laravel) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md new file mode 100644 index 00000000..47a5aa72 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md @@ -0,0 +1,45 @@ +# sqlcommenter-laravel [In Development] + +sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel +with comments that can be used later to correlate user code with SQL statements. + + +### Installation + +Add this to your composer.json +```shell +"repositories": [ + { + "type": "path", + "url": "/full/or/relative/path/to/sqlcommenter-laravel/package" + } +] +``` +Install the package +```shell +composer require "google/sqlcommenter-laravel" +``` +### Usage + +Publish the config file from library to into laravel app using below command + +```shell +php artisan vendor:publish --provider="google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" +``` + +Add the following class above ``Illuminate\Database\DatabaseServiceProvider::class, +`` in config/app.php +```php +'providers' => [ + ... + Google\GoogleSqlCommenterLaravel\Database\DatabaseServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + ... +] +``` +### Run the tests + +Run the tests using below command +```shell +./vendor/bin/phpunit tests +``` diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json b/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json new file mode 100644 index 00000000..1e2fbd07 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json @@ -0,0 +1,37 @@ +{ + "name": "google/sqlcommenter-laravel", + "description": "Laravel middleware to send events to OpenTelemetry", + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Google Developers", + "email": "sqlcommenter@googlegroups.com", + "role": "Developer" + }], + "require": { + "open-telemetry/opentelemetry": "~0.0.9", + "php-http/guzzle7-adapter": "^1.0" + }, + "autoload": { + "psr-4": { + "Google\\GoogleSqlCommenterLaravel\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "extra": { + "laravel": { + "providers": [ + "Google\\GoogleSqlCommenterLaravel\\GoogleSqlCommenterServiceProvider" + ] + } + }, + "scripts": { + "format": "phpcbf --standard=psr2 src/" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php new file mode 100644 index 00000000..c1d95c72 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php @@ -0,0 +1,137 @@ +getSqlComments(); + $records = parent::select($query, $bindings, $useReadPdo); + + if (count($records) > 0) { + return $records; + } + return null; + } + + /** + * Run a select statement against the database. + * + * @param string $query + * @param array $bindings + * @param bool $useReadPdo + * @return array + */ + public function select($query, $bindings = [], $useReadPdo = true) + { + $query .= $this->getSqlComments(); + $records = parent::select($query, $bindings, $useReadPdo); + return $records; + } + + /** + * Run an insert statement against the database. + * + * @param string $query + * @param array $bindings + * @return bool + */ + public function insert($query, $bindings = []) + { + $query .= $this->getSqlComments(); + + $records = parent::insert($query, $bindings); + + return $records; + } + + /** + * Run an update statement against the database. + * + * @param string $query + * @param array $bindings + * @return int + */ + public function update($query, $bindings = []) + { + $query .= $this->getSqlComments(); + + return $this->affectingStatement($query, $bindings); + } + + /** + * Run a delete statement against the database. + * + * @param string $query + * @param array $bindings + * @return int + */ + public function delete($query, $bindings = []) + { + $query .= $this->getSqlComments(); + + return $this->affectingStatement($query, $bindings); + } + + private function getSqlComments() + { + $configurationKey = 'google_sqlcommenter.include.'; + $comment = []; + $action = null; + + if (!empty(app('request')->route())) { + $action = app('request')->route()->getAction(); + } + if (config($configurationKey . 'framework', true)) { + $comment['framework'] = "laravel-" . app()->version(); + } + if (config($configurationKey . 'controller', true) and !empty($action['controller'])) { + $comment['controller'] = explode("@", class_basename($action['controller']))[0]; + } + if (config($configurationKey . 'action', true) and !empty($action['controller'] and str_contains($action['controller'], '@'))) { + $comment['action'] = explode("@", class_basename($action['controller']))[1]; + } + if (config($configurationKey . 'route', true)) { + $comment['route'] = request()->getRequestUri(); + } + if (config($configurationKey . 'db_driver', true)) { + $connection = config('database.default'); + $comment['db_driver'] = config("database.connections.{$connection}.driver"); + } + if (config($configurationKey . 'opentelemetry', true)) { + $carrier = Opentelemetry::getOpentelemetryValues(); + $comment = array_merge($comment, $carrier); + } + return Utils::formatComments(array_filter(($comment))); + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/DatabaseServiceProvider.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/DatabaseServiceProvider.php new file mode 100644 index 00000000..a01f0482 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/DatabaseServiceProvider.php @@ -0,0 +1,48 @@ +getPdo()->getAttribute(PDO::ATTR_SERVER_VERSION), 'MariaDB'); + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\MySqlGrammar + */ + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\MySqlBuilder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new MySqlBuilder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\MySqlGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the schema state for the connection. + * + * @param \Illuminate\Filesystem\Filesystem|null $files + * @param callable|null $processFactory + * @return \Illuminate\Database\Schema\MySqlSchemaState + */ + public function getSchemaState(Filesystem $files = null, callable $processFactory = null) + { + return new MySqlSchemaState($this, $files, $processFactory); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\MySqlProcessor + */ + protected function getDefaultPostProcessor() + { + return new MySqlProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Illuminate\Database\PDO\MySqlDriver + */ + protected function getDoctrineDriver() + { + return new MySqlDriver; + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/PostgresConnection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/PostgresConnection.php new file mode 100644 index 00000000..d1564ffe --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/PostgresConnection.php @@ -0,0 +1,95 @@ +withTablePrefix(new QueryGrammar); + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\PostgresBuilder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new PostgresBuilder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\PostgresGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the schema state for the connection. + * + * @param \Illuminate\Filesystem\Filesystem|null $files + * @param callable|null $processFactory + * @return \Illuminate\Database\Schema\PostgresSchemaState + */ + public function getSchemaState(Filesystem $files = null, callable $processFactory = null) + { + return new PostgresSchemaState($this, $files, $processFactory); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\PostgresProcessor + */ + protected function getDefaultPostProcessor() + { + return new PostgresProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Illuminate\Database\PDO\PostgresDriver + */ + protected function getDoctrineDriver() + { + return new PostgresDriver; + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SQLiteConnection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SQLiteConnection.php new file mode 100755 index 00000000..30c249b8 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SQLiteConnection.php @@ -0,0 +1,130 @@ +getForeignKeyConstraintsConfigurationValue(); + + if ($enableForeignKeyConstraints === null) { + return; + } + + $enableForeignKeyConstraints + ? $this->getSchemaBuilder()->enableForeignKeyConstraints() + : $this->getSchemaBuilder()->disableForeignKeyConstraints(); + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\SQLiteGrammar + */ + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\SQLiteBuilder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new SQLiteBuilder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\SQLiteGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the schema state for the connection. + * + * @param \Illuminate\Filesystem\Filesystem|null $files + * @param callable|null $processFactory + * + * @throws \RuntimeException + */ + public function getSchemaState(Filesystem $files = null, callable $processFactory = null) + { + return new SqliteSchemaState($this, $files, $processFactory); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\SQLiteProcessor + */ + protected function getDefaultPostProcessor() + { + return new SQLiteProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Illuminate\Database\PDO\SQLiteDriver + */ + protected function getDoctrineDriver() + { + return new SQLiteDriver; + } + + /** + * Get the database connection foreign key constraints configuration option. + * + * @return bool|null + */ + protected function getForeignKeyConstraintsConfigurationValue() + { + return $this->getConfig('foreign_key_constraints'); + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SqlServerConnection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SqlServerConnection.php new file mode 100755 index 00000000..9ed3a06f --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/SqlServerConnection.php @@ -0,0 +1,138 @@ +getDriverName() === 'sqlsrv') { + return parent::transaction($callback); + } + + $this->getPdo()->exec('BEGIN TRAN'); + + // We'll simply execute the given callback within a try / catch block + // and if we catch any exception we can rollback the transaction + // so that none of the changes are persisted to the database. + try { + $result = $callback($this); + + $this->getPdo()->exec('COMMIT TRAN'); + } + + // If we catch an exception, we will rollback so nothing gets messed + // up in the database. Then we'll re-throw the exception so it can + // be handled how the developer sees fit for their applications. + catch (Throwable $e) { + $this->getPdo()->exec('ROLLBACK TRAN'); + + throw $e; + } + + return $result; + } + } + + /** + * Get the default query grammar instance. + * + * @return \Illuminate\Database\Query\Grammars\SqlServerGrammar + */ + protected function getDefaultQueryGrammar() + { + return $this->withTablePrefix(new QueryGrammar); + } + + /** + * Get a schema builder instance for the connection. + * + * @return \Illuminate\Database\Schema\SqlServerBuilder + */ + public function getSchemaBuilder() + { + if (is_null($this->schemaGrammar)) { + $this->useDefaultSchemaGrammar(); + } + + return new SqlServerBuilder($this); + } + + /** + * Get the default schema grammar instance. + * + * @return \Illuminate\Database\Schema\Grammars\SqlServerGrammar + */ + protected function getDefaultSchemaGrammar() + { + return $this->withTablePrefix(new SchemaGrammar); + } + + /** + * Get the schema state for the connection. + * + * @param \Illuminate\Filesystem\Filesystem|null $files + * @param callable|null $processFactory + * + * @throws \RuntimeException + */ + public function getSchemaState(Filesystem $files = null, callable $processFactory = null) + { + throw new RuntimeException('Schema dumping is not supported when using SQL Server.'); + } + + /** + * Get the default post processor instance. + * + * @return \Illuminate\Database\Query\Processors\SqlServerProcessor + */ + protected function getDefaultPostProcessor() + { + return new SqlServerProcessor; + } + + /** + * Get the Doctrine DBAL driver. + * + * @return \Illuminate\Database\PDO\SqlServerDriver + */ + protected function getDoctrineDriver() + { + return new SqlServerDriver; + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/GoogleSqlCommenterServiceProvider.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/GoogleSqlCommenterServiceProvider.php new file mode 100644 index 00000000..644bd179 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/GoogleSqlCommenterServiceProvider.php @@ -0,0 +1,49 @@ +publishes([ + __DIR__ . '/config/google_sqlcommenter.php' => config_path('google_sqlcommenter.php') + ]); + + $this->mergeConfigFrom( + __DIR__ . '/config/google_sqlcommenter.php', + 'google_sqlcommenter' + ); + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Opentelemetry.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Opentelemetry.php new file mode 100644 index 00000000..b793c487 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Opentelemetry.php @@ -0,0 +1,32 @@ +inject($carrier); + return $carrier; + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php new file mode 100644 index 00000000..1931d151 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php @@ -0,0 +1,50 @@ + $value) { + if ($key == $lastElement) { + $sql_comment .= Utils::customUrlEncode($key) . "=" . "'" . Utils::customUrlEncode($value) . "'*/"; + } else { + $sql_comment .= Utils::customUrlEncode($key) . "=" . "'" . Utils::customUrlEncode($value) . "',"; + } + } + return $sql_comment; + } + + private static function customUrlEncode($input) + { + $encodedString = urlencode($input); + + # Since SQL uses '%' as a keyword, '%' is a by-product of url quoting + # e.g. foo,bar --> foo%2Cbar + # thus in our quoting, we need to escape it too to finally give + # foo,bar --> foo%%2Cbar + + return str_replace("%", "%%", $encodedString); + } +} diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/config/google_sqlcommenter.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/config/google_sqlcommenter.php new file mode 100644 index 00000000..afda8bc3 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/config/google_sqlcommenter.php @@ -0,0 +1,18 @@ + [ + 'framework' => true, + 'controller' => true, + 'route' => true, + 'db_driver' => true, + 'opentelemetry' => true, + 'action' => true, + ] + +]; diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php new file mode 100644 index 00000000..51ed3e1a --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php @@ -0,0 +1,35 @@ +assertEquals("/*key1='value1',key2='value2'*/", Utils::formatComments(array("key1" => "value1", "key2" => "value2"))); + } + public function testFormatCommentsWithoutKeys(): void + { + $this->assertEquals("", Utils::formatComments(array())); + } + public function testFormatCommentsWithSpecialCharKeys(): void + { + $this->assertEquals("/*key1='value1%%40',key2='value2'*/", Utils::formatComments(array("key1" => "value1@", "key2" => "value2"))); + } +} From 73776c57fd512231af8fa499b29ed0893a232465 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Thu, 28 Apr 2022 23:21:23 +0530 Subject: [PATCH 006/108] Fix SQLCommenter comment addition before end of SQL statement delimiter (#112) --- .../cloud/sqlcommenter/psycopg2/extension.py | 7 ++++- .../tests/psycopg2/tests.py | 30 +++++++++---------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py index dd523a48..accce407 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py @@ -80,7 +80,12 @@ def execute(self, sql, args=None): if with_opentelemetry: data.update(get_opentelemetry_values()) - sql += generate_sql_comment(**data) + if len(data) != 0: + sql = sql.rstrip() + if sql[-1] == ';': + sql = sql[:-1] + generate_sql_comment(**data) + ';' + else: + sql = sql + generate_sql_comment(**data) return psycopg2.extensions.cursor.execute(self, sql, args) diff --git a/python/sqlcommenter-python/tests/psycopg2/tests.py b/python/sqlcommenter-python/tests/psycopg2/tests.py index 9d5a0232..022e2f3a 100644 --- a/python/sqlcommenter-python/tests/psycopg2/tests.py +++ b/python/sqlcommenter-python/tests/psycopg2/tests.py @@ -45,47 +45,47 @@ def test_no_args(self): def test_db_driver(self): self.assertSQL( - "SELECT 1; /*db_driver='psycopg2%%3A{}'*/".format(url_quote(psycopg2.__version__)), + "SELECT 1 /*db_driver='psycopg2%%3A{}'*/;".format(url_quote(psycopg2.__version__)), with_db_driver=True, ) def test_dbapi_threadsafety(self): self.assertSQL( - "SELECT 1; /*dbapi_threadsafety={}*/".format(psycopg2.threadsafety), + "SELECT 1 /*dbapi_threadsafety={}*/;".format(psycopg2.threadsafety), with_dbapi_threadsafety=True, ) def test_driver_paramstyle(self): self.assertSQL( - "SELECT 1; /*driver_paramstyle='{}'*/".format(psycopg2.paramstyle), + "SELECT 1 /*driver_paramstyle='{}'*/;".format(psycopg2.paramstyle), with_driver_paramstyle=True, ) def test_dbapi_level(self): self.assertSQL( - "SELECT 1; /*dbapi_level='{}'*/".format(url_quote(psycopg2.apilevel)), + "SELECT 1 /*dbapi_level='{}'*/;".format(url_quote(psycopg2.apilevel)), with_dbapi_level=True, ) def test_libpq_version(self): self.assertSQL( - "SELECT 1; /*libpq_version={}*/".format(url_quote(psycopg2.__libpq_version__)), + "SELECT 1 /*libpq_version={}*/;".format(url_quote(psycopg2.__libpq_version__)), with_libpq_version=True, ) def test_opencensus(self): with mock_opencensus_tracer(): self.assertSQL( - "SELECT 1; /*traceparent='00-trace%%20id-span%%20id-00'," - "tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/", + "SELECT 1 /*traceparent='00-trace%%20id-span%%20id-00'," + "tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/;", with_opencensus=True, ) def test_opentelemetry(self): with mock_opentelemetry_context(): self.assertSQL( - "SELECT 1; /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," - "tracestate='some_key%%3Dsome_value'*/", + "SELECT 1 /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," + "tracestate='some_key%%3Dsome_value'*/;", with_opentelemetry=True, ) @@ -94,8 +94,8 @@ def test_both_opentelemetry_and_opencensus_warn(self): "google.cloud.sqlcommenter.psycopg2.extension.logger" ) as logger_mock, mock_opencensus_tracer(), mock_opentelemetry_context(): self.assertSQL( - "SELECT 1; /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," - "tracestate='some_key%%3Dsome_value'*/", + "SELECT 1 /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," + "tracestate='some_key%%3Dsome_value'*/;", with_opentelemetry=True, with_opencensus=True, ) @@ -112,26 +112,26 @@ class FlaskTests(Psycopg2TestCase): @mock.patch('google.cloud.sqlcommenter.psycopg2.extension.get_flask_info', return_value=flask_info) def test_all_data(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='flask',route='/'*/", + "SELECT 1 /*controller='c',framework='flask',route='/'*/;", ) @mock.patch('google.cloud.sqlcommenter.psycopg2.extension.get_flask_info', return_value=flask_info) def test_framework_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',route='/'*/", + "SELECT 1 /*controller='c',route='/'*/;", with_framework=False, ) @mock.patch('google.cloud.sqlcommenter.psycopg2.extension.get_flask_info', return_value=flask_info) def test_controller_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*framework='flask',route='/'*/", + "SELECT 1 /*framework='flask',route='/'*/;", with_controller=False, ) @mock.patch('google.cloud.sqlcommenter.psycopg2.extension.get_flask_info', return_value=flask_info) def test_route_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='flask'*/", + "SELECT 1 /*controller='c',framework='flask'*/;", with_route=False, ) From 09d353b6e300dc01e418f00563c8a8f6ada67032 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Thu, 12 May 2022 19:29:14 +0530 Subject: [PATCH 007/108] Integration test for laravel using docker and githubworkflow (#119) This PR adds 1. Sample application, updates them to use sqlcommenter-php library and runs integration test on that. 2. Github workflows for unit and integration tests. --- .../workflows/laravel-integration-tests.yaml | 85 + .github/workflows/laravel-unit-tests.yaml | 53 + .gitignore | 2 + .phpunit.result.cache | 1 + .../packages/sqlcommenter-laravel/README.md | 3 +- .../src/Database/Connection.php | 27 +- .../sqlcommenter-laravel/.editorconfig | 18 + .../samples/sqlcommenter-laravel/.env.ci | 52 + .../samples/sqlcommenter-laravel/.env.example | 52 + .../sqlcommenter-laravel/.gitattributes | 10 + .../samples/sqlcommenter-laravel/.gitignore | 14 + .../samples/sqlcommenter-laravel/.styleci.yml | 12 + .../samples/sqlcommenter-laravel/README.md | 37 + .../app/Console/Kernel.php | 47 + .../app/Exceptions/Handler.php | 64 + .../app/Http/Controllers/Controller.php | 27 + .../app/Http/Controllers/RawDBController.php | 38 + .../app/Http/Controllers/UserController.php | 59 + .../sqlcommenter-laravel/app/Http/Kernel.php | 81 + .../app/Http/Middleware/Authenticate.php | 35 + .../app/Http/Middleware/EncryptCookies.php | 31 + .../PreventRequestsDuringMaintenance.php | 31 + .../Middleware/RedirectIfAuthenticated.php | 46 + .../app/Http/Middleware/TrimStrings.php | 33 + .../app/Http/Middleware/TrustHosts.php | 34 + .../app/Http/Middleware/TrustProxies.php | 42 + .../app/Http/Middleware/VerifyCsrfToken.php | 31 + .../sqlcommenter-laravel/app/Models/User.php | 58 + .../app/Providers/AppServiceProvider.php | 42 + .../app/Providers/AuthServiceProvider.php | 44 + .../Providers/BroadcastServiceProvider.php | 35 + .../app/Providers/EventServiceProvider.php | 56 + .../app/Providers/RouteServiceProvider.php | 66 + .../samples/sqlcommenter-laravel/artisan | 53 + .../sqlcommenter-laravel/bootstrap/app.php | 84 + .../bootstrap/cache/.gitignore | 2 + .../sqlcommenter-laravel/composer.json | 68 + .../sqlcommenter-laravel/composer.lock | 8409 +++++++++++++++++ .../sqlcommenter-laravel/config/app.php | 212 + .../sqlcommenter-laravel/config/auth.php | 125 + .../config/broadcasting.php | 81 + .../sqlcommenter-laravel/config/cache.php | 124 + .../sqlcommenter-laravel/config/cors.php | 48 + .../sqlcommenter-laravel/config/database.php | 165 + .../config/filesystems.php | 90 + .../sqlcommenter-laravel/config/hashing.php | 66 + .../sqlcommenter-laravel/config/logging.php | 133 + .../sqlcommenter-laravel/config/mail.php | 131 + .../sqlcommenter-laravel/config/queue.php | 107 + .../sqlcommenter-laravel/config/sanctum.php | 81 + .../sqlcommenter-laravel/config/services.php | 48 + .../sqlcommenter-laravel/config/session.php | 215 + .../sqlcommenter-laravel/config/view.php | 50 + .../sqlcommenter-laravel/database/.gitignore | 1 + .../database/factories/UserFactory.php | 56 + .../2014_10_12_000000_create_users_table.php | 36 + ...12_100000_create_password_resets_table.php | 32 + ..._08_19_000000_create_failed_jobs_table.php | 36 + ...01_create_personal_access_tokens_table.php | 36 + .../database/seeders/DatabaseSeeder.php | 33 + .../samples/sqlcommenter-laravel/lang/en.json | 7 + .../sqlcommenter-laravel/lang/en/auth.php | 34 + .../lang/en/pagination.php | 33 + .../lang/en/passwords.php | 36 + .../lang/en/validation.php | 176 + .../samples/sqlcommenter-laravel/package.json | 18 + .../samples/sqlcommenter-laravel/phpunit.xml | 31 + .../sqlcommenter-laravel/public/.htaccess | 21 + .../sqlcommenter-laravel/public/favicon.ico | 0 .../sqlcommenter-laravel/public/index.php | 69 + .../sqlcommenter-laravel/public/robots.txt | 2 + .../resources/css/app.css | 0 .../sqlcommenter-laravel/resources/js/app.js | 1 + .../resources/js/bootstrap.js | 28 + .../resources/views/welcome.blade.php | 132 + .../sqlcommenter-laravel/routes/api.php | 47 + .../sqlcommenter-laravel/routes/channels.php | 32 + .../sqlcommenter-laravel/routes/console.php | 33 + .../sqlcommenter-laravel/routes/web.php | 32 + .../storage/app/.gitignore | 3 + .../storage/app/public/.gitignore | 2 + .../storage/framework/.gitignore | 9 + .../storage/framework/cache/.gitignore | 3 + .../storage/framework/cache/data/.gitignore | 2 + .../storage/framework/sessions/.gitignore | 2 + .../storage/framework/testing/.gitignore | 2 + .../storage/framework/views/.gitignore | 2 + .../storage/logs/.gitignore | 2 + .../tests/CreatesApplication.php | 22 + .../tests/Feature/DBTest.php | 79 + .../tests/Feature/EloquentTest.php | 82 + .../sqlcommenter-laravel/tests/TestCase.php | 24 + .../sqlcommenter-laravel/webpack.mix.js | 17 + 93 files changed, 12760 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/laravel-integration-tests.yaml create mode 100644 .github/workflows/laravel-unit-tests.yaml create mode 100644 .gitignore create mode 100644 .phpunit.result.cache create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.editorconfig create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.ci create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.example create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitattributes create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/.styleci.yml create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Console/Kernel.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Exceptions/Handler.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/Controller.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/RawDBController.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/UserController.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Kernel.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/Authenticate.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/EncryptCookies.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/PreventRequestsDuringMaintenance.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/RedirectIfAuthenticated.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrimStrings.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustHosts.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustProxies.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/VerifyCsrfToken.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Models/User.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/AppServiceProvider.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/AuthServiceProvider.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/BroadcastServiceProvider.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/EventServiceProvider.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/RouteServiceProvider.php create mode 100755 php/sqlcommenter-php/samples/sqlcommenter-laravel/artisan create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/app.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/cache/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.json create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.lock create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/app.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/auth.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/broadcasting.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cache.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cors.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/database.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/filesystems.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/hashing.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/logging.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/mail.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/queue.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/sanctum.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/services.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/session.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/config/view.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/factories/UserFactory.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_000000_create_users_table.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_100000_create_password_resets_table.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_08_19_000000_create_failed_jobs_table.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/database/seeders/DatabaseSeeder.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en.json create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/auth.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/pagination.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/passwords.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/validation.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/package.json create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/phpunit.xml create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/public/.htaccess create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/public/favicon.ico create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/public/index.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/public/robots.txt create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/css/app.css create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/app.js create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/bootstrap.js create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/views/welcome.blade.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/api.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/channels.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/console.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/web.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/app/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/app/public/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/cache/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/cache/data/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/sessions/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/testing/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/framework/views/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/storage/logs/.gitignore create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/CreatesApplication.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/DBTest.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/EloquentTest.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/TestCase.php create mode 100644 php/sqlcommenter-php/samples/sqlcommenter-laravel/webpack.mix.js diff --git a/.github/workflows/laravel-integration-tests.yaml b/.github/workflows/laravel-integration-tests.yaml new file mode 100644 index 00000000..240fb949 --- /dev/null +++ b/.github/workflows/laravel-integration-tests.yaml @@ -0,0 +1,85 @@ +on: + push: + branches: + - master + paths: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + +name: Laravel Integration Tests +jobs: + phpunit: + runs-on: ubuntu-latest + container: + image: kirschbaumdevelopment/laravel-test-runner:8.0 + + services: + mysql: + image: mysql:8 + env: + MYSQL_ROOT_PASSWORD: password + MYSQL_DATABASE: test + ports: + - 33306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Get Composer Cache Directory + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Get yarn cache + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install composer dependencies + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: | + composer install --no-scripts + + - name: Prepare Laravel Application + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: | + cp .env.ci .env + php artisan key:generate + + - name: Install front-end dependencies + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: | + npm install + npm run dev + + - name: Apply migrations + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: | + php artisan migrate + + - name: Publish SQLCommenter Configurations + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: | + php artisan vendor:publish --provider="Google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" + + - name: Run Testsuite + working-directory: ./php/sqlcommenter-php/samples/sqlcommenter-laravel + run: vendor/bin/phpunit tests/ diff --git a/.github/workflows/laravel-unit-tests.yaml b/.github/workflows/laravel-unit-tests.yaml new file mode 100644 index 00000000..795efe54 --- /dev/null +++ b/.github/workflows/laravel-unit-tests.yaml @@ -0,0 +1,53 @@ +on: + push: + branches: + - master + paths: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + +name: Laravel Unit Tests +jobs: + phpunit: + runs-on: ubuntu-latest + container: + image: kirschbaumdevelopment/laravel-test-runner:8.0 + + steps: + - uses: actions/checkout@v1 + with: + fetch-depth: 1 + + - name: Get Composer Cache Directory + working-directory: ./php/sqlcommenter-php/packages/sqlcommenter-laravel + id: composer-cache + run: | + echo "::set-output name=dir::$(composer config cache-files-dir)" + + - uses: actions/cache@v1 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} + restore-keys: | + ${{ runner.os }}-composer- + + - name: Get yarn cache + working-directory: ./php/sqlcommenter-php/packages/sqlcommenter-laravel + id: yarn-cache + run: echo "::set-output name=dir::$(yarn cache dir)" + + - uses: actions/cache@v1 + with: + path: ${{ steps.yarn-cache.outputs.dir }} + key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }} + restore-keys: | + ${{ runner.os }}-yarn- + + - name: Install composer dependencies + working-directory: ./php/sqlcommenter-php/packages/sqlcommenter-laravel + run: | + composer install --no-scripts + + - name: Run Testsuite + working-directory: ./php/sqlcommenter-php/packages/sqlcommenter-laravel + run: vendor/bin/phpunit tests/ diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..cc3016a8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +php/sqlcommenter-php/packages/sqlcommenter-laravel/vendor/* +.idea/** \ No newline at end of file diff --git a/.phpunit.result.cache b/.phpunit.result.cache new file mode 100644 index 00000000..e3d7530d --- /dev/null +++ b/.phpunit.result.cache @@ -0,0 +1 @@ +{"version":1,"defects":{"UtilsTest::testFormatCommentsWithKeys":4,"UtilsTest::testFormatCommentsWithoutKeys":4,"UtilsTest::testFormatCommentsWithSpecialCharKeys":4},"times":{"Tests\\Unit\\ExampleTest::test_that_true_is_true":0,"UtilsTest::testFormatCommentsWithKeys":0,"UtilsTest::testFormatCommentsWithoutKeys":0,"UtilsTest::testFormatCommentsWithSpecialCharKeys":0}} \ No newline at end of file diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md index 47a5aa72..b99ea8e5 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md @@ -24,7 +24,8 @@ composer require "google/sqlcommenter-laravel" Publish the config file from library to into laravel app using below command ```shell -php artisan vendor:publish --provider="google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" +php artisan vendor:publish --provider="Google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" + ``` Add the following class above ``Illuminate\Database\DatabaseServiceProvider::class, diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php index c1d95c72..0914952e 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php @@ -35,7 +35,7 @@ class Connection extends BaseConnection */ public function selectOne($query, $bindings = [], $useReadPdo = true) { - $query .= $this->getSqlComments(); + $query = $this->getSqlComments($query); $records = parent::select($query, $bindings, $useReadPdo); if (count($records) > 0) { @@ -54,7 +54,7 @@ public function selectOne($query, $bindings = [], $useReadPdo = true) */ public function select($query, $bindings = [], $useReadPdo = true) { - $query .= $this->getSqlComments(); + $query = $this->getSqlComments($query); $records = parent::select($query, $bindings, $useReadPdo); return $records; } @@ -68,8 +68,7 @@ public function select($query, $bindings = [], $useReadPdo = true) */ public function insert($query, $bindings = []) { - $query .= $this->getSqlComments(); - + $query = $this->getSqlComments($query); $records = parent::insert($query, $bindings); return $records; @@ -84,8 +83,8 @@ public function insert($query, $bindings = []) */ public function update($query, $bindings = []) { - $query .= $this->getSqlComments(); - + $query = $this->getSqlComments($query); + return $this->affectingStatement($query, $bindings); } @@ -98,12 +97,13 @@ public function update($query, $bindings = []) */ public function delete($query, $bindings = []) { - $query .= $this->getSqlComments(); + + $query = $this->getSqlComments($query); return $this->affectingStatement($query, $bindings); } - private function getSqlComments() + private function getSqlComments($query) { $configurationKey = 'google_sqlcommenter.include.'; $comment = []; @@ -118,7 +118,7 @@ private function getSqlComments() if (config($configurationKey . 'controller', true) and !empty($action['controller'])) { $comment['controller'] = explode("@", class_basename($action['controller']))[0]; } - if (config($configurationKey . 'action', true) and !empty($action['controller'] and str_contains($action['controller'], '@'))) { + if (config($configurationKey . 'action', true) and !empty($action and $action['controller'] and str_contains($action['controller'], '@'))) { $comment['action'] = explode("@", class_basename($action['controller']))[1]; } if (config($configurationKey . 'route', true)) { @@ -132,6 +132,13 @@ private function getSqlComments() $carrier = Opentelemetry::getOpentelemetryValues(); $comment = array_merge($comment, $carrier); } - return Utils::formatComments(array_filter(($comment))); + + $query=trim($query); + + if ($query[-1] == ';'){ + return rtrim($query ,";"). Utils::formatComments(array_filter(($comment))). ';'; + } + return $query . Utils::formatComments(array_filter(($comment))); + } } diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.editorconfig b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.editorconfig new file mode 100644 index 00000000..1671c9b9 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.editorconfig @@ -0,0 +1,18 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +insert_final_newline = true +indent_style = space +indent_size = 4 +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false + +[*.{yml,yaml}] +indent_size = 2 + +[docker-compose.yml] +indent_size = 4 diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.ci b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.ci new file mode 100644 index 00000000..ac4294a4 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.ci @@ -0,0 +1,52 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY=base64:JqM8ZOydXLT3tcQRl+GPEWuEoCFnXNOZ51DgjoV6FfM= +APP_DEBUG=true +APP_URL=http://localhost + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=mysql +DB_PORT=3306 +DB_DATABASE=test +DB_USERNAME=root +DB_PASSWORD=password + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DISK=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.example b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.example new file mode 100644 index 00000000..9bb1bd7c --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.env.example @@ -0,0 +1,52 @@ +APP_NAME=Laravel +APP_ENV=local +APP_KEY= +APP_DEBUG=true +APP_URL=http://localhost + +LOG_CHANNEL=stack +LOG_DEPRECATIONS_CHANNEL=null +LOG_LEVEL=debug + +DB_CONNECTION=mysql +DB_HOST=127.0.0.1 +DB_PORT=3306 +DB_DATABASE=laravel +DB_USERNAME=root +DB_PASSWORD= + +BROADCAST_DRIVER=log +CACHE_DRIVER=file +FILESYSTEM_DISK=local +QUEUE_CONNECTION=sync +SESSION_DRIVER=file +SESSION_LIFETIME=120 + +MEMCACHED_HOST=127.0.0.1 + +REDIS_HOST=127.0.0.1 +REDIS_PASSWORD=null +REDIS_PORT=6379 + +MAIL_MAILER=smtp +MAIL_HOST=mailhog +MAIL_PORT=1025 +MAIL_USERNAME=null +MAIL_PASSWORD=null +MAIL_ENCRYPTION=null +MAIL_FROM_ADDRESS="hello@example.com" +MAIL_FROM_NAME="${APP_NAME}" + +AWS_ACCESS_KEY_ID= +AWS_SECRET_ACCESS_KEY= +AWS_DEFAULT_REGION=us-east-1 +AWS_BUCKET= +AWS_USE_PATH_STYLE_ENDPOINT=false + +PUSHER_APP_ID= +PUSHER_APP_KEY= +PUSHER_APP_SECRET= +PUSHER_APP_CLUSTER=mt1 + +MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" +MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitattributes b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitattributes new file mode 100644 index 00000000..510d9961 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitattributes @@ -0,0 +1,10 @@ +* text=auto + +*.blade.php diff=html +*.css diff=css +*.html diff=html +*.md diff=markdown +*.php diff=php + +/.github export-ignore +CHANGELOG.md export-ignore diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitignore b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitignore new file mode 100644 index 00000000..bc67a663 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.gitignore @@ -0,0 +1,14 @@ +/node_modules +/public/hot +/public/storage +/storage/*.key +/vendor +.env +.env.backup +.phpunit.result.cache +Homestead.json +Homestead.yaml +npm-debug.log +yarn-error.log +/.idea +/.vscode diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/.styleci.yml b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.styleci.yml new file mode 100644 index 00000000..79f63b44 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/.styleci.yml @@ -0,0 +1,12 @@ +php: + preset: laravel + disabled: + - no_unused_imports + finder: + not-name: + - index.php +js: + finder: + not-name: + - webpack.mix.js +css: true diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md new file mode 100644 index 00000000..59b1982c --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md @@ -0,0 +1,37 @@ +# sqlcommenter-laravel-sample + +sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel +with comments that can be used later to correlate user code with SQL statements. + +## Setup + +### Install Dependencies + +Install the required packages +```shell +composer install +``` +### Publish the config file + +Publish the config file from library to into laravel app using below command + +```shell +php artisan vendor:publish --provider="Google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" +``` +### Add .env file +Rename .env.example to .env and change to appropriate configs + +## Apply migrations +```shell +php artisan migrate +``` +### Run the server +```shell +php artisan serve +``` +### Run the tests + +Run the tests using below command +```shell +./vendor/bin/phpunit tests +``` diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Console/Kernel.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Console/Kernel.php new file mode 100644 index 00000000..a8d97835 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Console/Kernel.php @@ -0,0 +1,47 @@ +command('inspire')->hourly(); + } + + /** + * Register the commands for the application. + * + * @return void + */ + protected function commands() + { + $this->load(__DIR__.'/Commands'); + + require base_path('routes/console.php'); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Exceptions/Handler.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Exceptions/Handler.php new file mode 100644 index 00000000..a3f2459a --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Exceptions/Handler.php @@ -0,0 +1,64 @@ +, \Psr\Log\LogLevel::*> + */ + protected $levels = [ + // + ]; + + /** + * A list of the exception types that are not reported. + * + * @var array> + */ + protected $dontReport = [ + // + ]; + + /** + * A list of the inputs that are never flashed for validation exceptions. + * + * @var array + */ + protected $dontFlash = [ + 'current_password', + 'password', + 'password_confirmation', + ]; + + /** + * Register the exception handling callbacks for the application. + * + * @return void + */ + public function register() + { + $this->reportable(function (Throwable $e) { + // + }); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/Controller.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/Controller.php new file mode 100644 index 00000000..9a689453 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Controllers/Controller.php @@ -0,0 +1,27 @@ +name = 'john'; + $user_update->email ='contact_me@d.com'; + $user_update->password ='Password$3456'; + $user_update->save(); + return 'Success'; + } + + public function delete() + { + User::where('email', 'contact_me@d.com')->delete(); + return 'Success'; + } + + public function update() + { + User::where('email', 'contact_me@d.com')->update(["name" =>'johnny']); + return 'Success'; + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Kernel.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Kernel.php new file mode 100644 index 00000000..91a63499 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Kernel.php @@ -0,0 +1,81 @@ + + */ + protected $middleware = [ + // \App\Http\Middleware\TrustHosts::class, + \App\Http\Middleware\TrustProxies::class, + \Illuminate\Http\Middleware\HandleCors::class, + \App\Http\Middleware\PreventRequestsDuringMaintenance::class, + \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class, + \App\Http\Middleware\TrimStrings::class, + \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class, + ]; + + /** + * The application's route middleware groups. + * + * @var array> + */ + protected $middlewareGroups = [ + 'web' => [ + \App\Http\Middleware\EncryptCookies::class, + \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class, + \Illuminate\Session\Middleware\StartSession::class, + \Illuminate\View\Middleware\ShareErrorsFromSession::class, + \App\Http\Middleware\VerifyCsrfToken::class, + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + + 'api' => [ + // \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class, + 'throttle:api', + \Illuminate\Routing\Middleware\SubstituteBindings::class, + ], + ]; + + /** + * The application's route middleware. + * + * These middleware may be assigned to groups or used individually. + * + * @var array + */ + protected $routeMiddleware = [ + 'auth' => \App\Http\Middleware\Authenticate::class, + 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, + 'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class, + 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, + 'can' => \Illuminate\Auth\Middleware\Authorize::class, + 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, + 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, + 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, + 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, + 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/Authenticate.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/Authenticate.php new file mode 100644 index 00000000..64e2e958 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/Authenticate.php @@ -0,0 +1,35 @@ +expectsJson()) { + return route('login'); + } + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/EncryptCookies.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/EncryptCookies.php new file mode 100644 index 00000000..331f80b1 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/EncryptCookies.php @@ -0,0 +1,31 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/PreventRequestsDuringMaintenance.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/PreventRequestsDuringMaintenance.php new file mode 100644 index 00000000..81ed00ce --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/PreventRequestsDuringMaintenance.php @@ -0,0 +1,31 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/RedirectIfAuthenticated.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/RedirectIfAuthenticated.php new file mode 100644 index 00000000..3869423b --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/RedirectIfAuthenticated.php @@ -0,0 +1,46 @@ +check()) { + return redirect(RouteServiceProvider::HOME); + } + } + + return $next($request); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrimStrings.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrimStrings.php new file mode 100644 index 00000000..125444b4 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrimStrings.php @@ -0,0 +1,33 @@ + + */ + protected $except = [ + 'current_password', + 'password', + 'password_confirmation', + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustHosts.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustHosts.php new file mode 100644 index 00000000..72a99921 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustHosts.php @@ -0,0 +1,34 @@ + + */ + public function hosts() + { + return [ + $this->allSubdomainsOfApplicationUrl(), + ]; + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustProxies.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustProxies.php new file mode 100644 index 00000000..5e696a44 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/TrustProxies.php @@ -0,0 +1,42 @@ +|string|null + */ + protected $proxies; + + /** + * The headers that should be used to detect proxies. + * + * @var int + */ + protected $headers = + Request::HEADER_X_FORWARDED_FOR | + Request::HEADER_X_FORWARDED_HOST | + Request::HEADER_X_FORWARDED_PORT | + Request::HEADER_X_FORWARDED_PROTO | + Request::HEADER_X_FORWARDED_AWS_ELB; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/VerifyCsrfToken.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/VerifyCsrfToken.php new file mode 100644 index 00000000..ca4af1e3 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Http/Middleware/VerifyCsrfToken.php @@ -0,0 +1,31 @@ + + */ + protected $except = [ + // + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Models/User.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Models/User.php new file mode 100644 index 00000000..0e5753fc --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Models/User.php @@ -0,0 +1,58 @@ + + */ + protected $fillable = [ + 'name', + 'email', + 'password', + ]; + + /** + * The attributes that should be hidden for serialization. + * + * @var array + */ + protected $hidden = [ + 'password', + 'remember_token', + ]; + + /** + * The attributes that should be cast. + * + * @var array + */ + protected $casts = [ + 'email_verified_at' => 'datetime', + ]; +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/AppServiceProvider.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/AppServiceProvider.php new file mode 100644 index 00000000..103ebd90 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/AppServiceProvider.php @@ -0,0 +1,42 @@ + + */ + protected $policies = [ + // 'App\Models\Model' => 'App\Policies\ModelPolicy', + ]; + + /** + * Register any authentication / authorization services. + * + * @return void + */ + public function boot() + { + $this->registerPolicies(); + + // + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/BroadcastServiceProvider.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/BroadcastServiceProvider.php new file mode 100644 index 00000000..d239e38d --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/BroadcastServiceProvider.php @@ -0,0 +1,35 @@ +> + */ + protected $listen = [ + Registered::class => [ + SendEmailVerificationNotification::class, + ], + ]; + + /** + * Register any events for your application. + * + * @return void + */ + public function boot() + { + // + } + + /** + * Determine if events and listeners should be automatically discovered. + * + * @return bool + */ + public function shouldDiscoverEvents() + { + return false; + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/RouteServiceProvider.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/RouteServiceProvider.php new file mode 100644 index 00000000..f853d449 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/app/Providers/RouteServiceProvider.php @@ -0,0 +1,66 @@ +configureRateLimiting(); + + $this->routes(function () { + Route::middleware('api') + ->prefix('api') + ->group(base_path('routes/api.php')); + + Route::middleware('web') + ->group(base_path('routes/web.php')); + }); + } + + /** + * Configure the rate limiters for the application. + * + * @return void + */ + protected function configureRateLimiting() + { + RateLimiter::for('api', function (Request $request) { + return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip()); + }); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/artisan b/php/sqlcommenter-php/samples/sqlcommenter-laravel/artisan new file mode 100755 index 00000000..67a3329b --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/artisan @@ -0,0 +1,53 @@ +#!/usr/bin/env php +make(Illuminate\Contracts\Console\Kernel::class); + +$status = $kernel->handle( + $input = new Symfony\Component\Console\Input\ArgvInput, + new Symfony\Component\Console\Output\ConsoleOutput +); + +/* +|-------------------------------------------------------------------------- +| Shutdown The Application +|-------------------------------------------------------------------------- +| +| Once Artisan has finished running, we will fire off the shutdown events +| so that any final work may be done by the application before we shut +| down the process. This is the last thing to happen to the request. +| +*/ + +$kernel->terminate($input, $status); + +exit($status); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/app.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/app.php new file mode 100644 index 00000000..b63bf205 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/app.php @@ -0,0 +1,84 @@ +getTracer('io.opentelemetry.contrib.php'); + +$rootSpan = $tracer->spanBuilder('root')->startSpan(); +$rootSpan->activate(); + +$app = new Illuminate\Foundation\Application( + $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__) +); + +/* +|-------------------------------------------------------------------------- +| Bind Important Interfaces +|-------------------------------------------------------------------------- +| +| Next, we need to bind some important interfaces into the container so +| we will be able to resolve them when needed. The kernels serve the +| incoming requests to this application from both the web and CLI. +| +*/ + +$app->singleton( + Illuminate\Contracts\Http\Kernel::class, + App\Http\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Console\Kernel::class, + App\Console\Kernel::class +); + +$app->singleton( + Illuminate\Contracts\Debug\ExceptionHandler::class, + App\Exceptions\Handler::class +); + +/* +|-------------------------------------------------------------------------- +| Return The Application +|-------------------------------------------------------------------------- +| +| This script returns the application instance. The instance is given to +| the calling script so we can separate the building of the instances +| from the actual running of the application and sending responses. +| +*/ + +return $app; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/cache/.gitignore b/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/cache/.gitignore new file mode 100644 index 00000000..d6b7ef32 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/bootstrap/cache/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.json b/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.json new file mode 100644 index 00000000..b399c3f5 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.json @@ -0,0 +1,68 @@ +{ + "name": "laravel/laravel", + "type": "project", + "description": "The Laravel Framework.", + "keywords": ["framework", "laravel"], + "license": "MIT", + "require": { + "php": "^8.0.2", + "google/sqlcommenter-laravel": "dev-master", + "guzzlehttp/guzzle": "^7.2", + "laravel/framework": "^9.2", + "laravel/sanctum": "^2.14.1", + "laravel/tinker": "^2.7" + }, + "require-dev": { + "fakerphp/faker": "^1.9.1", + "laravel/sail": "^1.0.1", + "mockery/mockery": "^1.4.4", + "nunomaduro/collision": "^6.1", + "phpunit/phpunit": "^9.5.10", + "spatie/laravel-ignition": "^1.0" + }, + "autoload": { + "psr-4": { + "App\\": "app/", + "Database\\Factories\\": "database/factories/", + "Database\\Seeders\\": "database/seeders/" + } + }, + "autoload-dev": { + "psr-4": { + "Tests\\": "tests/" + } + }, + "scripts": { + "post-autoload-dump": [ + "Illuminate\\Foundation\\ComposerScripts::postAutoloadDump", + "@php artisan package:discover --ansi" + ], + "post-update-cmd": [ + "@php artisan vendor:publish --tag=laravel-assets --ansi --force" + ], + "post-root-package-install": [ + "@php -r \"file_exists('.env') || copy('.env.example', '.env');\"" + ], + "post-create-project-cmd": [ + "@php artisan key:generate --ansi" + ] + }, + "extra": { + "laravel": { + "dont-discover": [] + } + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, + "minimum-stability": "dev", + "prefer-stable": true, + "repositories": [ + { + "type": "path", + "url": "../../packages/sqlcommenter-laravel" + } + ] +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.lock b/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.lock new file mode 100644 index 00000000..b0ee1b3c --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/composer.lock @@ -0,0 +1,8409 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "5a068783010bebd4bcc7e8e3717431ab", + "packages": [ + { + "name": "brick/math", + "version": "0.9.3", + "source": { + "type": "git", + "url": "https://github.com/brick/math.git", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/brick/math/zipball/ca57d18f028f84f777b2168cd1911b0dee2343ae", + "reference": "ca57d18f028f84f777b2168cd1911b0dee2343ae", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^7.5.15 || ^8.5 || ^9.0", + "vimeo/psalm": "4.9.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "brick", + "math" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.9.3" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/brick/math", + "type": "tidelift" + } + ], + "time": "2021-08-15T20:50:18+00:00" + }, + { + "name": "dflydev/dot-access-data", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/dflydev/dflydev-dot-access-data.git", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dflydev/dflydev-dot-access-data/zipball/0992cc19268b259a39e86f296da5f0677841f42c", + "reference": "0992cc19268b259a39e86f296da5f0677841f42c", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.42", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.3", + "scrutinizer/ocular": "1.6.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^3.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Dflydev\\DotAccessData\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Dragonfly Development Inc.", + "email": "info@dflydev.com", + "homepage": "http://dflydev.com" + }, + { + "name": "Beau Simensen", + "email": "beau@dflydev.com", + "homepage": "http://beausimensen.com" + }, + { + "name": "Carlos Frutos", + "email": "carlos@kiwing.it", + "homepage": "https://github.com/cfrutos" + }, + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com" + } + ], + "description": "Given a deep data structure, access data by dot notation.", + "homepage": "https://github.com/dflydev/dflydev-dot-access-data", + "keywords": [ + "access", + "data", + "dot", + "notation" + ], + "support": { + "issues": "https://github.com/dflydev/dflydev-dot-access-data/issues", + "source": "https://github.com/dflydev/dflydev-dot-access-data/tree/v3.0.1" + }, + "time": "2021-08-13T13:06:58+00:00" + }, + { + "name": "doctrine/inflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/doctrine/inflector.git", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^8.2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "vimeo/psalm": "^4.10" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Benjamin Eberlei", + "email": "kontakt@beberlei.de" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.", + "homepage": "https://www.doctrine-project.org/projects/inflector.html", + "keywords": [ + "inflection", + "inflector", + "lowercase", + "manipulation", + "php", + "plural", + "singular", + "strings", + "uppercase", + "words" + ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:16:43+00:00" + }, + { + "name": "doctrine/lexer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-02-28T11:07:21+00:00" + }, + { + "name": "dragonmantank/cron-expression", + "version": "v3.3.1", + "source": { + "type": "git", + "url": "https://github.com/dragonmantank/cron-expression.git", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/dragonmantank/cron-expression/zipball/be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "reference": "be85b3f05b46c39bbc0d95f6c071ddff669510fa", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "webmozart/assert": "^1.0" + }, + "replace": { + "mtdowling/cron-expression": "^1.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-webmozart-assert": "^1.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Cron\\": "src/Cron/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Tankersley", + "email": "chris@ctankersley.com", + "homepage": "https://github.com/dragonmantank" + } + ], + "description": "CRON for PHP: Calculate the next or previous run date and determine if a CRON expression is due", + "keywords": [ + "cron", + "schedule" + ], + "support": { + "issues": "https://github.com/dragonmantank/cron-expression/issues", + "source": "https://github.com/dragonmantank/cron-expression/tree/v3.3.1" + }, + "funding": [ + { + "url": "https://github.com/dragonmantank", + "type": "github" + } + ], + "time": "2022-01-18T15:43:28+00:00" + }, + { + "name": "egulias/email-validator", + "version": "3.1.2", + "source": { + "type": "git", + "url": "https://github.com/egulias/EmailValidator.git", + "reference": "ee0db30118f661fb166bcffbf5d82032df484697" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ee0db30118f661fb166bcffbf5d82032df484697", + "reference": "ee0db30118f661fb166bcffbf5d82032df484697", + "shasum": "" + }, + "require": { + "doctrine/lexer": "^1.2", + "php": ">=7.2", + "symfony/polyfill-intl-idn": "^1.15" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.2", + "phpunit/phpunit": "^8.5.8|^9.3.3", + "vimeo/psalm": "^4" + }, + "suggest": { + "ext-intl": "PHP Internationalization Libraries are required to use the SpoofChecking validation" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Egulias\\EmailValidator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eduardo Gulias Davis" + } + ], + "description": "A library for validating emails against several RFCs", + "homepage": "https://github.com/egulias/EmailValidator", + "keywords": [ + "email", + "emailvalidation", + "emailvalidator", + "validation", + "validator" + ], + "support": { + "issues": "https://github.com/egulias/EmailValidator/issues", + "source": "https://github.com/egulias/EmailValidator/tree/3.1.2" + }, + "funding": [ + { + "url": "https://github.com/egulias", + "type": "github" + } + ], + "time": "2021-10-11T09:18:27+00:00" + }, + { + "name": "fruitcake/php-cors", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/fruitcake/php-cors.git", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/fruitcake/php-cors/zipball/58571acbaa5f9f462c9c77e911700ac66f446d4e", + "reference": "58571acbaa5f9f462c9c77e911700ac66f446d4e", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "symfony/http-foundation": "^4.4|^5.4|^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "phpunit/phpunit": "^9", + "squizlabs/php_codesniffer": "^3.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Fruitcake\\Cors\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fruitcake", + "homepage": "https://fruitcake.nl" + }, + { + "name": "Barryvdh", + "email": "barryvdh@gmail.com" + } + ], + "description": "Cross-origin resource sharing library for the Symfony HttpFoundation", + "homepage": "https://github.com/fruitcake/php-cors", + "keywords": [ + "cors", + "laravel", + "symfony" + ], + "support": { + "issues": "https://github.com/fruitcake/php-cors/issues", + "source": "https://github.com/fruitcake/php-cors/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://fruitcake.nl", + "type": "custom" + }, + { + "url": "https://github.com/barryvdh", + "type": "github" + } + ], + "time": "2022-02-20T15:07:15+00:00" + }, + { + "name": "google/protobuf", + "version": "v3.20.1", + "source": { + "type": "git", + "url": "https://github.com/protocolbuffers/protobuf-php.git", + "reference": "5537a424882b2cbce891330d3e4bdfe363694975" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/5537a424882b2cbce891330d3e4bdfe363694975", + "reference": "5537a424882b2cbce891330d3e4bdfe363694975", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": ">=5.0.0" + }, + "suggest": { + "ext-bcmath": "Need to support JSON deserialization" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Protobuf\\": "src/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "proto library for PHP", + "homepage": "https://developers.google.com/protocol-buffers/", + "keywords": [ + "proto" + ], + "support": { + "issues": "https://github.com/protocolbuffers/protobuf-php/issues", + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v3.20.1" + }, + "time": "2022-04-22T01:22:58+00:00" + }, + { + "name": "google/sqlcommenter-laravel", + "version": "dev-master", + "dist": { + "type": "path", + "url": "../../packages/sqlcommenter-laravel", + "reference": "c509cc3f6d750170f2d4fe438bb04f610f0ea754" + }, + "require": { + "open-telemetry/opentelemetry": "~0.0.9", + "php-http/guzzle7-adapter": "^1.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Google\\GoogleSqlCommenterLaravel\\GoogleSqlCommenterServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Google\\GoogleSqlCommenterLaravel\\": "src" + }, + "classmap": [ + "src/" + ] + }, + "scripts": { + "format": [ + "phpcbf --standard=psr2 src/" + ] + }, + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Google Developers", + "email": "sqlcommenter@googlegroups.com", + "role": "Developer" + } + ], + "description": "Laravel middleware to send events to OpenTelemetry", + "transport-options": { + "relative": true + } + }, + { + "name": "graham-campbell/result-type", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/GrahamCampbell/Result-Type.git", + "reference": "0690bde05318336c7221785f2a932467f98b64ca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", + "reference": "0690bde05318336c7221785f2a932467f98b64ca", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "phpoption/phpoption": "^1.8" + }, + "require-dev": { + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "autoload": { + "psr-4": { + "GrahamCampbell\\ResultType\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "An Implementation Of The Result Type", + "keywords": [ + "Graham Campbell", + "GrahamCampbell", + "Result Type", + "Result-Type", + "result" + ], + "support": { + "issues": "https://github.com/GrahamCampbell/Result-Type/issues", + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type", + "type": "tidelift" + } + ], + "time": "2021-11-21T21:41:47+00:00" + }, + { + "name": "grpc/grpc", + "version": "1.42.0", + "source": { + "type": "git", + "url": "https://github.com/grpc/grpc-php.git", + "reference": "9fa44f104cb92e924d4da547323a97f3d8aca6d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/grpc/grpc-php/zipball/9fa44f104cb92e924d4da547323a97f3d8aca6d4", + "reference": "9fa44f104cb92e924d4da547323a97f3d8aca6d4", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "google/auth": "^v1.3.0" + }, + "suggest": { + "ext-protobuf": "For better performance, install the protobuf C extension.", + "google/protobuf": "To get started using grpc quickly, install the native protobuf library." + }, + "type": "library", + "autoload": { + "psr-4": { + "Grpc\\": "src/lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "gRPC library for PHP", + "homepage": "https://grpc.io", + "keywords": [ + "rpc" + ], + "support": { + "source": "https://github.com/grpc/grpc-php/tree/v1.42.0" + }, + "time": "2021-11-19T08:13:51+00:00" + }, + { + "name": "guzzlehttp/guzzle", + "version": "7.4.2", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ac1ec1cd9b5624694c3a40be801d94137afb12b4", + "reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "guzzlehttp/promises": "^1.5", + "guzzlehttp/psr7": "^1.8.3 || ^2.1", + "php": "^7.2.5 || ^8.0", + "psr/http-client": "^1.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "provide": { + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-curl": "*", + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "psr/log": "^1.1 || ^2.0 || ^3.0" + }, + "suggest": { + "ext-curl": "Required for CURL handler support", + "ext-intl": "Required for Internationalized Domain Name (IDN) support", + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.4-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Jeremy Lindblom", + "email": "jeremeamia@gmail.com", + "homepage": "https://github.com/jeremeamia" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "psr-18", + "psr-7", + "rest", + "web service" + ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.4.2" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle", + "type": "tidelift" + } + ], + "time": "2022-03-20T14:16:28+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "1.5.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "symfony/phpunit-bridge": "^4.4 || ^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/promises", + "type": "tidelift" + } + ], + "time": "2021-10-22T20:56:57+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/c94a94f120803a18554c1805ef2e539f8285f9a2", + "reference": "c94a94f120803a18554c1805ef2e539f8285f9a2", + "shasum": "" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "ralouphie/getallheaders": "^3.0" + }, + "provide": { + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "http-interop/http-factory-tests": "^0.9", + "phpunit/phpunit": "^8.5.8 || ^9.3.10" + }, + "suggest": { + "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "George Mponos", + "email": "gmponos@gmail.com", + "homepage": "https://github.com/gmponos" + }, + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com", + "homepage": "https://github.com/Nyholm" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://github.com/sagikazarmark" + }, + { + "name": "Tobias Schultze", + "email": "webmaster@tubo-world.de", + "homepage": "https://github.com/Tobion" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "psr-7", + "request", + "response", + "stream", + "uri", + "url" + ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.2.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://github.com/Nyholm", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/guzzlehttp/psr7", + "type": "tidelift" + } + ], + "time": "2022-03-20T21:55:58+00:00" + }, + { + "name": "laravel/framework", + "version": "v9.9.0", + "source": { + "type": "git", + "url": "https://github.com/laravel/framework.git", + "reference": "4d5a07640891b772188d7737348886a0222737d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/framework/zipball/4d5a07640891b772188d7737348886a0222737d8", + "reference": "4d5a07640891b772188d7737348886a0222737d8", + "shasum": "" + }, + "require": { + "doctrine/inflector": "^2.0", + "dragonmantank/cron-expression": "^3.1", + "egulias/email-validator": "^3.1", + "ext-mbstring": "*", + "ext-openssl": "*", + "fruitcake/php-cors": "^1.2", + "laravel/serializable-closure": "^1.0", + "league/commonmark": "^2.2", + "league/flysystem": "^3.0", + "monolog/monolog": "^2.0", + "nesbot/carbon": "^2.53.1", + "php": "^8.0.2", + "psr/container": "^1.1.1|^2.0.1", + "psr/log": "^1.0|^2.0|^3.0", + "psr/simple-cache": "^1.0|^2.0|^3.0", + "ramsey/uuid": "^4.2.2", + "symfony/console": "^6.0", + "symfony/error-handler": "^6.0", + "symfony/finder": "^6.0", + "symfony/http-foundation": "^6.0", + "symfony/http-kernel": "^6.0", + "symfony/mailer": "^6.0", + "symfony/mime": "^6.0", + "symfony/process": "^6.0", + "symfony/routing": "^6.0", + "symfony/var-dumper": "^6.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.2", + "vlucas/phpdotenv": "^5.4.1", + "voku/portable-ascii": "^2.0" + }, + "conflict": { + "tightenco/collect": "<5.5.33" + }, + "provide": { + "psr/container-implementation": "1.1|2.0", + "psr/simple-cache-implementation": "1.0|2.0|3.0" + }, + "replace": { + "illuminate/auth": "self.version", + "illuminate/broadcasting": "self.version", + "illuminate/bus": "self.version", + "illuminate/cache": "self.version", + "illuminate/collections": "self.version", + "illuminate/conditionable": "self.version", + "illuminate/config": "self.version", + "illuminate/console": "self.version", + "illuminate/container": "self.version", + "illuminate/contracts": "self.version", + "illuminate/cookie": "self.version", + "illuminate/database": "self.version", + "illuminate/encryption": "self.version", + "illuminate/events": "self.version", + "illuminate/filesystem": "self.version", + "illuminate/hashing": "self.version", + "illuminate/http": "self.version", + "illuminate/log": "self.version", + "illuminate/macroable": "self.version", + "illuminate/mail": "self.version", + "illuminate/notifications": "self.version", + "illuminate/pagination": "self.version", + "illuminate/pipeline": "self.version", + "illuminate/queue": "self.version", + "illuminate/redis": "self.version", + "illuminate/routing": "self.version", + "illuminate/session": "self.version", + "illuminate/support": "self.version", + "illuminate/testing": "self.version", + "illuminate/translation": "self.version", + "illuminate/validation": "self.version", + "illuminate/view": "self.version" + }, + "require-dev": { + "aws/aws-sdk-php": "^3.198.1", + "doctrine/dbal": "^2.13.3|^3.1.4", + "fakerphp/faker": "^1.9.2", + "guzzlehttp/guzzle": "^7.2", + "league/flysystem-aws-s3-v3": "^3.0", + "league/flysystem-ftp": "^3.0", + "league/flysystem-sftp-v3": "^3.0", + "mockery/mockery": "^1.4.4", + "orchestra/testbench-core": "^7.1", + "pda/pheanstalk": "^4.0", + "phpstan/phpstan": "^1.4.7", + "phpunit/phpunit": "^9.5.8", + "predis/predis": "^1.1.9", + "symfony/cache": "^6.0" + }, + "suggest": { + "ably/ably-php": "Required to use the Ably broadcast driver (^1.0).", + "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage, and SES mail driver (^3.198.1).", + "brianium/paratest": "Required to run tests in parallel (^6.0).", + "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.13.3|^3.1.4).", + "ext-bcmath": "Required to use the multiple_of validation rule.", + "ext-ftp": "Required to use the Flysystem FTP driver.", + "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", + "ext-memcached": "Required to use the memcache cache driver.", + "ext-pcntl": "Required to use all features of the queue worker.", + "ext-posix": "Required to use all features of the queue worker.", + "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", + "fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).", + "filp/whoops": "Required for friendly error pages in development (^2.14.3).", + "guzzlehttp/guzzle": "Required to use the HTTP Client and the ping methods on schedules (^7.2).", + "laravel/tinker": "Required to use the tinker console command (^2.0).", + "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^3.0).", + "league/flysystem-ftp": "Required to use the Flysystem FTP driver (^3.0).", + "league/flysystem-sftp-v3": "Required to use the Flysystem SFTP driver (^3.0).", + "mockery/mockery": "Required to use mocking (^1.4.4).", + "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", + "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^9.5.8).", + "predis/predis": "Required to use the predis connector (^1.1.9).", + "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", + "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^6.0|^7.0).", + "symfony/cache": "Required to PSR-6 cache bridge (^6.0).", + "symfony/filesystem": "Required to enable support for relative symbolic links (^6.0).", + "symfony/http-client": "Required to enable support for the Symfony API mail transports (^6.0).", + "symfony/mailgun-mailer": "Required to enable support for the Mailgun mail transport (^6.0).", + "symfony/postmark-mailer": "Required to enable support for the Postmark mail transport (^6.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.x-dev" + } + }, + "autoload": { + "files": [ + "src/Illuminate/Collections/helpers.php", + "src/Illuminate/Events/functions.php", + "src/Illuminate/Foundation/helpers.php", + "src/Illuminate/Support/helpers.php" + ], + "psr-4": { + "Illuminate\\": "src/Illuminate/", + "Illuminate\\Support\\": [ + "src/Illuminate/Macroable/", + "src/Illuminate/Collections/", + "src/Illuminate/Conditionable/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "The Laravel Framework.", + "homepage": "https://laravel.com", + "keywords": [ + "framework", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/framework/issues", + "source": "https://github.com/laravel/framework" + }, + "time": "2022-04-19T15:01:23+00:00" + }, + { + "name": "laravel/sanctum", + "version": "v2.15.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/sanctum.git", + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sanctum/zipball/31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", + "reference": "31fbe6f85aee080c4dc2f9b03dc6dd5d0ee72473", + "shasum": "" + }, + "require": { + "ext-json": "*", + "illuminate/console": "^6.9|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.9|^7.0|^8.0|^9.0", + "illuminate/database": "^6.9|^7.0|^8.0|^9.0", + "illuminate/support": "^6.9|^7.0|^8.0|^9.0", + "php": "^7.2|^8.0" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "orchestra/testbench": "^4.0|^5.0|^6.0|^7.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sanctum\\SanctumServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sanctum\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel Sanctum provides a featherweight authentication system for SPAs and simple APIs.", + "keywords": [ + "auth", + "laravel", + "sanctum" + ], + "support": { + "issues": "https://github.com/laravel/sanctum/issues", + "source": "https://github.com/laravel/sanctum" + }, + "time": "2022-04-08T13:39:49+00:00" + }, + { + "name": "laravel/serializable-closure", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "reference": "9e4b005daa20b0c161f3845040046dc9ddc1d74e", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "pestphp/pest": "^1.18", + "phpstan/phpstan": "^0.12.98", + "symfony/var-dumper": "^5.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-02-11T19:23:53+00:00" + }, + { + "name": "laravel/tinker", + "version": "v2.7.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/tinker.git", + "reference": "dff39b661e827dae6e092412f976658df82dbac5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/tinker/zipball/dff39b661e827dae6e092412f976658df82dbac5", + "reference": "dff39b661e827dae6e092412f976658df82dbac5", + "shasum": "" + }, + "require": { + "illuminate/console": "^6.0|^7.0|^8.0|^9.0", + "illuminate/contracts": "^6.0|^7.0|^8.0|^9.0", + "illuminate/support": "^6.0|^7.0|^8.0|^9.0", + "php": "^7.2.5|^8.0", + "psy/psysh": "^0.10.4|^0.11.1", + "symfony/var-dumper": "^4.3.4|^5.0|^6.0" + }, + "require-dev": { + "mockery/mockery": "~1.3.3|^1.4.2", + "phpunit/phpunit": "^8.5.8|^9.3.3" + }, + "suggest": { + "illuminate/database": "The Illuminate Database package (^6.0|^7.0|^8.0|^9.0)." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Tinker\\TinkerServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Tinker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Powerful REPL for the Laravel framework.", + "keywords": [ + "REPL", + "Tinker", + "laravel", + "psysh" + ], + "support": { + "issues": "https://github.com/laravel/tinker/issues", + "source": "https://github.com/laravel/tinker/tree/v2.7.2" + }, + "time": "2022-03-23T12:38:24+00:00" + }, + { + "name": "league/commonmark", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/commonmark.git", + "reference": "32a49eb2b38fe5e5c417ab748a45d0beaab97955" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/32a49eb2b38fe5e5c417ab748a45d0beaab97955", + "reference": "32a49eb2b38fe5e5c417ab748a45d0beaab97955", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "league/config": "^1.1.1", + "php": "^7.4 || ^8.0", + "psr/event-dispatcher": "^1.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", + "symfony/polyfill-php80": "^1.16" + }, + "require-dev": { + "cebe/markdown": "^1.0", + "commonmark/cmark": "0.30.0", + "commonmark/commonmark.js": "0.30.0", + "composer/package-versions-deprecated": "^1.8", + "embed/embed": "^4.4", + "erusev/parsedown": "^1.0", + "ext-json": "*", + "github/gfm": "0.29.0", + "michelf/php-markdown": "^1.4", + "nyholm/psr7": "^1.5", + "phpstan/phpstan": "^0.12.88 || ^1.0.0", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "symfony/finder": "^5.3", + "symfony/yaml": "^2.3 | ^3.0 | ^4.0 | ^5.0 | ^6.0", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "suggest": { + "symfony/yaml": "v2.3+ required if using the Front Matter extension" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "League\\CommonMark\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and GitHub-Flavored Markdown (GFM)", + "homepage": "https://commonmark.thephpleague.com", + "keywords": [ + "commonmark", + "flavored", + "gfm", + "github", + "github-flavored", + "markdown", + "md", + "parser" + ], + "support": { + "docs": "https://commonmark.thephpleague.com/", + "forum": "https://github.com/thephpleague/commonmark/discussions", + "issues": "https://github.com/thephpleague/commonmark/issues", + "rss": "https://github.com/thephpleague/commonmark/releases.atom", + "source": "https://github.com/thephpleague/commonmark" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/commonmark", + "type": "tidelift" + } + ], + "time": "2022-04-07T22:37:05+00:00" + }, + { + "name": "league/config", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/config.git", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/config/zipball/a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "reference": "a9d39eeeb6cc49d10a6e6c36f22c4c1f4a767f3e", + "shasum": "" + }, + "require": { + "dflydev/dot-access-data": "^3.0.1", + "nette/schema": "^1.2", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^0.12.90", + "phpunit/phpunit": "^9.5.5", + "scrutinizer/ocular": "^1.8.1", + "unleashedtech/php-coding-standard": "^3.1", + "vimeo/psalm": "^4.7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Config\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "https://www.colinodell.com", + "role": "Lead Developer" + } + ], + "description": "Define configuration arrays with strict schemas and access values with dot notation", + "homepage": "https://config.thephpleague.com", + "keywords": [ + "array", + "config", + "configuration", + "dot", + "dot-access", + "nested", + "schema" + ], + "support": { + "docs": "https://config.thephpleague.com/", + "issues": "https://github.com/thephpleague/config/issues", + "rss": "https://github.com/thephpleague/config/releases.atom", + "source": "https://github.com/thephpleague/config" + }, + "funding": [ + { + "url": "https://www.colinodell.com/sponsor", + "type": "custom" + }, + { + "url": "https://www.paypal.me/colinpodell/10.00", + "type": "custom" + }, + { + "url": "https://github.com/colinodell", + "type": "github" + } + ], + "time": "2021-08-14T12:15:32+00:00" + }, + { + "name": "league/flysystem", + "version": "3.0.17", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "29eb78cac0be0c22237c5e0f6f98234d97037d79" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/29eb78cac0be0c22237c5e0f6f98234d97037d79", + "reference": "29eb78cac0be0c22237c5e0f6f98234d97037d79", + "shasum": "" + }, + "require": { + "league/mime-type-detection": "^1.0.0", + "php": "^8.0.2" + }, + "conflict": { + "aws/aws-sdk-php": "3.209.31 || 3.210.0", + "guzzlehttp/guzzle": "<7.0", + "guzzlehttp/ringphp": "<1.1.1", + "symfony/http-client": "<5.2" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.0", + "aws/aws-sdk-php": "^3.198.1", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "ext-ftp": "*", + "ext-zip": "*", + "friendsofphp/php-cs-fixer": "^3.5", + "google/cloud-storage": "^1.23", + "microsoft/azure-storage-blob": "^1.1", + "phpseclib/phpseclib": "^2.0", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^9.5.11", + "sabre/dav": "^4.3.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/3.0.17" + }, + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-04-14T14:57:13+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "reference": "ff6248ea87a9f116e78edd6002e39e5128a0d4dd", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.11.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-04-17T13:12:02+00:00" + }, + { + "name": "monolog/monolog", + "version": "2.5.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "4192345e260f1d51b365536199744b987e160edc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/4192345e260f1d51b365536199744b987e160edc", + "reference": "4192345e260f1d51b365536199744b987e160edc", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "provide": { + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "elasticsearch/elasticsearch": "^7", + "graylog2/gelf-php": "^1.4.2", + "mongodb/mongodb": "^1.8", + "php-amqplib/php-amqplib": "~2.4 || ^3", + "php-console/php-console": "^3.1.3", + "phpspec/prophecy": "^1.6.1", + "phpstan/phpstan": "^0.12.91", + "phpunit/phpunit": "^8.5", + "predis/predis": "^1.1", + "rollbar/rollbar": "^1.3 || ^2 || ^3", + "ruflin/elastica": ">=0.90@dev", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", + "ext-mbstring": "Allow to work properly with unicode symbols", + "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "https://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.5.0" + }, + "funding": [ + { + "url": "https://github.com/Seldaek", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/monolog/monolog", + "type": "tidelift" + } + ], + "time": "2022-04-08T15:43:54+00:00" + }, + { + "name": "nesbot/carbon", + "version": "2.57.0", + "source": { + "type": "git", + "url": "https://github.com/briannesbitt/Carbon.git", + "reference": "4a54375c21eea4811dbd1149fe6b246517554e78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/4a54375c21eea4811dbd1149fe6b246517554e78", + "reference": "4a54375c21eea4811dbd1149fe6b246517554e78", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.1.8 || ^8.0", + "symfony/polyfill-mbstring": "^1.0", + "symfony/polyfill-php80": "^1.16", + "symfony/translation": "^3.4 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "doctrine/dbal": "^2.0 || ^3.0", + "doctrine/orm": "^2.7", + "friendsofphp/php-cs-fixer": "^3.0", + "kylekatarnls/multi-tester": "^2.0", + "phpmd/phpmd": "^2.9", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.54 || ^1.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.14", + "squizlabs/php_codesniffer": "^3.4" + }, + "bin": [ + "bin/carbon" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-master": "2.x-dev" + }, + "laravel": { + "providers": [ + "Carbon\\Laravel\\ServiceProvider" + ] + }, + "phpstan": { + "includes": [ + "extension.neon" + ] + } + }, + "autoload": { + "psr-4": { + "Carbon\\": "src/Carbon/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Brian Nesbitt", + "email": "brian@nesbot.com", + "homepage": "https://markido.com" + }, + { + "name": "kylekatarnls", + "homepage": "https://github.com/kylekatarnls" + } + ], + "description": "An API extension for DateTime that supports 281 different languages.", + "homepage": "https://carbon.nesbot.com", + "keywords": [ + "date", + "datetime", + "time" + ], + "support": { + "docs": "https://carbon.nesbot.com/docs", + "issues": "https://github.com/briannesbitt/Carbon/issues", + "source": "https://github.com/briannesbitt/Carbon" + }, + "funding": [ + { + "url": "https://opencollective.com/Carbon", + "type": "open_collective" + }, + { + "url": "https://tidelift.com/funding/github/packagist/nesbot/carbon", + "type": "tidelift" + } + ], + "time": "2022-02-13T18:13:33+00:00" + }, + { + "name": "nette/schema", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/nette/schema.git", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/schema/zipball/9a39cef03a5b34c7de64f551538cbba05c2be5df", + "reference": "9a39cef03a5b34c7de64f551538cbba05c2be5df", + "shasum": "" + }, + "require": { + "nette/utils": "^2.5.7 || ^3.1.5 || ^4.0", + "php": ">=7.1 <8.2" + }, + "require-dev": { + "nette/tester": "^2.3 || ^2.4", + "phpstan/phpstan-nette": "^0.12", + "tracy/tracy": "^2.7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "📐 Nette Schema: validating data structures against a given Schema.", + "homepage": "https://nette.org", + "keywords": [ + "config", + "nette" + ], + "support": { + "issues": "https://github.com/nette/schema/issues", + "source": "https://github.com/nette/schema/tree/v1.2.2" + }, + "time": "2021-10-15T11:40:02+00:00" + }, + { + "name": "nette/utils", + "version": "v3.2.7", + "source": { + "type": "git", + "url": "https://github.com/nette/utils.git", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nette/utils/zipball/0af4e3de4df9f1543534beab255ccf459e7a2c99", + "reference": "0af4e3de4df9f1543534beab255ccf459e7a2c99", + "shasum": "" + }, + "require": { + "php": ">=7.2 <8.2" + }, + "conflict": { + "nette/di": "<3.0.6" + }, + "require-dev": { + "nette/tester": "~2.0", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.3" + }, + "suggest": { + "ext-gd": "to use Image", + "ext-iconv": "to use Strings::webalize(), toAscii(), chr() and reverse()", + "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", + "ext-json": "to use Nette\\Utils\\Json", + "ext-mbstring": "to use Strings::lower() etc...", + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", + "ext-xml": "to use Strings::length() etc. when mbstring is not available" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause", + "GPL-2.0-only", + "GPL-3.0-only" + ], + "authors": [ + { + "name": "David Grudl", + "homepage": "https://davidgrudl.com" + }, + { + "name": "Nette Community", + "homepage": "https://nette.org/contributors" + } + ], + "description": "🛠 Nette Utils: lightweight utilities for string & array manipulation, image handling, safe JSON encoding/decoding, validation, slug or strong password generating etc.", + "homepage": "https://nette.org", + "keywords": [ + "array", + "core", + "datetime", + "images", + "json", + "nette", + "paginator", + "password", + "slugify", + "string", + "unicode", + "utf-8", + "utility", + "validation" + ], + "support": { + "issues": "https://github.com/nette/utils/issues", + "source": "https://github.com/nette/utils/tree/v3.2.7" + }, + "time": "2022-01-24T11:29:14+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.13.2", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + }, + "time": "2021-11-30T19:35:32+00:00" + }, + { + "name": "nyholm/dsn", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/dsn.git", + "reference": "9445621b426bac8c0ca161db8cd700da00a4e618" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/dsn/zipball/9445621b426bac8c0ca161db8cd700da00a4e618", + "reference": "9445621b426bac8c0ca161db8cd700da00a4e618", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "symfony/phpunit-bridge": "^5.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Dsn\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "Parse your DSN strings in a powerful and flexible way", + "homepage": "http://tnyholm.se", + "keywords": [ + "database", + "dsn", + "dsn parser", + "parser" + ], + "support": { + "issues": "https://github.com/Nyholm/dsn/issues", + "source": "https://github.com/Nyholm/dsn/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/Nyholm", + "type": "github" + } + ], + "time": "2021-11-18T09:23:29+00:00" + }, + { + "name": "open-telemetry/opentelemetry", + "version": "0.0.10", + "source": { + "type": "git", + "url": "https://github.com/open-telemetry/opentelemetry-php.git", + "reference": "4e3264578b5fcc1750cad5bdbf01ba9fb3caab0b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/open-telemetry/opentelemetry-php/zipball/4e3264578b5fcc1750cad5bdbf01ba9fb3caab0b", + "reference": "4e3264578b5fcc1750cad5bdbf01ba9fb3caab0b", + "shasum": "" + }, + "require": { + "ext-json": "*", + "google/protobuf": "^3.3.0", + "grpc/grpc": "^1.30", + "nyholm/dsn": "^2.0.0", + "packaged/thrift": "^0.15.0", + "php": "^7.4 || ^8.0", + "php-http/async-client-implementation": "^1.0", + "php-http/discovery": "^1.14", + "promphp/prometheus_client_php": "^2.2.1", + "psr/http-factory-implementation": "^1.0", + "psr/log": "^1.1|^2.0|^3.0", + "symfony/polyfill-mbstring": "^1.23" + }, + "replace": { + "open-telemetry/api": "self.version", + "open-telemetry/context": "self.version", + "open-telemetry/proto-otel": "self.version", + "open-telemetry/sdk": "self.version", + "open-telemetry/sdk-contrib": "self.version", + "open-telemetry/sem-conv": "self.version" + }, + "require-dev": { + "assertwell/phpunit-global-state": "^0.2", + "composer/xdebug-handler": "^2.0", + "dg/bypass-finals": "^1.3", + "ext-grpc": "*", + "friendsofphp/php-cs-fixer": "^3.4", + "guzzlehttp/guzzle": "^7.4", + "guzzlehttp/psr7": "^2.1", + "mikey179/vfsstream": "^1.6", + "mockery/mockery": "^1.4", + "monolog/monolog": "^2.3", + "nyholm/psr7": "^1.4", + "phan/phan": "^5.0", + "php-http/mock-client": "^1.5", + "phpbench/phpbench": "^1.2", + "phpmetrics/phpmetrics": "^2.7", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-mockery": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.3", + "psalm/plugin-mockery": "^0.9", + "psalm/plugin-phpunit": "^0.16", + "psalm/psalm": "^4.0", + "qossmic/deptrac-shim": "^0.18", + "symfony/http-client": "^5.2" + }, + "suggest": { + "ext-grpc": "To use the OTLP GRPC Exporter", + "ext-protobuf": "For more performant protobuf/grpc exporting", + "ext-sockets": "To use the Thrift UDP Exporter for the Jaeger Agent" + }, + "type": "library", + "autoload": { + "files": [ + "src/Context/fiber/initialize_fiber_handler.php", + "src/SDK/Common/Dev/Compatibility/_load.php" + ], + "psr-4": { + "Jaeger\\Thrift\\": "thrift/jaeger/", + "OpenTelemetry\\": "src/", + "Opentelemetry\\Proto\\": "proto/otel/Opentelemetry/Proto/", + "GPBMetadata\\Opentelemetry\\": "proto/otel/GPBMetadata/Opentelemetry/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Bob Strecansky", + "email": "bob.strecansky@gmail.com" + }, + { + "name": "Dmitry Krokhin", + "email": "nekufa@gmail.com" + }, + { + "name": "Levi Morrison", + "email": "levim@php.net" + } + ], + "description": "OpenTelemetry makes robust, portable telemetry a built-in feature of cloud-native software.", + "homepage": "https://opentelemetry.io/docs/php", + "support": { + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php/tree/0.0.10" + }, + "time": "2022-04-27T12:09:42+00:00" + }, + { + "name": "packaged/thrift", + "version": "0.15.0", + "source": { + "type": "git", + "url": "https://github.com/packaged/thrift.git", + "reference": "dbf4e5ff5c85d56ccae62265ed25424b366ce269" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/packaged/thrift/zipball/dbf4e5ff5c85d56ccae62265ed25424b366ce269", + "reference": "dbf4e5ff5c85d56ccae62265ed25424b366ce269", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Thrift\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Apache Thrift", + "homepage": "http://thrift.apache.org/", + "keywords": [ + "apache", + "thrift" + ], + "support": { + "issues": "https://github.com/packaged/thrift/issues", + "source": "https://github.com/packaged/thrift/tree/0.15.0" + }, + "time": "2021-09-23T10:34:40+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.14.1", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "de90ab2b41d7d61609f504e031339776bc8c7223" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/de90ab2b41d7d61609f504e031339776bc8c7223", + "reference": "de90ab2b41d7d61609f504e031339776bc8c7223", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0" + }, + "require-dev": { + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1", + "puli/composer-plugin": "1.0.0-beta10" + }, + "suggest": { + "php-http/message": "Allow to use Guzzle, Diactoros or Slim Framework factories" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.9-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds installed HTTPlug implementations and PSR-7 message factories", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.14.1" + }, + "time": "2021-09-18T07:57:46+00:00" + }, + { + "name": "php-http/guzzle7-adapter", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/guzzle7-adapter.git", + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/guzzle7-adapter/zipball/fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", + "reference": "fb075a71dbfa4847cf0c2938c4e5a9c478ef8b01", + "shasum": "" + }, + "require": { + "guzzlehttp/guzzle": "^7.0", + "php": "^7.2 | ^8.0", + "php-http/httplug": "^2.0", + "psr/http-client": "^1.0" + }, + "provide": { + "php-http/async-client-implementation": "1.0", + "php-http/client-implementation": "1.0", + "psr/http-client-implementation": "1.0" + }, + "require-dev": { + "php-http/client-integration-tests": "^3.0", + "phpunit/phpunit": "^8.0|^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Adapter\\Guzzle7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + } + ], + "description": "Guzzle 7 HTTP Adapter", + "homepage": "http://httplug.io", + "keywords": [ + "Guzzle", + "http" + ], + "support": { + "issues": "https://github.com/php-http/guzzle7-adapter/issues", + "source": "https://github.com/php-http/guzzle7-adapter/tree/1.0.0" + }, + "time": "2021-03-09T07:35:15+00:00" + }, + { + "name": "php-http/httplug", + "version": "2.3.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/httplug.git", + "reference": "f640739f80dfa1152533976e3c112477f69274eb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/httplug/zipball/f640739f80dfa1152533976e3c112477f69274eb", + "reference": "f640739f80dfa1152533976e3c112477f69274eb", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "php-http/promise": "^1.1", + "psr/http-client": "^1.0", + "psr/http-message": "^1.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.1", + "phpspec/phpspec": "^5.1 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Eric GELOEN", + "email": "geloen.eric@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com", + "homepage": "https://sagikazarmark.hu" + } + ], + "description": "HTTPlug, the HTTP client abstraction for PHP", + "homepage": "http://httplug.io", + "keywords": [ + "client", + "http" + ], + "support": { + "issues": "https://github.com/php-http/httplug/issues", + "source": "https://github.com/php-http/httplug/tree/2.3.0" + }, + "time": "2022-02-21T09:52:22+00:00" + }, + { + "name": "php-http/promise", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/promise.git", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/promise/zipball/4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "reference": "4c4c1f9b7289a2ec57cde7f1e9762a5789506f88", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "friends-of-phpspec/phpspec-code-coverage": "^4.3.2", + "phpspec/phpspec": "^5.1.2 || ^6.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "Http\\Promise\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Joel Wurtz", + "email": "joel.wurtz@gmail.com" + }, + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Promise used for asynchronous HTTP requests", + "homepage": "http://httplug.io", + "keywords": [ + "promise" + ], + "support": { + "issues": "https://github.com/php-http/promise/issues", + "source": "https://github.com/php-http/promise/tree/1.1.0" + }, + "time": "2020-07-07T09:29:14+00:00" + }, + { + "name": "phpoption/phpoption", + "version": "1.8.1", + "source": { + "type": "git", + "url": "https://github.com/schmittjoh/php-option.git", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpOption\\": "src/PhpOption/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Johannes M. Schmitt", + "email": "schmittjoh@gmail.com", + "homepage": "https://github.com/schmittjoh" + }, + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + } + ], + "description": "Option Type for PHP", + "keywords": [ + "language", + "option", + "php", + "type" + ], + "support": { + "issues": "https://github.com/schmittjoh/php-option/issues", + "source": "https://github.com/schmittjoh/php-option/tree/1.8.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2021-12-04T23:24:31+00:00" + }, + { + "name": "promphp/prometheus_client_php", + "version": "v2.6.0", + "source": { + "type": "git", + "url": "https://github.com/PromPHP/prometheus_client_php.git", + "reference": "10881142d2c55de19f529ebbcb7f89558c6d46d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PromPHP/prometheus_client_php/zipball/10881142d2c55de19f529ebbcb7f89558c6d46d4", + "reference": "10881142d2c55de19f529ebbcb7f89558c6d46d4", + "shasum": "" + }, + "require": { + "ext-json": "*", + "php": "^7.2|^8.0" + }, + "replace": { + "endclothing/prometheus_client_php": "*", + "jimdo/prometheus_client_php": "*", + "lkaemmerling/prometheus_client_php": "*" + }, + "require-dev": { + "guzzlehttp/guzzle": "^6.3|^7.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5.4", + "phpstan/phpstan-phpunit": "^1.1.0", + "phpstan/phpstan-strict-rules": "^1.1.0", + "phpunit/phpunit": "^9.4", + "squizlabs/php_codesniffer": "^3.6", + "symfony/polyfill-apcu": "^1.6" + }, + "suggest": { + "ext-apc": "Required if using APCu.", + "ext-redis": "Required if using Redis.", + "promphp/prometheus_push_gateway_php": "An easy client for using Prometheus PushGateway.", + "symfony/polyfill-apcu": "Required if you use APCu on PHP8.0+" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Prometheus\\": "src/Prometheus/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Lukas Kämmerling", + "email": "kontakt@lukas-kaemmerling.de" + } + ], + "description": "Prometheus instrumentation library for PHP applications.", + "support": { + "issues": "https://github.com/PromPHP/prometheus_client_php/issues", + "source": "https://github.com/PromPHP/prometheus_client_php/tree/v2.6.0" + }, + "time": "2022-04-12T14:07:05+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, + "time": "2020-06-29T06:28:15+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "reference": "12ac7fcd07e5b077433f5f2bee95b3a771bf61be", + "shasum": "" + }, + "require": { + "php": ">=7.0.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, + "time": "2019-04-30T12:38:16+00:00" + }, + { + "name": "psr/http-message", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "psr/simple-cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/simple-cache.git", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/simple-cache/zipball/764e0b3939f5ca87cb904f570ef9be2d78a07865", + "reference": "764e0b3939f5ca87cb904f570ef9be2d78a07865", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\SimpleCache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interfaces for simple caching", + "keywords": [ + "cache", + "caching", + "psr", + "psr-16", + "simple-cache" + ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/3.0.0" + }, + "time": "2021-10-29T13:26:27+00:00" + }, + { + "name": "psy/psysh", + "version": "v0.11.2", + "source": { + "type": "git", + "url": "https://github.com/bobthecow/psysh.git", + "reference": "7f7da640d68b9c9fec819caae7c744a213df6514" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/7f7da640d68b9c9fec819caae7c744a213df6514", + "reference": "7f7da640d68b9c9fec819caae7c744a213df6514", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-tokenizer": "*", + "nikic/php-parser": "^4.0 || ^3.1", + "php": "^8.0 || ^7.0.8", + "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^6.0 || ^5.0 || ^4.0 || ^3.4" + }, + "conflict": { + "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.2", + "hoa/console": "3.17.05.02" + }, + "suggest": { + "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", + "ext-pdo-sqlite": "The doc command requires SQLite to work.", + "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well.", + "ext-readline": "Enables support for arrow-key history navigation, and showing and manipulating command history.", + "hoa/console": "A pure PHP readline implementation. You'll want this if your PHP install doesn't already support readline or libedit." + }, + "bin": [ + "bin/psysh" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.11.x-dev" + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Psy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Justin Hileman", + "email": "justin@justinhileman.info", + "homepage": "http://justinhileman.com" + } + ], + "description": "An interactive shell for modern PHP.", + "homepage": "http://psysh.org", + "keywords": [ + "REPL", + "console", + "interactive", + "shell" + ], + "support": { + "issues": "https://github.com/bobthecow/psysh/issues", + "source": "https://github.com/bobthecow/psysh/tree/v0.11.2" + }, + "time": "2022-02-28T15:28:54+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "ramsey/collection", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "reference": "cccc74ee5e328031b15640b51056ee8d3bb66c0a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8", + "symfony/polyfill-php81": "^1.23" + }, + "require-dev": { + "captainhook/captainhook": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "ergebnis/composer-normalize": "^2.6", + "fakerphp/faker": "^1.5", + "hamcrest/hamcrest-php": "^2", + "jangregor/phpstan-prophecy": "^0.8", + "mockery/mockery": "^1.3", + "phpspec/prophecy-phpunit": "^2.0", + "phpstan/extension-installer": "^1", + "phpstan/phpstan": "^0.12.32", + "phpstan/phpstan-mockery": "^0.12.5", + "phpstan/phpstan-phpunit": "^0.12.11", + "phpunit/phpunit": "^8.5 || ^9", + "psy/psysh": "^0.10.4", + "slevomat/coding-standard": "^6.3", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/collection", + "type": "tidelift" + } + ], + "time": "2021-10-10T03:01:02+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.3.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", + "reference": "8505afd4fea63b81a85d3b7b53ac3cb8dc347c28", + "shasum": "" + }, + "require": { + "brick/math": "^0.8 || ^0.9", + "ext-ctype": "*", + "ext-json": "*", + "php": "^8.0", + "ramsey/collection": "^1.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.10", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "doctrine/annotations": "^1.8", + "ergebnis/composer-normalize": "^2.15", + "mockery/mockery": "^1.3", + "moontoast/math": "^1.1", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.2", + "php-mock/php-mock-mockery": "^1.3", + "php-parallel-lint/php-parallel-lint": "^1.1", + "phpbench/phpbench": "^1.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-mockery": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpunit/phpunit": "^8.5 || ^9", + "slevomat/coding-standard": "^7.0", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.9" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-ctype": "Enables faster processing of character classification using ctype functions.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.3.1" + }, + "funding": [ + { + "url": "https://github.com/ramsey", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/ramsey/uuid", + "type": "tidelift" + } + ], + "time": "2022-03-27T21:42:02+00:00" + }, + { + "name": "symfony/console", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" + }, + "conflict": { + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "suggest": { + "psr/log": "For using the console logger", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-31T17:18:25+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "1955d595c12c111629cc814d3f2a2ff13580508a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/1955d595c12c111629cc814d3f2a2ff13580508a", + "reference": "1955d595c12c111629cc814d3f2a2ff13580508a", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/error-handler", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/error-handler.git", + "reference": "e600c54e5b30555eecea3ffe4314e58f832e78ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/e600c54e5b30555eecea3ffe4314e58f832e78ee", + "reference": "e600c54e5b30555eecea3ffe4314e58f832e78ee", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\ErrorHandler\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to manage errors and ease debugging PHP code", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-18T16:21:55+00:00" + }, + { + "name": "symfony/event-dispatcher", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934", + "reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/event-dispatcher-contracts": "^2|^3" + }, + "conflict": { + "symfony/dependency-injection": "<5.4" + }, + "provide": { + "psr/event-dispatcher-implementation": "1.0", + "symfony/event-dispatcher-implementation": "2.0|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" + }, + "suggest": { + "symfony/dependency-injection": "", + "symfony/http-kernel": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\EventDispatcher\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/event-dispatcher-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/event-dispatcher-contracts.git", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/event-dispatcher": "^1" + }, + "suggest": { + "symfony/event-dispatcher-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\EventDispatcher\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to dispatching event", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/finder", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430", + "reference": "8661b74dbabc23223f38c9b99d3f8ade71170430", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Finds files and directories via an intuitive fluent interface", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-26T17:23:29+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "c816b26f03b6902dba79b352c84a17f53d815f0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/c816b26f03b6902dba79b352c84a17f53d815f0d", + "reference": "c816b26f03b6902dba79b352c84a17f53d815f0d", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-24T14:13:59+00:00" + }, + { + "name": "symfony/http-kernel", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-kernel.git", + "reference": "9c03dab07a6aa336ffaadc15352b1d14f4ce01f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/9c03dab07a6aa336ffaadc15352b1d14f4ce01f5", + "reference": "9c03dab07a6aa336ffaadc15352b1d14f4ce01f5", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" + }, + "require-dev": { + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpKernel\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides a structured process for converting a Request into a Response", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-04-02T06:35:11+00:00" + }, + { + "name": "symfony/mailer", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mailer.git", + "reference": "f7343f94e7afecca2ad840b078f9d80200e1bd27" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mailer/zipball/f7343f94e7afecca2ad840b078f9d80200e1bd27", + "reference": "f7343f94e7afecca2ad840b078f9d80200e1bd27", + "shasum": "" + }, + "require": { + "egulias/email-validator": "^2.1.10|^3", + "php": ">=8.0.2", + "psr/event-dispatcher": "^1", + "psr/log": "^1|^2|^3", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3" + }, + "conflict": { + "symfony/http-kernel": "<5.4" + }, + "require-dev": { + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/messenger": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mailer\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Helps sending emails", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/mailer/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-18T16:06:28+00:00" + }, + { + "name": "symfony/mime", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/mime.git", + "reference": "74266e396f812a2301536397a6360b6e6913c0d8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/mime/zipball/74266e396f812a2301536397a6360b6e6913c0d8", + "reference": "74266e396f812a2301536397a6360b6e6913c0d8", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-intl-idn": "^1.10", + "symfony/polyfill-mbstring": "^1.0" + }, + "conflict": { + "egulias/email-validator": "~3.0.0", + "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/type-resolver": "<1.4.0", + "symfony/mailer": "<5.4" + }, + "require-dev": { + "egulias/email-validator": "^2.1.10|^3.1", + "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Mime\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows manipulating MIME messages", + "homepage": "https://symfony.com", + "keywords": [ + "mime", + "mime-type" + ], + "support": { + "source": "https://github.com/symfony/mime/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-13T20:10:05+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "30885182c981ab175d4d034db0f6f469898070ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-10-20T20:35:02+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", + "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-23T21:10:46+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/749045c69efb97c70d25d7463abba812e91f3a44", + "reference": "749045c69efb97c70d25d7463abba812e91f3a44", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-intl-normalizer": "^1.10", + "symfony/polyfill-php72": "^1.10" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Idn\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Laurent Bassin", + "email": "laurent@bassin.info" + }, + { + "name": "Trevor Rowbotham", + "email": "trevor.rowbotham@pm.me" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's idn_to_ascii and idn_to_utf8 functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "idn", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-14T14:02:44+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-02-19T12:13:01+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", + "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-11-30T18:21:41+00:00" + }, + { + "name": "symfony/polyfill-php72", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-05-27T09:17:38+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-04T08:16:47+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.25.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-09-13T13:58:11+00:00" + }, + { + "name": "symfony/process", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/process.git", + "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/process/zipball/e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Process\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Executes commands in sub-processes", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-18T16:21:55+00:00" + }, + { + "name": "symfony/routing", + "version": "v6.0.5", + "source": { + "type": "git", + "url": "https://github.com/symfony/routing.git", + "reference": "a738b152426ac7fcb94bdab8188264652238bef1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/routing/zipball/a738b152426ac7fcb94bdab8188264652238bef1", + "reference": "a738b152426ac7fcb94bdab8188264652238bef1", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "conflict": { + "doctrine/annotations": "<1.12", + "symfony/config": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/yaml": "<5.4" + }, + "require-dev": { + "doctrine/annotations": "^1.12", + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "symfony/config": "For using the all-in-one router or any loader", + "symfony/expression-language": "For using expression matching", + "symfony/http-foundation": "For using a Symfony Request object", + "symfony/yaml": "For using the YAML loader" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Routing\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Maps an HTTP request to a set of configuration variables", + "homepage": "https://symfony.com", + "keywords": [ + "router", + "routing", + "uri", + "url" + ], + "support": { + "source": "https://github.com/symfony/routing/tree/v6.0.5" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-31T19:46:53+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-13T20:10:05+00:00" + }, + { + "name": "symfony/string", + "version": "v6.0.3", + "source": { + "type": "git", + "url": "https://github.com/symfony/string.git", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2", + "reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" + }, + "require-dev": { + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/translation", + "version": "v6.0.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1", + "reference": "b2792b39d74cf41ea3065f27fd2ddf0b556ac7a1", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/translation-contracts": "^2.3|^3.0" + }, + "conflict": { + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/twig-bundle": "<5.4", + "symfony/yaml": "<5.4" + }, + "provide": { + "symfony/translation-implementation": "2.3|3.0" + }, + "require-dev": { + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2.0|^3.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/polyfill-intl-icu": "^1.21", + "symfony/service-contracts": "^1.1.2|^2|^3", + "symfony/yaml": "^5.4|^6.0" + }, + "suggest": { + "psr/log-implementation": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" + }, + "type": "library", + "autoload": { + "files": [ + "Resources/functions.php" + ], + "psr-4": { + "Symfony\\Component\\Translation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides tools to internationalize your application", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/translation/tree/v6.0.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-31T17:18:25+00:00" + }, + { + "name": "symfony/translation-contracts", + "version": "v3.0.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation-contracts.git", + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "shasum": "" + }, + "require": { + "php": ">=8.0.2" + }, + "suggest": { + "symfony/translation-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Translation\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to translation", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-01-02T09:55:41+00:00" + }, + { + "name": "symfony/var-dumper", + "version": "v6.0.6", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-dumper.git", + "reference": "38358405ae948963c50a3aae3dfea598223ba15e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/38358405ae948963c50a3aae3dfea598223ba15e", + "reference": "38358405ae948963c50a3aae3dfea598223ba15e", + "shasum": "" + }, + "require": { + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<5.4" + }, + "require-dev": { + "ext-iconv": "*", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "twig/twig": "^2.13|^3.0.4" + }, + "suggest": { + "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", + "ext-intl": "To show region name in time zone dump", + "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" + }, + "bin": [ + "Resources/bin/var-dump-server" + ], + "type": "library", + "autoload": { + "files": [ + "Resources/functions/dump.php" + ], + "psr-4": { + "Symfony\\Component\\VarDumper\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides mechanisms for walking through any arbitrary PHP variable", + "homepage": "https://symfony.com", + "keywords": [ + "debug", + "dump" + ], + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v6.0.6" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-03-02T12:58:14+00:00" + }, + { + "name": "tijsverkoyen/css-to-inline-styles", + "version": "2.2.4", + "source": { + "type": "git", + "url": "https://github.com/tijsverkoyen/CssToInlineStyles.git", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tijsverkoyen/CssToInlineStyles/zipball/da444caae6aca7a19c0c140f68c6182e337d5b1c", + "reference": "da444caae6aca7a19c0c140f68c6182e337d5b1c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "php": "^5.5 || ^7.0 || ^8.0", + "symfony/css-selector": "^2.7 || ^3.0 || ^4.0 || ^5.0 || ^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0 || ^7.5 || ^8.5.21 || ^9.5.10" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "TijsVerkoyen\\CssToInlineStyles\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Tijs Verkoyen", + "email": "css_to_inline_styles@verkoyen.eu", + "role": "Developer" + } + ], + "description": "CssToInlineStyles is a class that enables you to convert HTML-pages/files into HTML-pages/files with inline styles. This is very useful when you're sending emails.", + "homepage": "https://github.com/tijsverkoyen/CssToInlineStyles", + "support": { + "issues": "https://github.com/tijsverkoyen/CssToInlineStyles/issues", + "source": "https://github.com/tijsverkoyen/CssToInlineStyles/tree/2.2.4" + }, + "time": "2021-12-08T09:12:39+00:00" + }, + { + "name": "vlucas/phpdotenv", + "version": "v5.4.1", + "source": { + "type": "git", + "url": "https://github.com/vlucas/phpdotenv.git", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/264dce589e7ce37a7ba99cb901eed8249fbec92f", + "reference": "264dce589e7ce37a7ba99cb901eed8249fbec92f", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "graham-campbell/result-type": "^1.0.2", + "php": "^7.1.3 || ^8.0", + "phpoption/phpoption": "^1.8", + "symfony/polyfill-ctype": "^1.23", + "symfony/polyfill-mbstring": "^1.23.1", + "symfony/polyfill-php80": "^1.23.1" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "ext-filter": "*", + "phpunit/phpunit": "^7.5.20 || ^8.5.21 || ^9.5.10" + }, + "suggest": { + "ext-filter": "Required to use the boolean validator." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.4-dev" + } + }, + "autoload": { + "psr-4": { + "Dotenv\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, + { + "name": "Vance Lucas", + "email": "vance@vancelucas.com", + "homepage": "https://github.com/vlucas" + } + ], + "description": "Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SERVER` automagically.", + "keywords": [ + "dotenv", + "env", + "environment" + ], + "support": { + "issues": "https://github.com/vlucas/phpdotenv/issues", + "source": "https://github.com/vlucas/phpdotenv/tree/v5.4.1" + }, + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/vlucas/phpdotenv", + "type": "tidelift" + } + ], + "time": "2021-12-12T23:22:04+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "b56450eed252f6801410d810c8e1727224ae0743" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/b56450eed252f6801410d810c8e1727224ae0743", + "reference": "b56450eed252f6801410d810c8e1727224ae0743", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0 || ~9.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "support": { + "issues": "https://github.com/voku/portable-ascii/issues", + "source": "https://github.com/voku/portable-ascii/tree/2.0.1" + }, + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://opencollective.com/portable-ascii", + "type": "open_collective" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2022-03-08T17:03:00+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5.13" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-03-03T08:28:38+00:00" + }, + { + "name": "facade/ignition-contracts", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/facade/ignition-contracts.git", + "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/facade/ignition-contracts/zipball/3c921a1cdba35b68a7f0ccffc6dffc1995b18267", + "reference": "3c921a1cdba35b68a7f0ccffc6dffc1995b18267", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^v2.15.8", + "phpunit/phpunit": "^9.3.11", + "vimeo/psalm": "^3.17.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Facade\\IgnitionContracts\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van der Herten", + "email": "freek@spatie.be", + "homepage": "https://flareapp.io", + "role": "Developer" + } + ], + "description": "Solution contracts for Ignition", + "homepage": "https://github.com/facade/ignition-contracts", + "keywords": [ + "contracts", + "flare", + "ignition" + ], + "support": { + "issues": "https://github.com/facade/ignition-contracts/issues", + "source": "https://github.com/facade/ignition-contracts/tree/1.0.2" + }, + "time": "2020-10-16T08:27:54+00:00" + }, + { + "name": "fakerphp/faker", + "version": "v1.19.0", + "source": { + "type": "git", + "url": "https://github.com/FakerPHP/Faker.git", + "reference": "d7f08a622b3346766325488aa32ddc93ccdecc75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/FakerPHP/Faker/zipball/d7f08a622b3346766325488aa32ddc93ccdecc75", + "reference": "d7f08a622b3346766325488aa32ddc93ccdecc75", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.2 || ^3.0" + }, + "conflict": { + "fzaninotto/faker": "*" + }, + "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", + "doctrine/persistence": "^1.3 || ^2.0", + "ext-intl": "*", + "symfony/phpunit-bridge": "^4.4 || ^5.2" + }, + "suggest": { + "doctrine/orm": "Required to use Faker\\ORM\\Doctrine", + "ext-curl": "Required by Faker\\Provider\\Image to download images.", + "ext-dom": "Required by Faker\\Provider\\HtmlLorem for generating random HTML.", + "ext-iconv": "Required by Faker\\Provider\\ru_RU\\Text::realText() for generating real Russian text.", + "ext-mbstring": "Required for multibyte Unicode string functionality." + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "v1.19-dev" + } + }, + "autoload": { + "psr-4": { + "Faker\\": "src/Faker/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "François Zaninotto" + } + ], + "description": "Faker is a PHP library that generates fake data for you.", + "keywords": [ + "data", + "faker", + "fixtures" + ], + "support": { + "issues": "https://github.com/FakerPHP/Faker/issues", + "source": "https://github.com/FakerPHP/Faker/tree/v1.19.0" + }, + "time": "2022-02-02T17:38:57+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.5", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "shasum": "" + }, + "require": { + "php": "^5.5.9 || ^7.0 || ^8.0", + "psr/log": "^1.0.1 || ^2.0 || ^3.0" + }, + "require-dev": { + "mockery/mockery": "^0.9 || ^1.0", + "phpunit/phpunit": "^4.8.36 || ^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.8 || ^9.3.3", + "symfony/var-dumper": "^2.6 || ^3.0 || ^4.0 || ^5.0" + }, + "suggest": { + "symfony/var-dumper": "Pretty print complex values better with var-dumper available", + "whoops/soap": "Formats errors as SOAP responses" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Whoops\\": "src/Whoops/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Filipe Dobreira", + "homepage": "https://github.com/filp", + "role": "Developer" + } + ], + "description": "php error handling for cool kids", + "homepage": "https://filp.github.io/whoops/", + "keywords": [ + "error", + "exception", + "handling", + "library", + "throwable", + "whoops" + ], + "support": { + "issues": "https://github.com/filp/whoops/issues", + "source": "https://github.com/filp/whoops/tree/2.14.5" + }, + "funding": [ + { + "url": "https://github.com/denis-sokolov", + "type": "github" + } + ], + "time": "2022-01-07T12:00:00+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "support": { + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" + }, + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "laravel/sail", + "version": "v1.13.10", + "source": { + "type": "git", + "url": "https://github.com/laravel/sail.git", + "reference": "cbf55e1a392724313f7726c38578b5e008df6a0f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/sail/zipball/cbf55e1a392724313f7726c38578b5e008df6a0f", + "reference": "cbf55e1a392724313f7726c38578b5e008df6a0f", + "shasum": "" + }, + "require": { + "illuminate/console": "^8.0|^9.0", + "illuminate/contracts": "^8.0|^9.0", + "illuminate/support": "^8.0|^9.0", + "php": "^7.3|^8.0" + }, + "bin": [ + "bin/sail" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "laravel": { + "providers": [ + "Laravel\\Sail\\SailServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Sail\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Docker files for running a basic Laravel application.", + "keywords": [ + "docker", + "laravel" + ], + "support": { + "issues": "https://github.com/laravel/sail/issues", + "source": "https://github.com/laravel/sail" + }, + "time": "2022-04-14T18:29:22+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", + "reference": "c10a5f6e06fc2470ab1822fa13fa2a7380f8fbac", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "support": { + "issues": "https://github.com/mockery/mockery/issues", + "source": "https://github.com/mockery/mockery/tree/1.5.0" + }, + "time": "2022-01-20T13:18:17+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.11.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2022-03-03T13:19:32+00:00" + }, + { + "name": "nunomaduro/collision", + "version": "v6.2.0", + "source": { + "type": "git", + "url": "https://github.com/nunomaduro/collision.git", + "reference": "c379636dc50e829edb3a8bcb944a01aa1aed8f25" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nunomaduro/collision/zipball/c379636dc50e829edb3a8bcb944a01aa1aed8f25", + "reference": "c379636dc50e829edb3a8bcb944a01aa1aed8f25", + "shasum": "" + }, + "require": { + "facade/ignition-contracts": "^1.0.2", + "filp/whoops": "^2.14.5", + "php": "^8.0.0", + "symfony/console": "^6.0.2" + }, + "require-dev": { + "brianium/paratest": "^6.4.1", + "laravel/framework": "^9.7", + "nunomaduro/larastan": "^1.0.2", + "nunomaduro/mock-final-classes": "^1.1.0", + "orchestra/testbench": "^7.3.0", + "phpunit/phpunit": "^9.5.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-develop": "6.x-dev" + }, + "laravel": { + "providers": [ + "NunoMaduro\\Collision\\Adapters\\Laravel\\CollisionServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "NunoMaduro\\Collision\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nuno Maduro", + "email": "enunomaduro@gmail.com" + } + ], + "description": "Cli error handling for console/command-line PHP applications.", + "keywords": [ + "artisan", + "cli", + "command-line", + "console", + "error", + "handling", + "laravel", + "laravel-zero", + "php", + "symfony" + ], + "support": { + "issues": "https://github.com/nunomaduro/collision/issues", + "source": "https://github.com/nunomaduro/collision" + }, + "funding": [ + { + "url": "https://www.paypal.com/paypalme/enunomaduro", + "type": "custom" + }, + { + "url": "https://github.com/nunomaduro", + "type": "github" + }, + { + "url": "https://www.patreon.com/nunomaduro", + "type": "patreon" + } + ], + "time": "2022-04-05T15:31:38+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.6.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "77a32518733312af16a44300404e945338981de3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*", + "psalm/phar": "^4.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, + "time": "2022-03-15T21:29:03+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "v1.15.0", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2 || ~8.0, <8.2", + "phpdocumentor/reflection-docblock": "^5.2", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.2.15", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.13.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-07T09:28:20+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.5.20", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^3.0", + "sebastian/version": "^3.0.2" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-01T12:37:26+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:52:27+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-04-03T09:37:03+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-11-11T14:18:36+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-02-14T08:28:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:17:30+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2022-03-15T09:54:48+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "spatie/backtrace", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/spatie/backtrace.git", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/backtrace/zipball/4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "reference": "4ee7d41aa5268107906ea8a4d9ceccde136dbd5b", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "ext-json": "*", + "phpunit/phpunit": "^9.3", + "symfony/var-dumper": "^5.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Backtrace\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Freek Van de Herten", + "email": "freek@spatie.be", + "homepage": "https://spatie.be", + "role": "Developer" + } + ], + "description": "A better backtrace", + "homepage": "https://github.com/spatie/backtrace", + "keywords": [ + "Backtrace", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/backtrace/issues", + "source": "https://github.com/spatie/backtrace/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/spatie", + "type": "github" + }, + { + "url": "https://spatie.be/open-source/support-us", + "type": "other" + } + ], + "time": "2021-11-09T10:57:15+00:00" + }, + { + "name": "spatie/flare-client-php", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/spatie/flare-client-php.git", + "reference": "ceab058852a1278d9f57a7b95f1c348e4956d866" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/flare-client-php/zipball/ceab058852a1278d9f57a7b95f1c348e4956d866", + "reference": "ceab058852a1278d9f57a7b95f1c348e4956d866", + "shasum": "" + }, + "require": { + "illuminate/pipeline": "^8.0|^9.0", + "php": "^8.0", + "spatie/backtrace": "^1.2", + "symfony/http-foundation": "^5.0|^6.0", + "symfony/mime": "^5.2|^6.0", + "symfony/process": "^5.2|^6.0", + "symfony/var-dumper": "^5.2|^6.0" + }, + "require-dev": { + "dms/phpunit-arraysubset-asserts": "^0.3.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/phpunit-snapshot-assertions": "^4.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\FlareClient\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Send PHP errors to Flare", + "homepage": "https://github.com/spatie/flare-client-php", + "keywords": [ + "exception", + "flare", + "reporting", + "spatie" + ], + "support": { + "issues": "https://github.com/spatie/flare-client-php/issues", + "source": "https://github.com/spatie/flare-client-php/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-03-11T13:21:28+00:00" + }, + { + "name": "spatie/ignition", + "version": "1.2.9", + "source": { + "type": "git", + "url": "https://github.com/spatie/ignition.git", + "reference": "db25202fab2d5c14613b8914a1bb374998bbf870" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/ignition/zipball/db25202fab2d5c14613b8914a1bb374998bbf870", + "reference": "db25202fab2d5c14613b8914a1bb374998bbf870", + "shasum": "" + }, + "require": { + "ext-json": "*", + "ext-mbstring": "*", + "monolog/monolog": "^2.0", + "php": "^8.0", + "spatie/flare-client-php": "^1.1", + "symfony/console": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" + }, + "require-dev": { + "mockery/mockery": "^1.4", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "symfony/process": "^5.4|^6.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Spatie\\Ignition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for PHP applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/ignition/issues", + "source": "https://github.com/spatie/ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-04-23T20:37:21+00:00" + }, + { + "name": "spatie/laravel-ignition", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/spatie/laravel-ignition.git", + "reference": "924d1ae878874ad0bb49f63b69a9af759a34ee78" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/spatie/laravel-ignition/zipball/924d1ae878874ad0bb49f63b69a9af759a34ee78", + "reference": "924d1ae878874ad0bb49f63b69a9af759a34ee78", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "ext-json": "*", + "ext-mbstring": "*", + "illuminate/support": "^8.77|^9.0", + "monolog/monolog": "^2.3", + "php": "^8.0", + "spatie/flare-client-php": "^1.0.1", + "spatie/ignition": "^1.2.4", + "symfony/console": "^5.0|^6.0", + "symfony/var-dumper": "^5.0|^6.0" + }, + "require-dev": { + "filp/whoops": "^2.14", + "livewire/livewire": "^2.8|dev-develop", + "mockery/mockery": "^1.4", + "nunomaduro/larastan": "^1.0", + "orchestra/testbench": "^6.23|^7.0", + "pestphp/pest": "^1.20", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "spatie/laravel-ray": "^1.27" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Spatie\\LaravelIgnition\\IgnitionServiceProvider" + ], + "aliases": { + "Flare": "Spatie\\LaravelIgnition\\Facades\\Flare" + } + } + }, + "autoload": { + "files": [ + "src/helpers.php" + ], + "psr-4": { + "Spatie\\LaravelIgnition\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Spatie", + "email": "info@spatie.be", + "role": "Developer" + } + ], + "description": "A beautiful error page for Laravel applications.", + "homepage": "https://flareapp.io/ignition", + "keywords": [ + "error", + "flare", + "laravel", + "page" + ], + "support": { + "docs": "https://flareapp.io/docs/ignition-for-laravel/introduction", + "forum": "https://twitter.com/flareappio", + "issues": "https://github.com/spatie/laravel-ignition/issues", + "source": "https://github.com/spatie/laravel-ignition" + }, + "funding": [ + { + "url": "https://github.com/spatie", + "type": "github" + } + ], + "time": "2022-04-14T18:04:51+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2021-07-28T10:34:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "google/sqlcommenter-laravel": 20 + }, + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": "^8.0.2" + }, + "platform-dev": [], + "plugin-api-version": "2.2.0" +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/app.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/app.php new file mode 100644 index 00000000..f9a219ad --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/app.php @@ -0,0 +1,212 @@ + env('APP_NAME', 'Laravel'), + + /* + |-------------------------------------------------------------------------- + | Application Environment + |-------------------------------------------------------------------------- + | + | This value determines the "environment" your application is currently + | running in. This may determine how you prefer to configure various + | services the application utilizes. Set this in your ".env" file. + | + */ + + 'env' => env('APP_ENV', 'production'), + + /* + |-------------------------------------------------------------------------- + | Application Debug Mode + |-------------------------------------------------------------------------- + | + | When your application is in debug mode, detailed error messages with + | stack traces will be shown on every error that occurs within your + | application. If disabled, a simple generic error page is shown. + | + */ + + 'debug' => (bool) env('APP_DEBUG', false), + + /* + |-------------------------------------------------------------------------- + | Application URL + |-------------------------------------------------------------------------- + | + | This URL is used by the console to properly generate URLs when using + | the Artisan command line tool. You should set this to the root of + | your application so that it is used when running Artisan tasks. + | + */ + + 'url' => env('APP_URL', 'http://localhost'), + + 'asset_url' => env('ASSET_URL'), + + /* + |-------------------------------------------------------------------------- + | Application Timezone + |-------------------------------------------------------------------------- + | + | Here you may specify the default timezone for your application, which + | will be used by the PHP date and date-time functions. We have gone + | ahead and set this to a sensible default for you out of the box. + | + */ + + 'timezone' => 'UTC', + + /* + |-------------------------------------------------------------------------- + | Application Locale Configuration + |-------------------------------------------------------------------------- + | + | The application locale determines the default locale that will be used + | by the translation service provider. You are free to set this value + | to any of the locales which will be supported by the application. + | + */ + + 'locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Application Fallback Locale + |-------------------------------------------------------------------------- + | + | The fallback locale determines the locale to use when the current one + | is not available. You may change the value to correspond to any of + | the language folders that are provided through your application. + | + */ + + 'fallback_locale' => 'en', + + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + + /* + |-------------------------------------------------------------------------- + | Encryption Key + |-------------------------------------------------------------------------- + | + | This key is used by the Illuminate encrypter service and should be set + | to a random, 32 character string, otherwise these encrypted strings + | will not be safe. Please do this before deploying an application! + | + */ + + 'key' => env('APP_KEY'), + + 'cipher' => 'AES-256-CBC', + + /* + |-------------------------------------------------------------------------- + | Autoloaded Service Providers + |-------------------------------------------------------------------------- + | + | The service providers listed here will be automatically loaded on the + | request to your application. Feel free to add your own services to + | this array to grant expanded functionality to your applications. + | + */ + + 'providers' => [ + + /* + * Laravel Framework Service Providers... + */ + Illuminate\Auth\AuthServiceProvider::class, + Illuminate\Broadcasting\BroadcastServiceProvider::class, + Illuminate\Bus\BusServiceProvider::class, + Illuminate\Cache\CacheServiceProvider::class, + Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class, + Illuminate\Cookie\CookieServiceProvider::class, + Google\GoogleSqlCommenterLaravel\Database\DatabaseServiceProvider::class, + Illuminate\Database\DatabaseServiceProvider::class, + Illuminate\Encryption\EncryptionServiceProvider::class, + Illuminate\Filesystem\FilesystemServiceProvider::class, + Illuminate\Foundation\Providers\FoundationServiceProvider::class, + Illuminate\Hashing\HashServiceProvider::class, + Illuminate\Mail\MailServiceProvider::class, + Illuminate\Notifications\NotificationServiceProvider::class, + Illuminate\Pagination\PaginationServiceProvider::class, + Illuminate\Pipeline\PipelineServiceProvider::class, + Illuminate\Queue\QueueServiceProvider::class, + Illuminate\Redis\RedisServiceProvider::class, + Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, + Illuminate\Session\SessionServiceProvider::class, + Illuminate\Translation\TranslationServiceProvider::class, + Illuminate\Validation\ValidationServiceProvider::class, + Illuminate\View\ViewServiceProvider::class, + + /* + * Package Service Providers... + */ + + /* + * Application Service Providers... + */ + App\Providers\AppServiceProvider::class, + App\Providers\AuthServiceProvider::class, + // App\Providers\BroadcastServiceProvider::class, + App\Providers\EventServiceProvider::class, + App\Providers\RouteServiceProvider::class, + + ], + + /* + |-------------------------------------------------------------------------- + | Class Aliases + |-------------------------------------------------------------------------- + | + | This array of class aliases will be registered when this application + | is started. However, feel free to register as many as you wish as + | the aliases are "lazy" loaded so they don't hinder performance. + | + */ + + 'aliases' => Facade::defaultAliases()->merge([ + // 'ExampleClass' => App\Example\ExampleClass::class, + ])->toArray(), + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/auth.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/auth.php new file mode 100644 index 00000000..a202c9fa --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/auth.php @@ -0,0 +1,125 @@ + [ + 'guard' => 'web', + 'passwords' => 'users', + ], + + /* + |-------------------------------------------------------------------------- + | Authentication Guards + |-------------------------------------------------------------------------- + | + | Next, you may define every authentication guard for your application. + | Of course, a great default configuration has been defined for you + | here which uses session storage and the Eloquent user provider. + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | Supported: "session" + | + */ + + 'guards' => [ + 'web' => [ + 'driver' => 'session', + 'provider' => 'users', + ], + ], + + /* + |-------------------------------------------------------------------------- + | User Providers + |-------------------------------------------------------------------------- + | + | All authentication drivers have a user provider. This defines how the + | users are actually retrieved out of your database or other storage + | mechanisms used by this application to persist your user's data. + | + | If you have multiple user tables or models you may configure multiple + | sources which represent each model / table. These sources may then + | be assigned to any extra authentication guards you have defined. + | + | Supported: "database", "eloquent" + | + */ + + 'providers' => [ + 'users' => [ + 'driver' => 'eloquent', + 'model' => App\Models\User::class, + ], + + // 'users' => [ + // 'driver' => 'database', + // 'table' => 'users', + // ], + ], + + /* + |-------------------------------------------------------------------------- + | Resetting Passwords + |-------------------------------------------------------------------------- + | + | You may specify multiple password reset configurations if you have more + | than one user table or model in the application and you want to have + | separate password reset settings based on the specific user types. + | + | The expire time is the number of minutes that each reset token will be + | considered valid. This security feature keeps tokens short-lived so + | they have less time to be guessed. You may change this as needed. + | + */ + + 'passwords' => [ + 'users' => [ + 'provider' => 'users', + 'table' => 'password_resets', + 'expire' => 60, + 'throttle' => 60, + ], + ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => 10800, + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/broadcasting.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/broadcasting.php new file mode 100644 index 00000000..89463e55 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/broadcasting.php @@ -0,0 +1,81 @@ + env('BROADCAST_DRIVER', 'null'), + + /* + |-------------------------------------------------------------------------- + | Broadcast Connections + |-------------------------------------------------------------------------- + | + | Here you may define all of the broadcast connections that will be used + | to broadcast events to other systems or over websockets. Samples of + | each available type of connection are provided inside this array. + | + */ + + 'connections' => [ + + 'pusher' => [ + 'driver' => 'pusher', + 'key' => env('PUSHER_APP_KEY'), + 'secret' => env('PUSHER_APP_SECRET'), + 'app_id' => env('PUSHER_APP_ID'), + 'options' => [ + 'cluster' => env('PUSHER_APP_CLUSTER'), + 'useTLS' => true, + ], + 'client_options' => [ + // Guzzle client options: https://docs.guzzlephp.org/en/stable/request-options.html + ], + ], + + 'ably' => [ + 'driver' => 'ably', + 'key' => env('ABLY_KEY'), + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + ], + + 'log' => [ + 'driver' => 'log', + ], + + 'null' => [ + 'driver' => 'null', + ], + + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cache.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cache.php new file mode 100644 index 00000000..8cf23409 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cache.php @@ -0,0 +1,124 @@ + env('CACHE_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Cache Stores + |-------------------------------------------------------------------------- + | + | Here you may define all of the cache "stores" for your application as + | well as their drivers. You may even define multiple stores for the + | same cache driver to group types of items stored in your caches. + | + | Supported drivers: "apc", "array", "database", "file", + | "memcached", "redis", "dynamodb", "octane", "null" + | + */ + + 'stores' => [ + + 'apc' => [ + 'driver' => 'apc', + ], + + 'array' => [ + 'driver' => 'array', + 'serialize' => false, + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'cache', + 'connection' => null, + 'lock_connection' => null, + ], + + 'file' => [ + 'driver' => 'file', + 'path' => storage_path('framework/cache/data'), + ], + + 'memcached' => [ + 'driver' => 'memcached', + 'persistent_id' => env('MEMCACHED_PERSISTENT_ID'), + 'sasl' => [ + env('MEMCACHED_USERNAME'), + env('MEMCACHED_PASSWORD'), + ], + 'options' => [ + // Memcached::OPT_CONNECT_TIMEOUT => 2000, + ], + 'servers' => [ + [ + 'host' => env('MEMCACHED_HOST', '127.0.0.1'), + 'port' => env('MEMCACHED_PORT', 11211), + 'weight' => 100, + ], + ], + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'cache', + 'lock_connection' => 'default', + ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], + + 'octane' => [ + 'driver' => 'octane', + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Cache Key Prefix + |-------------------------------------------------------------------------- + | + | When utilizing the APC, database, memcached, Redis, or DynamoDB cache + | stores there might be other applications using the same cache. For + | that reason, you may prefix every cache key to avoid collisions. + | + */ + + 'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_cache_'), + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cors.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cors.php new file mode 100644 index 00000000..19520c9a --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/cors.php @@ -0,0 +1,48 @@ + ['api/*', 'sanctum/csrf-cookie'], + + 'allowed_methods' => ['*'], + + 'allowed_origins' => ['*'], + + 'allowed_origins_patterns' => [], + + 'allowed_headers' => ['*'], + + 'exposed_headers' => [], + + 'max_age' => 0, + + 'supports_credentials' => false, + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/database.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/database.php new file mode 100644 index 00000000..1aedd801 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/database.php @@ -0,0 +1,165 @@ + env('DB_CONNECTION', 'mysql'), + + /* + |-------------------------------------------------------------------------- + | Database Connections + |-------------------------------------------------------------------------- + | + | Here are each of the database connections setup for your application. + | Of course, examples of configuring each database platform that is + | supported by Laravel is shown below to make development simple. + | + | + | All database work in Laravel is done through the PHP PDO facilities + | so make sure you have the driver for your particular database of + | choice installed on your machine before you begin development. + | + */ + + 'connections' => [ + + 'sqlite' => [ + 'driver' => 'sqlite', + 'url' => env('DATABASE_URL'), + 'database' => env('DB_DATABASE', database_path('database.sqlite')), + 'prefix' => '', + 'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true), + ], + + 'mysql' => [ + 'driver' => 'mysql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '3306'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'unix_socket' => env('DB_SOCKET', ''), + 'charset' => 'utf8mb4', + 'collation' => 'utf8mb4_unicode_ci', + 'prefix' => '', + 'prefix_indexes' => true, + 'strict' => true, + 'engine' => null, + 'options' => extension_loaded('pdo_mysql') ? array_filter([ + PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'), + ]) : [], + ], + + 'pgsql' => [ + 'driver' => 'pgsql', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', '127.0.0.1'), + 'port' => env('DB_PORT', '5432'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + 'search_path' => 'public', + 'sslmode' => 'prefer', + ], + + 'sqlsrv' => [ + 'driver' => 'sqlsrv', + 'url' => env('DATABASE_URL'), + 'host' => env('DB_HOST', 'localhost'), + 'port' => env('DB_PORT', '1433'), + 'database' => env('DB_DATABASE', 'forge'), + 'username' => env('DB_USERNAME', 'forge'), + 'password' => env('DB_PASSWORD', ''), + 'charset' => 'utf8', + 'prefix' => '', + 'prefix_indexes' => true, + // 'encrypt' => env('DB_ENCRYPT', 'yes'), + // 'trust_server_certificate' => env('DB_TRUST_SERVER_CERTIFICATE', 'false'), + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Migration Repository Table + |-------------------------------------------------------------------------- + | + | This table keeps track of all the migrations that have already run for + | your application. Using this information, we can determine which of + | the migrations on disk haven't actually been run in the database. + | + */ + + 'migrations' => 'migrations', + + /* + |-------------------------------------------------------------------------- + | Redis Databases + |-------------------------------------------------------------------------- + | + | Redis is an open source, fast, and advanced key-value store that also + | provides a richer body of commands than a typical key-value system + | such as APC or Memcached. Laravel makes it easy to dig right in. + | + */ + + 'redis' => [ + + 'client' => env('REDIS_CLIENT', 'phpredis'), + + 'options' => [ + 'cluster' => env('REDIS_CLUSTER', 'redis'), + 'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'), + ], + + 'default' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_DB', '0'), + ], + + 'cache' => [ + 'url' => env('REDIS_URL'), + 'host' => env('REDIS_HOST', '127.0.0.1'), + 'username' => env('REDIS_USERNAME'), + 'password' => env('REDIS_PASSWORD'), + 'port' => env('REDIS_PORT', '6379'), + 'database' => env('REDIS_CACHE_DB', '1'), + ], + + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/filesystems.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/filesystems.php new file mode 100644 index 00000000..55d3f8a4 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/filesystems.php @@ -0,0 +1,90 @@ + env('FILESYSTEM_DISK', 'local'), + + /* + |-------------------------------------------------------------------------- + | Filesystem Disks + |-------------------------------------------------------------------------- + | + | Here you may configure as many filesystem "disks" as you wish, and you + | may even configure multiple disks of the same driver. Defaults have + | been set up for each driver as an example of the required values. + | + | Supported Drivers: "local", "ftp", "sftp", "s3" + | + */ + + 'disks' => [ + + 'local' => [ + 'driver' => 'local', + 'root' => storage_path('app'), + 'throw' => false, + ], + + 'public' => [ + 'driver' => 'local', + 'root' => storage_path('app/public'), + 'url' => env('APP_URL').'/storage', + 'visibility' => 'public', + 'throw' => false, + ], + + 's3' => [ + 'driver' => 's3', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION'), + 'bucket' => env('AWS_BUCKET'), + 'url' => env('AWS_URL'), + 'endpoint' => env('AWS_ENDPOINT'), + 'use_path_style_endpoint' => env('AWS_USE_PATH_STYLE_ENDPOINT', false), + 'throw' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Symbolic Links + |-------------------------------------------------------------------------- + | + | Here you may configure the symbolic links that will be created when the + | `storage:link` Artisan command is executed. The array keys should be + | the locations of the links and the values should be their targets. + | + */ + + 'links' => [ + public_path('storage') => storage_path('app/public'), + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/hashing.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/hashing.php new file mode 100644 index 00000000..fbb9ba03 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/hashing.php @@ -0,0 +1,66 @@ + 'bcrypt', + + /* + |-------------------------------------------------------------------------- + | Bcrypt Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Bcrypt algorithm. This will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'bcrypt' => [ + 'rounds' => env('BCRYPT_ROUNDS', 10), + ], + + /* + |-------------------------------------------------------------------------- + | Argon Options + |-------------------------------------------------------------------------- + | + | Here you may specify the configuration options that should be used when + | passwords are hashed using the Argon algorithm. These will allow you + | to control the amount of time it takes to hash the given password. + | + */ + + 'argon' => [ + 'memory' => 65536, + 'threads' => 1, + 'time' => 4, + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/logging.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/logging.php new file mode 100644 index 00000000..73509a72 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/logging.php @@ -0,0 +1,133 @@ + env('LOG_CHANNEL', 'stack'), + + /* + |-------------------------------------------------------------------------- + | Deprecations Log Channel + |-------------------------------------------------------------------------- + | + | This option controls the log channel that should be used to log warnings + | regarding deprecated PHP and library features. This allows you to get + | your application ready for upcoming major versions of dependencies. + | + */ + + 'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'), + + /* + |-------------------------------------------------------------------------- + | Log Channels + |-------------------------------------------------------------------------- + | + | Here you may configure the log channels for your application. Out of + | the box, Laravel uses the Monolog PHP logging library. This gives + | you a variety of powerful log handlers / formatters to utilize. + | + | Available Drivers: "single", "daily", "slack", "syslog", + | "errorlog", "monolog", + | "custom", "stack" + | + */ + + 'channels' => [ + 'stack' => [ + 'driver' => 'stack', + 'channels' => ['single'], + 'ignore_exceptions' => false, + ], + + 'single' => [ + 'driver' => 'single', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'daily' => [ + 'driver' => 'daily', + 'path' => storage_path('logs/laravel.log'), + 'level' => env('LOG_LEVEL', 'debug'), + 'days' => 14, + ], + + 'slack' => [ + 'driver' => 'slack', + 'url' => env('LOG_SLACK_WEBHOOK_URL'), + 'username' => 'Laravel Log', + 'emoji' => ':boom:', + 'level' => env('LOG_LEVEL', 'critical'), + ], + + 'papertrail' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => env('LOG_PAPERTRAIL_HANDLER', SyslogUdpHandler::class), + 'handler_with' => [ + 'host' => env('PAPERTRAIL_URL'), + 'port' => env('PAPERTRAIL_PORT'), + 'connectionString' => 'tls://'.env('PAPERTRAIL_URL').':'.env('PAPERTRAIL_PORT'), + ], + ], + + 'stderr' => [ + 'driver' => 'monolog', + 'level' => env('LOG_LEVEL', 'debug'), + 'handler' => StreamHandler::class, + 'formatter' => env('LOG_STDERR_FORMATTER'), + 'with' => [ + 'stream' => 'php://stderr', + ], + ], + + 'syslog' => [ + 'driver' => 'syslog', + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'errorlog' => [ + 'driver' => 'errorlog', + 'level' => env('LOG_LEVEL', 'debug'), + ], + + 'null' => [ + 'driver' => 'monolog', + 'handler' => NullHandler::class, + ], + + 'emergency' => [ + 'path' => storage_path('logs/laravel.log'), + ], + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/mail.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/mail.php new file mode 100644 index 00000000..ae6fb52a --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/mail.php @@ -0,0 +1,131 @@ + env('MAIL_MAILER', 'smtp'), + + /* + |-------------------------------------------------------------------------- + | Mailer Configurations + |-------------------------------------------------------------------------- + | + | Here you may configure all of the mailers used by your application plus + | their respective settings. Several examples have been configured for + | you and you are free to add your own as your application requires. + | + | Laravel supports a variety of mail "transport" drivers to be used while + | sending an e-mail. You will specify which one you are using for your + | mailers below. You are free to add additional mailers as required. + | + | Supported: "smtp", "sendmail", "mailgun", "ses", + | "postmark", "log", "array", "failover" + | + */ + + 'mailers' => [ + 'smtp' => [ + 'transport' => 'smtp', + 'host' => env('MAIL_HOST', 'smtp.mailgun.org'), + 'port' => env('MAIL_PORT', 587), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + ], + + 'ses' => [ + 'transport' => 'ses', + ], + + 'mailgun' => [ + 'transport' => 'mailgun', + ], + + 'postmark' => [ + 'transport' => 'postmark', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => env('MAIL_SENDMAIL_PATH', '/usr/sbin/sendmail -bs -i'), + ], + + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL'), + ], + + 'array' => [ + 'transport' => 'array', + ], + + 'failover' => [ + 'transport' => 'failover', + 'mailers' => [ + 'smtp', + 'log', + ], + ], + ], + + /* + |-------------------------------------------------------------------------- + | Global "From" Address + |-------------------------------------------------------------------------- + | + | You may wish for all e-mails sent by your application to be sent from + | the same address. Here, you may specify a name and address that is + | used globally for all e-mails that are sent by your application. + | + */ + + 'from' => [ + 'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'), + 'name' => env('MAIL_FROM_NAME', 'Example'), + ], + + /* + |-------------------------------------------------------------------------- + | Markdown Mail Settings + |-------------------------------------------------------------------------- + | + | If you are using Markdown based email rendering, you may configure your + | theme and component paths here, allowing you to customize the design + | of the emails. Or, you may simply stick with the Laravel defaults! + | + */ + + 'markdown' => [ + 'theme' => 'default', + + 'paths' => [ + resource_path('views/vendor/mail'), + ], + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/queue.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/queue.php new file mode 100644 index 00000000..4419ab5a --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/queue.php @@ -0,0 +1,107 @@ + env('QUEUE_CONNECTION', 'sync'), + + /* + |-------------------------------------------------------------------------- + | Queue Connections + |-------------------------------------------------------------------------- + | + | Here you may configure the connection information for each server that + | is used by your application. A default configuration has been added + | for each back-end shipped with Laravel. You are free to add more. + | + | Drivers: "sync", "database", "beanstalkd", "sqs", "redis", "null" + | + */ + + 'connections' => [ + + 'sync' => [ + 'driver' => 'sync', + ], + + 'database' => [ + 'driver' => 'database', + 'table' => 'jobs', + 'queue' => 'default', + 'retry_after' => 90, + 'after_commit' => false, + ], + + 'beanstalkd' => [ + 'driver' => 'beanstalkd', + 'host' => 'localhost', + 'queue' => 'default', + 'retry_after' => 90, + 'block_for' => 0, + 'after_commit' => false, + ], + + 'sqs' => [ + 'driver' => 'sqs', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'prefix' => env('SQS_PREFIX', 'https://sqs.us-east-1.amazonaws.com/your-account-id'), + 'queue' => env('SQS_QUEUE', 'default'), + 'suffix' => env('SQS_SUFFIX'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'after_commit' => false, + ], + + 'redis' => [ + 'driver' => 'redis', + 'connection' => 'default', + 'queue' => env('REDIS_QUEUE', 'default'), + 'retry_after' => 90, + 'block_for' => null, + 'after_commit' => false, + ], + + ], + + /* + |-------------------------------------------------------------------------- + | Failed Queue Jobs + |-------------------------------------------------------------------------- + | + | These options configure the behavior of failed queue job logging so you + | can control which database and table are used to store the jobs that + | have failed. You may change them to any database / table you wish. + | + */ + + 'failed' => [ + 'driver' => env('QUEUE_FAILED_DRIVER', 'database-uuids'), + 'database' => env('DB_CONNECTION', 'mysql'), + 'table' => 'failed_jobs', + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/sanctum.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/sanctum.php new file mode 100644 index 00000000..bdfe0e8e --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/sanctum.php @@ -0,0 +1,81 @@ + explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf( + '%s%s', + 'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1', + Sanctum::currentApplicationUrlWithPort() + ))), + + /* + |-------------------------------------------------------------------------- + | Sanctum Guards + |-------------------------------------------------------------------------- + | + | This array contains the authentication guards that will be checked when + | Sanctum is trying to authenticate a request. If none of these guards + | are able to authenticate the request, Sanctum will use the bearer + | token that's present on an incoming request for authentication. + | + */ + + 'guard' => ['web'], + + /* + |-------------------------------------------------------------------------- + | Expiration Minutes + |-------------------------------------------------------------------------- + | + | This value controls the number of minutes until an issued token will be + | considered expired. If this value is null, personal access tokens do + | not expire. This won't tweak the lifetime of first-party sessions. + | + */ + + 'expiration' => null, + + /* + |-------------------------------------------------------------------------- + | Sanctum Middleware + |-------------------------------------------------------------------------- + | + | When authenticating your first-party SPA with Sanctum you may need to + | customize some of the middleware Sanctum uses while processing the + | request. You may change the middleware listed below as required. + | + */ + + 'middleware' => [ + 'verify_csrf_token' => App\Http\Middleware\VerifyCsrfToken::class, + 'encrypt_cookies' => App\Http\Middleware\EncryptCookies::class, + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/services.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/services.php new file mode 100644 index 00000000..2c734ffe --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/services.php @@ -0,0 +1,48 @@ + [ + 'domain' => env('MAILGUN_DOMAIN'), + 'secret' => env('MAILGUN_SECRET'), + 'endpoint' => env('MAILGUN_ENDPOINT', 'api.mailgun.net'), + 'scheme' => 'https', + ], + + 'postmark' => [ + 'token' => env('POSTMARK_TOKEN'), + ], + + 'ses' => [ + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + ], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/session.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/session.php new file mode 100644 index 00000000..ce1fc200 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/session.php @@ -0,0 +1,215 @@ + env('SESSION_DRIVER', 'file'), + + /* + |-------------------------------------------------------------------------- + | Session Lifetime + |-------------------------------------------------------------------------- + | + | Here you may specify the number of minutes that you wish the session + | to be allowed to remain idle before it expires. If you want them + | to immediately expire on the browser closing, set that option. + | + */ + + 'lifetime' => env('SESSION_LIFETIME', 120), + + 'expire_on_close' => false, + + /* + |-------------------------------------------------------------------------- + | Session Encryption + |-------------------------------------------------------------------------- + | + | This option allows you to easily specify that all of your session data + | should be encrypted before it is stored. All encryption will be run + | automatically by Laravel and you can use the Session like normal. + | + */ + + 'encrypt' => false, + + /* + |-------------------------------------------------------------------------- + | Session File Location + |-------------------------------------------------------------------------- + | + | When using the native session driver, we need a location where session + | files may be stored. A default has been set for you but a different + | location may be specified. This is only needed for file sessions. + | + */ + + 'files' => storage_path('framework/sessions'), + + /* + |-------------------------------------------------------------------------- + | Session Database Connection + |-------------------------------------------------------------------------- + | + | When using the "database" or "redis" session drivers, you may specify a + | connection that should be used to manage these sessions. This should + | correspond to a connection in your database configuration options. + | + */ + + 'connection' => env('SESSION_CONNECTION'), + + /* + |-------------------------------------------------------------------------- + | Session Database Table + |-------------------------------------------------------------------------- + | + | When using the "database" session driver, you may specify the table we + | should use to manage the sessions. Of course, a sensible default is + | provided for you; however, you are free to change this as needed. + | + */ + + 'table' => 'sessions', + + /* + |-------------------------------------------------------------------------- + | Session Cache Store + |-------------------------------------------------------------------------- + | + | While using one of the framework's cache driven session backends you may + | list a cache store that should be used for these sessions. This value + | must match with one of the application's configured cache "stores". + | + | Affects: "apc", "dynamodb", "memcached", "redis" + | + */ + + 'store' => env('SESSION_STORE'), + + /* + |-------------------------------------------------------------------------- + | Session Sweeping Lottery + |-------------------------------------------------------------------------- + | + | Some session drivers must manually sweep their storage location to get + | rid of old sessions from storage. Here are the chances that it will + | happen on a given request. By default, the odds are 2 out of 100. + | + */ + + 'lottery' => [2, 100], + + /* + |-------------------------------------------------------------------------- + | Session Cookie Name + |-------------------------------------------------------------------------- + | + | Here you may change the name of the cookie used to identify a session + | instance by ID. The name specified here will get used every time a + | new session cookie is created by the framework for every driver. + | + */ + + 'cookie' => env( + 'SESSION_COOKIE', + Str::slug(env('APP_NAME', 'laravel'), '_').'_session' + ), + + /* + |-------------------------------------------------------------------------- + | Session Cookie Path + |-------------------------------------------------------------------------- + | + | The session cookie path determines the path for which the cookie will + | be regarded as available. Typically, this will be the root path of + | your application but you are free to change this when necessary. + | + */ + + 'path' => '/', + + /* + |-------------------------------------------------------------------------- + | Session Cookie Domain + |-------------------------------------------------------------------------- + | + | Here you may change the domain of the cookie used to identify a session + | in your application. This will determine which domains the cookie is + | available to in your application. A sensible default has been set. + | + */ + + 'domain' => env('SESSION_DOMAIN'), + + /* + |-------------------------------------------------------------------------- + | HTTPS Only Cookies + |-------------------------------------------------------------------------- + | + | By setting this option to true, session cookies will only be sent back + | to the server if the browser has a HTTPS connection. This will keep + | the cookie from being sent to you when it can't be done securely. + | + */ + + 'secure' => env('SESSION_SECURE_COOKIE'), + + /* + |-------------------------------------------------------------------------- + | HTTP Access Only + |-------------------------------------------------------------------------- + | + | Setting this value to true will prevent JavaScript from accessing the + | value of the cookie and the cookie will only be accessible through + | the HTTP protocol. You are free to modify this option if needed. + | + */ + + 'http_only' => true, + + /* + |-------------------------------------------------------------------------- + | Same-Site Cookies + |-------------------------------------------------------------------------- + | + | This option determines how your cookies behave when cross-site requests + | take place, and can be used to mitigate CSRF attacks. By default, we + | will set this value to "lax" since this is a secure default value. + | + | Supported: "lax", "strict", "none", null + | + */ + + 'same_site' => 'lax', + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/view.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/view.php new file mode 100644 index 00000000..ebe2032f --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/config/view.php @@ -0,0 +1,50 @@ + [ + resource_path('views'), + ], + + /* + |-------------------------------------------------------------------------- + | Compiled View Path + |-------------------------------------------------------------------------- + | + | This option determines where all the compiled Blade templates will be + | stored for your application. Typically, this is within the storage + | directory. However, as usual, you are free to change this value. + | + */ + + 'compiled' => env( + 'VIEW_COMPILED_PATH', + realpath(storage_path('framework/views')) + ), + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/.gitignore b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/.gitignore new file mode 100644 index 00000000..9b19b93c --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/.gitignore @@ -0,0 +1 @@ +*.sqlite* diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/factories/UserFactory.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/factories/UserFactory.php new file mode 100644 index 00000000..8c14c750 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/factories/UserFactory.php @@ -0,0 +1,56 @@ + + */ +class UserFactory extends Factory +{ + /** + * Define the model's default state. + * + * @return array + */ + public function definition() + { + return [ + 'name' => $this->faker->name(), + 'email' => $this->faker->unique()->safeEmail(), + 'email_verified_at' => now(), + 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password + 'remember_token' => Str::random(10), + ]; + } + + /** + * Indicate that the model's email address should be unverified. + * + * @return static + */ + public function unverified() + { + return $this->state(function (array $attributes) { + return [ + 'email_verified_at' => null, + ]; + }); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_000000_create_users_table.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_000000_create_users_table.php new file mode 100644 index 00000000..cf6b7766 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_000000_create_users_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('name'); + $table->string('email')->unique(); + $table->timestamp('email_verified_at')->nullable(); + $table->string('password'); + $table->rememberToken(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('users'); + } +}; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_100000_create_password_resets_table.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_100000_create_password_resets_table.php new file mode 100644 index 00000000..fcacb80b --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2014_10_12_100000_create_password_resets_table.php @@ -0,0 +1,32 @@ +string('email')->index(); + $table->string('token'); + $table->timestamp('created_at')->nullable(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('password_resets'); + } +}; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_08_19_000000_create_failed_jobs_table.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_08_19_000000_create_failed_jobs_table.php new file mode 100644 index 00000000..17191986 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_08_19_000000_create_failed_jobs_table.php @@ -0,0 +1,36 @@ +id(); + $table->string('uuid')->unique(); + $table->text('connection'); + $table->text('queue'); + $table->longText('payload'); + $table->longText('exception'); + $table->timestamp('failed_at')->useCurrent(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('failed_jobs'); + } +}; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php new file mode 100644 index 00000000..fd235f8c --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/migrations/2019_12_14_000001_create_personal_access_tokens_table.php @@ -0,0 +1,36 @@ +id(); + $table->morphs('tokenable'); + $table->string('name'); + $table->string('token', 64)->unique(); + $table->text('abilities')->nullable(); + $table->timestamp('last_used_at')->nullable(); + $table->timestamps(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('personal_access_tokens'); + } +}; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/seeders/DatabaseSeeder.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/seeders/DatabaseSeeder.php new file mode 100644 index 00000000..5c5201b4 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/database/seeders/DatabaseSeeder.php @@ -0,0 +1,33 @@ +create(); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en.json b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en.json new file mode 100644 index 00000000..577680dd --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en.json @@ -0,0 +1,7 @@ +{ + "The :attribute must contain at least one letter.": "The :attribute must contain at least one letter.", + "The :attribute must contain at least one number.": "The :attribute must contain at least one number.", + "The :attribute must contain at least one symbol.": "The :attribute must contain at least one symbol.", + "The :attribute must contain at least one uppercase and one lowercase letter.": "The :attribute must contain at least one uppercase and one lowercase letter.", + "The given :attribute has appeared in a data leak. Please choose a different :attribute.": "The given :attribute has appeared in a data leak. Please choose a different :attribute." +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/auth.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/auth.php new file mode 100644 index 00000000..ae73db40 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/auth.php @@ -0,0 +1,34 @@ + 'These credentials do not match our records.', + 'password' => 'The provided password is incorrect.', + 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/pagination.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/pagination.php new file mode 100644 index 00000000..8f9c613b --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/pagination.php @@ -0,0 +1,33 @@ + '« Previous', + 'next' => 'Next »', + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/passwords.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/passwords.php new file mode 100644 index 00000000..be839d23 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/passwords.php @@ -0,0 +1,36 @@ + 'Your password has been reset!', + 'sent' => 'We have emailed your password reset link!', + 'throttled' => 'Please wait before retrying.', + 'token' => 'This password reset token is invalid.', + 'user' => "We can't find a user with that email address.", + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/validation.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/validation.php new file mode 100644 index 00000000..e8e087e8 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/lang/en/validation.php @@ -0,0 +1,176 @@ + 'The :attribute must be accepted.', + 'accepted_if' => 'The :attribute must be accepted when :other is :value.', + 'active_url' => 'The :attribute is not a valid URL.', + 'after' => 'The :attribute must be a date after :date.', + 'after_or_equal' => 'The :attribute must be a date after or equal to :date.', + 'alpha' => 'The :attribute must only contain letters.', + 'alpha_dash' => 'The :attribute must only contain letters, numbers, dashes and underscores.', + 'alpha_num' => 'The :attribute must only contain letters and numbers.', + 'array' => 'The :attribute must be an array.', + 'before' => 'The :attribute must be a date before :date.', + 'before_or_equal' => 'The :attribute must be a date before or equal to :date.', + 'between' => [ + 'array' => 'The :attribute must have between :min and :max items.', + 'file' => 'The :attribute must be between :min and :max kilobytes.', + 'numeric' => 'The :attribute must be between :min and :max.', + 'string' => 'The :attribute must be between :min and :max characters.', + ], + 'boolean' => 'The :attribute field must be true or false.', + 'confirmed' => 'The :attribute confirmation does not match.', + 'current_password' => 'The password is incorrect.', + 'date' => 'The :attribute is not a valid date.', + 'date_equals' => 'The :attribute must be a date equal to :date.', + 'date_format' => 'The :attribute does not match the format :format.', + 'declined' => 'The :attribute must be declined.', + 'declined_if' => 'The :attribute must be declined when :other is :value.', + 'different' => 'The :attribute and :other must be different.', + 'digits' => 'The :attribute must be :digits digits.', + 'digits_between' => 'The :attribute must be between :min and :max digits.', + 'dimensions' => 'The :attribute has invalid image dimensions.', + 'distinct' => 'The :attribute field has a duplicate value.', + 'email' => 'The :attribute must be a valid email address.', + 'ends_with' => 'The :attribute must end with one of the following: :values.', + 'enum' => 'The selected :attribute is invalid.', + 'exists' => 'The selected :attribute is invalid.', + 'file' => 'The :attribute must be a file.', + 'filled' => 'The :attribute field must have a value.', + 'gt' => [ + 'array' => 'The :attribute must have more than :value items.', + 'file' => 'The :attribute must be greater than :value kilobytes.', + 'numeric' => 'The :attribute must be greater than :value.', + 'string' => 'The :attribute must be greater than :value characters.', + ], + 'gte' => [ + 'array' => 'The :attribute must have :value items or more.', + 'file' => 'The :attribute must be greater than or equal to :value kilobytes.', + 'numeric' => 'The :attribute must be greater than or equal to :value.', + 'string' => 'The :attribute must be greater than or equal to :value characters.', + ], + 'image' => 'The :attribute must be an image.', + 'in' => 'The selected :attribute is invalid.', + 'in_array' => 'The :attribute field does not exist in :other.', + 'integer' => 'The :attribute must be an integer.', + 'ip' => 'The :attribute must be a valid IP address.', + 'ipv4' => 'The :attribute must be a valid IPv4 address.', + 'ipv6' => 'The :attribute must be a valid IPv6 address.', + 'json' => 'The :attribute must be a valid JSON string.', + 'lt' => [ + 'array' => 'The :attribute must have less than :value items.', + 'file' => 'The :attribute must be less than :value kilobytes.', + 'numeric' => 'The :attribute must be less than :value.', + 'string' => 'The :attribute must be less than :value characters.', + ], + 'lte' => [ + 'array' => 'The :attribute must not have more than :value items.', + 'file' => 'The :attribute must be less than or equal to :value kilobytes.', + 'numeric' => 'The :attribute must be less than or equal to :value.', + 'string' => 'The :attribute must be less than or equal to :value characters.', + ], + 'mac_address' => 'The :attribute must be a valid MAC address.', + 'max' => [ + 'array' => 'The :attribute must not have more than :max items.', + 'file' => 'The :attribute must not be greater than :max kilobytes.', + 'numeric' => 'The :attribute must not be greater than :max.', + 'string' => 'The :attribute must not be greater than :max characters.', + ], + 'mimes' => 'The :attribute must be a file of type: :values.', + 'mimetypes' => 'The :attribute must be a file of type: :values.', + 'min' => [ + 'array' => 'The :attribute must have at least :min items.', + 'file' => 'The :attribute must be at least :min kilobytes.', + 'numeric' => 'The :attribute must be at least :min.', + 'string' => 'The :attribute must be at least :min characters.', + ], + 'multiple_of' => 'The :attribute must be a multiple of :value.', + 'not_in' => 'The selected :attribute is invalid.', + 'not_regex' => 'The :attribute format is invalid.', + 'numeric' => 'The :attribute must be a number.', + 'present' => 'The :attribute field must be present.', + 'prohibited' => 'The :attribute field is prohibited.', + 'prohibited_if' => 'The :attribute field is prohibited when :other is :value.', + 'prohibited_unless' => 'The :attribute field is prohibited unless :other is in :values.', + 'prohibits' => 'The :attribute field prohibits :other from being present.', + 'regex' => 'The :attribute format is invalid.', + 'required' => 'The :attribute field is required.', + 'required_array_keys' => 'The :attribute field must contain entries for: :values.', + 'required_if' => 'The :attribute field is required when :other is :value.', + 'required_unless' => 'The :attribute field is required unless :other is in :values.', + 'required_with' => 'The :attribute field is required when :values is present.', + 'required_with_all' => 'The :attribute field is required when :values are present.', + 'required_without' => 'The :attribute field is required when :values is not present.', + 'required_without_all' => 'The :attribute field is required when none of :values are present.', + 'same' => 'The :attribute and :other must match.', + 'size' => [ + 'array' => 'The :attribute must contain :size items.', + 'file' => 'The :attribute must be :size kilobytes.', + 'numeric' => 'The :attribute must be :size.', + 'string' => 'The :attribute must be :size characters.', + ], + 'starts_with' => 'The :attribute must start with one of the following: :values.', + 'string' => 'The :attribute must be a string.', + 'timezone' => 'The :attribute must be a valid timezone.', + 'unique' => 'The :attribute has already been taken.', + 'uploaded' => 'The :attribute failed to upload.', + 'url' => 'The :attribute must be a valid URL.', + 'uuid' => 'The :attribute must be a valid UUID.', + + /* + |-------------------------------------------------------------------------- + | Custom Validation Language Lines + |-------------------------------------------------------------------------- + | + | Here you may specify custom validation messages for attributes using the + | convention "attribute.rule" to name the lines. This makes it quick to + | specify a specific custom language line for a given attribute rule. + | + */ + + 'custom' => [ + 'attribute-name' => [ + 'rule-name' => 'custom-message', + ], + ], + + /* + |-------------------------------------------------------------------------- + | Custom Validation Attributes + |-------------------------------------------------------------------------- + | + | The following language lines are used to swap our attribute placeholder + | with something more reader friendly such as "E-Mail Address" instead + | of "email". This simply helps us make our message more expressive. + | + */ + + 'attributes' => [], + +]; diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/package.json b/php/sqlcommenter-php/samples/sqlcommenter-laravel/package.json new file mode 100644 index 00000000..7a9aecdf --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/package.json @@ -0,0 +1,18 @@ +{ + "private": true, + "scripts": { + "dev": "npm run development", + "development": "mix", + "watch": "mix watch", + "watch-poll": "mix watch -- --watch-options-poll=1000", + "hot": "mix watch --hot", + "prod": "npm run production", + "production": "mix --production" + }, + "devDependencies": { + "axios": "^0.25", + "laravel-mix": "^6.0.6", + "lodash": "^4.17.19", + "postcss": "^8.1.14" + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/phpunit.xml b/php/sqlcommenter-php/samples/sqlcommenter-laravel/phpunit.xml new file mode 100644 index 00000000..2ac86a18 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/phpunit.xml @@ -0,0 +1,31 @@ + + + + + ./tests/Unit + + + ./tests/Feature + + + + + ./app + + + + + + + + + + + + + + diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/.htaccess b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/.htaccess new file mode 100644 index 00000000..3aec5e27 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/.htaccess @@ -0,0 +1,21 @@ + + + Options -MultiViews -Indexes + + + RewriteEngine On + + # Handle Authorization Header + RewriteCond %{HTTP:Authorization} . + RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}] + + # Redirect Trailing Slashes If Not A Folder... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_URI} (.+)/$ + RewriteRule ^ %1 [L,R=301] + + # Send Requests To Front Controller... + RewriteCond %{REQUEST_FILENAME} !-d + RewriteCond %{REQUEST_FILENAME} !-f + RewriteRule ^ index.php [L] + diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/favicon.ico b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/favicon.ico new file mode 100644 index 00000000..e69de29b diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/index.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/index.php new file mode 100644 index 00000000..0acb12fa --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/index.php @@ -0,0 +1,69 @@ +make(Kernel::class); + +$response = $kernel->handle( + $request = Request::capture() +)->send(); + +$kernel->terminate($request, $response); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/robots.txt b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/robots.txt new file mode 100644 index 00000000..eb053628 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/css/app.css b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/css/app.css new file mode 100644 index 00000000..e69de29b diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/app.js b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/app.js new file mode 100644 index 00000000..40c55f65 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/app.js @@ -0,0 +1 @@ +require('./bootstrap'); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/bootstrap.js b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/bootstrap.js new file mode 100644 index 00000000..69225776 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/js/bootstrap.js @@ -0,0 +1,28 @@ +window._ = require('lodash'); + +/** + * We'll load the axios HTTP library which allows us to easily issue requests + * to our Laravel back-end. This library automatically handles sending the + * CSRF token as a header based on the value of the "XSRF" token cookie. + */ + +window.axios = require('axios'); + +window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'; + +/** + * Echo exposes an expressive API for subscribing to channels and listening + * for events that are broadcast by Laravel. Echo and event broadcasting + * allows your team to easily build robust real-time web applications. + */ + +// import Echo from 'laravel-echo'; + +// window.Pusher = require('pusher-js'); + +// window.Echo = new Echo({ +// broadcaster: 'pusher', +// key: process.env.MIX_PUSHER_APP_KEY, +// cluster: process.env.MIX_PUSHER_APP_CLUSTER, +// forceTLS: true +// }); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/views/welcome.blade.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/views/welcome.blade.php new file mode 100644 index 00000000..dd6a45db --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/resources/views/welcome.blade.php @@ -0,0 +1,132 @@ + + + + + + + Laravel + + + + + + + + + + +
+ @if (Route::has('login')) + + @endif + +
+
+ + + + + +
+ +
+
+
+ + +
+
+ Laravel has wonderful, thorough documentation covering every aspect of the framework. Whether you are new to the framework or have previous experience with Laravel, we recommend reading all of the documentation from beginning to end. +
+
+
+ +
+
+ + +
+ +
+
+ Laracasts offers thousands of video tutorials on Laravel, PHP, and JavaScript development. Check them out, see for yourself, and massively level up your development skills in the process. +
+
+
+ +
+
+ + +
+ +
+
+ Laravel News is a community driven portal and newsletter aggregating all of the latest and most important news in the Laravel ecosystem, including new package releases and tutorials. +
+
+
+ +
+
+ +
Vibrant Ecosystem
+
+ +
+
+ Laravel's robust library of first-party tools and libraries, such as Forge, Vapor, Nova, and Envoyer help you take your projects to the next level. Pair them with powerful open source libraries like Cashier, Dusk, Echo, Horizon, Sanctum, Telescope, and more. +
+
+
+
+
+ +
+
+
+ + + + + + Shop + + + + + + + + Sponsor + +
+
+ +
+ Laravel v{{ Illuminate\Foundation\Application::VERSION }} (PHP v{{ PHP_VERSION }}) +
+
+
+
+ + diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/api.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/api.php new file mode 100644 index 00000000..f2d96be4 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/api.php @@ -0,0 +1,47 @@ +get('/user', function (Request $request) { + return $request->user(); +}); + + +Route::get('/user/select', [UserController::class, 'select']); +Route::get('/user/create', [UserController::class, 'create']); +Route::get('/user/delete', [UserController::class, 'delete']); +Route::get('/user/update', [UserController::class, 'update']); + +Route::get('/db/select', [RawDBController::class, 'select']); +Route::get('/db/insert', [RawDBController::class, 'insert']); +Route::get('/db/delete', [RawDBController::class, 'delete']); +Route::get('/db/update', [RawDBController::class, 'update']); +Route::get('/db/selectone', [RawDBController::class, 'selectOne']); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/channels.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/channels.php new file mode 100644 index 00000000..1e499742 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/channels.php @@ -0,0 +1,32 @@ +id === (int) $id; +}); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/console.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/console.php new file mode 100644 index 00000000..7d0368f9 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/console.php @@ -0,0 +1,33 @@ +comment(Inspiring::quote()); +})->purpose('Display an inspiring quote'); diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/web.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/web.php new file mode 100644 index 00000000..39971608 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/routes/web.php @@ -0,0 +1,32 @@ +make(Kernel::class)->bootstrap(); + + return $app; + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/DBTest.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/DBTest.php new file mode 100644 index 00000000..78b77406 --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/DBTest.php @@ -0,0 +1,79 @@ +get('api/db/delete'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~delete from users where name='johnny'/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='delete',route='%%2Fapi%%2Fdb%%2Fdelete',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/;~", end($myDebugVar)['query']); + } + public function test_insert() + { + DB::enableQueryLog(); + $response = $this->get('api/db/insert'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~insert into users \(`name`, `email`, `password`\) values \('john', 'contact_me@daa.com', 'Passsword3456'\)/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='insert',route='%%2Fapi%%2Fdb%%2Finsert',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_select_one() + { + DB::enableQueryLog(); + $response = $this->get('api/db/selectone'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~select 1/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='selectOne',route='%%2Fapi%%2Fdb%%2Fselectone',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_update() + { + DB::enableQueryLog(); + $response = $this->get('api/db/update'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~update users set name='johnny' where name='john'/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='update',route='%%2Fapi%%2Fdb%%2Fupdate',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_select() + { + DB::enableQueryLog(); + $response = $this->get('api/db/select'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~select 1/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='select',route='%%2Fapi%%2Fdb%%2Fselect',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_select_with_route_disabled() + { + DB::enableQueryLog(); + config(['google_sqlcommenter.include.route' => false]); + $response = $this->get('api/db/select'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~select 1/\*framework='laravel-\d*.\d*.\d*',controller='RawDBController',action='select',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/EloquentTest.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/EloquentTest.php new file mode 100644 index 00000000..a0cf495b --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/Feature/EloquentTest.php @@ -0,0 +1,82 @@ +get('/'); + $response->assertStatus(200); + } + + public function test_delete() + { + DB::enableQueryLog(); + $response = $this->get('api/user/delete'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~delete from `users` where `email` = \?/\*framework='laravel-\d*.\d*.\d*',controller='UserController',action='delete',route='%%2Fapi%%2Fuser%%2Fdelete',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + public function test_create() + { + DB::enableQueryLog(); + $response = $this->get('api/user/create'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~insert into `users` \(`name`, `email`, `password`, `updated_at`, `created_at`\) values \(\?, \?, \?, \?, \?\)/\*framework='laravel-\d*.\d*.\d*',controller='UserController',action='create',route='%%2Fapi%%2Fuser%%2Fcreate',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_select_all() + { + DB::enableQueryLog(); + $response = $this->get('api/user/select'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~select \* from `users`/\*framework='laravel-\d*.\d*.\d*',controller='UserController',action='select',route='%%2Fapi%%2Fuser%%2Fselect',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_update() + { + DB::enableQueryLog(); + $response = $this->get('api/user/update'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~update `users` set `name` = \?, `users`.`updated_at` = \? where `email` = \?/\*framework='laravel-\d*.\d*.\d*',controller='UserController',action='update',route='%%2Fapi%%2Fuser%%2Fupdate',db_driver='mysql',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } + + public function test_select_all_db_driver_disabled() + { + DB::enableQueryLog(); + config(['google_sqlcommenter.include.db_driver' => false]); + $response = $this->get('api/user/select'); + $myDebugVar = DB::getQueryLog(); + $response->assertStatus(200); + $this->assertMatchesRegularExpression("~select \* from `users`/\*framework='laravel-\d*.\d*.\d*',controller='UserController',action='select',route='%%2Fapi%%2Fuser%%2Fselect',traceparent='\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\d{1,2}'\*/~", end($myDebugVar)['query']); + } +} diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/TestCase.php b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/TestCase.php new file mode 100644 index 00000000..999d55bb --- /dev/null +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/tests/TestCase.php @@ -0,0 +1,24 @@ + Date: Thu, 12 May 2022 22:10:51 +0530 Subject: [PATCH 008/108] build(deps): bump moment (#116) Bumps [moment](https://github.com/moment/moment) from 2.29.1 to 2.29.2. - [Release notes](https://github.com/moment/moment/releases) - [Changelog](https://github.com/moment/moment/blob/develop/CHANGELOG.md) - [Commits](https://github.com/moment/moment/compare/2.29.1...2.29.2) --- updated-dependencies: - dependency-name: moment dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../samples/express-opentelemetry/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json index fe4b74d3..8cdfde0e 100644 --- a/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/samples/express-opentelemetry/package-lock.json @@ -2743,9 +2743,9 @@ "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "node_modules/moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz", + "integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==", "engines": { "node": "*" } @@ -6590,9 +6590,9 @@ "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=" }, "moment": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", - "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + "version": "2.29.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.2.tgz", + "integrity": "sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg==" }, "moment-timezone": { "version": "0.5.32", From 6369b16b41190e64b9415a00aaef26aeca42d255 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 13 May 2022 19:18:30 +0530 Subject: [PATCH 009/108] Add compatability for ; in sqlalchemy,psycopg2 & django (#123) This PR fixes a zero day issue where comments are added after the end of SQL statement i.e. after `;`. This will create no or wrong association of the comment wrt the SQL statement. We previously fixed it for psycopg2 only, but this CL reactors the code and fixes the issue for sqlalchemy and as a precaution was added to django also. --- .../google/cloud/sqlcommenter/__init__.py | 11 ++++++ .../cloud/sqlcommenter/django/middleware.py | 6 ++-- .../cloud/sqlcommenter/psycopg2/extension.py | 9 ++--- .../cloud/sqlcommenter/sqlalchemy/executor.py | 5 ++- .../tests/generic/test_add_sql_comment.py | 36 +++++++++++++++++++ .../tests/sqlalchemy/tests.py | 34 +++++++++--------- 6 files changed, 71 insertions(+), 30 deletions(-) create mode 100644 python/sqlcommenter-python/tests/generic/test_add_sql_comment.py diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/__init__.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/__init__.py index 2b132f29..b1177c50 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/__init__.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/__init__.py @@ -36,12 +36,23 @@ def generate_sql_comment(**meta): # Sort the keywords to ensure that caching works and that testing is # deterministic. It eases visual inspection as well. + return ' /*' + KEY_VALUE_DELIMITER.join( '{}={!r}'.format(url_quote(key), url_quote(value)) for key, value in sorted(meta.items()) if value is not None ) + '*/' +def add_sql_comment(sql, **meta): + comment = generate_sql_comment(**meta) + sql = sql.rstrip() + if sql[-1] == ';': + sql = sql[:-1] + comment + ';' + else: + sql = sql + comment + return sql + + def url_quote(s): if not isinstance(s, (str, bytes)): return s diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py index 4db8f78a..cf271a48 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py @@ -19,7 +19,7 @@ import django from django.db import connection from django.db.backends.utils import CursorDebugWrapper -from google.cloud.sqlcommenter import generate_sql_comment +from google.cloud.sqlcommenter import add_sql_comment from google.cloud.sqlcommenter.opencensus import get_opencensus_values from google.cloud.sqlcommenter.opentelemetry import get_opentelemetry_values @@ -62,7 +62,8 @@ def __call__(self, execute, sql, params, many, context): db_driver = context['connection'].settings_dict.get('ENGINE', '') resolver_match = self.request.resolver_match - sql_comment = generate_sql_comment( + sql = add_sql_comment( + sql, # Information about the controller. controller=resolver_match.view_name if resolver_match and with_controller else None, # route is the pattern that matched a request with a controller i.e. the regex @@ -85,7 +86,6 @@ def __call__(self, execute, sql, params, many, context): # See: # * https://github.com/basecamp/marginalia/issues/61 # * https://github.com/basecamp/marginalia/pull/80 - sql += sql_comment # Add the query to the query log if debugging. if context['cursor'].__class__ is CursorDebugWrapper: diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py index accce407..28c26453 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/psycopg2/extension.py @@ -18,7 +18,7 @@ import psycopg2 import psycopg2.extensions -from google.cloud.sqlcommenter import generate_sql_comment +from google.cloud.sqlcommenter import add_sql_comment from google.cloud.sqlcommenter.flask import get_flask_info from google.cloud.sqlcommenter.opencensus import get_opencensus_values from google.cloud.sqlcommenter.opentelemetry import get_opentelemetry_values @@ -80,12 +80,7 @@ def execute(self, sql, args=None): if with_opentelemetry: data.update(get_opentelemetry_values()) - if len(data) != 0: - sql = sql.rstrip() - if sql[-1] == ';': - sql = sql[:-1] + generate_sql_comment(**data) + ';' - else: - sql = sql + generate_sql_comment(**data) + sql = add_sql_comment(sql, **data) return psycopg2.extensions.cursor.execute(self, sql, args) diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py index 9b0b962a..da3ae510 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/sqlalchemy/executor.py @@ -21,7 +21,7 @@ import logging import sqlalchemy -from google.cloud.sqlcommenter import generate_sql_comment +from google.cloud.sqlcommenter import add_sql_comment from google.cloud.sqlcommenter.fastapi import get_fastapi_info from google.cloud.sqlcommenter.flask import get_flask_info from google.cloud.sqlcommenter.opencensus import get_opencensus_values @@ -76,7 +76,7 @@ def before_cursor_execute(conn, cursor, sql, parameters, context, executemany): if with_opentelemetry: data.update(get_opentelemetry_values()) - sql_comment = generate_sql_comment(**data) + sql = add_sql_comment(sql, **data) # TODO: Check if the database type is MySQL and figure out # if we should prepend comments because MySQL server truncates @@ -84,7 +84,6 @@ def before_cursor_execute(conn, cursor, sql, parameters, context, executemany): # See: # * https://github.com/basecamp/marginalia/issues/61 # * https://github.com/basecamp/marginalia/pull/80 - sql += sql_comment return sql, parameters diff --git a/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py b/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py new file mode 100644 index 00000000..69de6068 --- /dev/null +++ b/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py @@ -0,0 +1,36 @@ +#!/usr/bin/python +# +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest import TestCase + +from google.cloud.sqlcommenter import add_sql_comment + + +class AddSqlCommentTests(TestCase): + def test_no_args(self): + self.assertEqual(add_sql_comment('Select 1'), 'Select 1') + + def test_end_comment_escaping(self): + self.assertEqual("Select 1 /*a='%%2A/abc'*/", add_sql_comment("Select 1", a='*/abc')) + + def test_bytes(self): + self.assertIn("Select 1 /*a='%%2A/abc'*/", add_sql_comment("Select 1",a=b'*/abc')) + + def test_url_quoting(self): + self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/", add_sql_comment("Select 1",foo='bar,baz')) + + def test_sql_with_semicolon(self): + self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/;", add_sql_comment("Select 1;",foo='bar,baz')) diff --git a/python/sqlcommenter-python/tests/sqlalchemy/tests.py b/python/sqlcommenter-python/tests/sqlalchemy/tests.py index c92b0b3c..d78b5a1e 100644 --- a/python/sqlcommenter-python/tests/sqlalchemy/tests.py +++ b/python/sqlcommenter-python/tests/sqlalchemy/tests.py @@ -52,21 +52,21 @@ def test_no_args(self): def test_db_driver(self): self.assertSQL( - "SELECT 1; /*db_driver='driver'*/", + "SELECT 1 /*db_driver='driver'*/;", with_db_driver=True, ) def test_db_framework(self): self.assertSQL( - "SELECT 1; /*db_framework='sqlalchemy%%3A{}'*/".format(sqlalchemy.__version__), + "SELECT 1 /*db_framework='sqlalchemy%%3A{}'*/;".format(sqlalchemy.__version__), with_db_framework=True, ) def test_opencensus(self): with mock_opencensus_tracer(): self.assertSQL( - "SELECT 1; /*traceparent='00-trace%%20id-span%%20id-00'," - "tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/", + "SELECT 1 /*traceparent='00-trace%%20id-span%%20id-00'," + "tracestate='congo%%3Dt61rcWkgMzE%%2Crojo%%3D00f067aa0ba902b7'*/;", with_opencensus=True, ) @@ -74,8 +74,8 @@ def test_opencensus(self): def test_opentelemetry(self): with mock_opentelemetry_context(): self.assertSQL( - "SELECT 1; /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," - "tracestate='some_key%%3Dsome_value'*/", + "SELECT 1 /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," + "tracestate='some_key%%3Dsome_value'*/;", with_opentelemetry=True, ) @@ -85,8 +85,8 @@ def test_both_opentelemetry_and_opencensus_warn(self): "google.cloud.sqlcommenter.sqlalchemy.executor.logger" ) as logger_mock, mock_opencensus_tracer(), mock_opentelemetry_context(): self.assertSQL( - "SELECT 1; /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," - "tracestate='some_key%%3Dsome_value'*/", + "SELECT 1 /*traceparent='00-000000000000000000000000deadbeef-000000000000beef-00'," + "tracestate='some_key%%3Dsome_value'*/;", with_opentelemetry=True, with_opencensus=True, ) @@ -103,27 +103,27 @@ class FlaskTests(SQLAlchemyTestCase): @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_flask_info', return_value=flask_info) def test_all_data(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='flask',route='/'*/", + "SELECT 1 /*controller='c',framework='flask',route='/'*/;", ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_flask_info', return_value=flask_info) def test_framework_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',route='/'*/", + "SELECT 1 /*controller='c',route='/'*/;", with_framework=False, ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_flask_info', return_value=flask_info) def test_controller_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*framework='flask',route='/'*/", + "SELECT 1 /*framework='flask',route='/'*/;", with_controller=False, ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_flask_info', return_value=flask_info) def test_route_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='flask'*/", + "SELECT 1 /*controller='c',framework='flask'*/;", with_route=False, ) @@ -138,26 +138,26 @@ class FastAPITests(SQLAlchemyTestCase): @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) def test_all_data(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='fastapi',route='/'*/", + "SELECT 1 /*controller='c',framework='fastapi',route='/'*/;", ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) def test_framework_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',route='/'*/", + "SELECT 1 /*controller='c',route='/'*/;", with_framework=False, ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) def test_controller_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*framework='fastapi',route='/'*/", + "SELECT 1 /*framework='fastapi',route='/'*/;", with_controller=False, ) @mock.patch('google.cloud.sqlcommenter.sqlalchemy.executor.get_fastapi_info', return_value=fastapi_info) def test_route_disabled(self, get_info): self.assertSQL( - "SELECT 1; /*controller='c',framework='fastapi'*/", + "SELECT 1 /*controller='c',framework='fastapi'*/;", with_route=False, - ) \ No newline at end of file + ) From 9018255f56bbb8a619bcfe889892e66ae6396b7e Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 24 May 2022 16:59:23 +0530 Subject: [PATCH 010/108] =?UTF-8?q?Adding=20asgiref=20as=20mandatory=20pac?= =?UTF-8?q?kage=20while=20installing=20python=20sqlcommen=E2=80=A6=20(#126?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Adding asgiref as mandatory package while installing python sqlcommenter library * Added asgiref and fastapi depencies in python tox.ini --- python/sqlcommenter-python/setup.py | 1 + python/sqlcommenter-python/tox.ini | 2 ++ 2 files changed, 3 insertions(+) diff --git a/python/sqlcommenter-python/setup.py b/python/sqlcommenter-python/setup.py index 392acea4..a68173c6 100644 --- a/python/sqlcommenter-python/setup.py +++ b/python/sqlcommenter-python/setup.py @@ -34,6 +34,7 @@ def read_file(filename): long_description_content_type='text/markdown', license='BSD', packages=find_packages(exclude=['tests']), + install_requires=['asgiref', 'fastapi'], extras_require={ 'django': ['django >= 1.11'], 'flask': ['flask'], diff --git a/python/sqlcommenter-python/tox.ini b/python/sqlcommenter-python/tox.ini index 41433144..aa16b0b9 100644 --- a/python/sqlcommenter-python/tox.ini +++ b/python/sqlcommenter-python/tox.ini @@ -24,6 +24,8 @@ deps = psycopg2: psycopg2-binary sqlalchemy: sqlalchemy six + asgiref + fastapi commands = python runtests.py From b1f4c57300a713c77b2f37921423b00024af2e32 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 24 May 2022 17:29:00 +0530 Subject: [PATCH 011/108] Php laravel ci automation (#128) This PR introduces a basic CI workflow for PHP SQLCommenter. The workflow is as follows: 1. On creating a PR on PHP SQLCommenter Laravel library code, we will run integration and unit tests. 2. After a PHP SQLCommenter Laravel library code PR is merged, we push the library code into `sqlcommenter-php` repository --- .../workflows/laravel-integration-tests.yaml | 9 +++++--- .github/workflows/laravel-publish-to-repo.yml | 21 +++++++++++++++++++ .github/workflows/laravel-unit-tests.yaml | 8 +++++-- 3 files changed, 33 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/laravel-publish-to-repo.yml diff --git a/.github/workflows/laravel-integration-tests.yaml b/.github/workflows/laravel-integration-tests.yaml index 240fb949..913aa0d3 100644 --- a/.github/workflows/laravel-integration-tests.yaml +++ b/.github/workflows/laravel-integration-tests.yaml @@ -1,3 +1,4 @@ +name: Laravel Integration Tests on: push: branches: @@ -5,10 +6,12 @@ on: paths: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - -name: Laravel Integration Tests + pull_request: + paths: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** jobs: - phpunit: + run-integrationtests: runs-on: ubuntu-latest container: image: kirschbaumdevelopment/laravel-test-runner:8.0 diff --git a/.github/workflows/laravel-publish-to-repo.yml b/.github/workflows/laravel-publish-to-repo.yml new file mode 100644 index 00000000..6e6f88ad --- /dev/null +++ b/.github/workflows/laravel-publish-to-repo.yml @@ -0,0 +1,21 @@ +name: Publish to Sqlcommenter-php repository +on: + push: + branches: + - master + paths: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** +jobs: + push-to-repo: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Pushes to another repository + uses: cpina/github-action-push-to-another-repository@main + env: + API_TOKEN_GITHUB: ${{ secrets.PHP_SQLCOMMENTER_PUSH_TOKEN }} + with: + source-directory: 'php/sqlcommenter-php/packages/sqlcommenter-laravel' + destination-github-username: 'google' + destination-repository-name: 'sqlcommenter-php' + target-branch: master diff --git a/.github/workflows/laravel-unit-tests.yaml b/.github/workflows/laravel-unit-tests.yaml index 795efe54..2b44fb9c 100644 --- a/.github/workflows/laravel-unit-tests.yaml +++ b/.github/workflows/laravel-unit-tests.yaml @@ -1,3 +1,4 @@ +name: Laravel Unit Tests on: push: branches: @@ -5,10 +6,13 @@ on: paths: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + pull_request: + paths: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** -name: Laravel Unit Tests jobs: - phpunit: + run-unittests: runs-on: ubuntu-latest container: image: kirschbaumdevelopment/laravel-test-runner:8.0 From e2b788efd1e9d3382713a186c18060b1fbb8e555 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 24 May 2022 17:44:06 +0530 Subject: [PATCH 012/108] Updating laravel source ReadMe (#129) Updating laravel source ReadMe --- php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md index b99ea8e5..bfab2fdc 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md @@ -38,9 +38,9 @@ Add the following class above ``Illuminate\Database\DatabaseServiceProvider::cla ... ] ``` -### Run the tests +### Run unit tests -Run the tests using below command +Run unit tests using below command ```shell ./vendor/bin/phpunit tests ``` From 56d0594e5d77af9789f94d5909a3bab2a6b19d12 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 24 May 2022 17:55:58 +0530 Subject: [PATCH 013/108] Renaming target branch for php push to repo workflow (#130) --- .github/workflows/laravel-publish-to-repo.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/laravel-publish-to-repo.yml b/.github/workflows/laravel-publish-to-repo.yml index 6e6f88ad..a8176484 100644 --- a/.github/workflows/laravel-publish-to-repo.yml +++ b/.github/workflows/laravel-publish-to-repo.yml @@ -18,4 +18,4 @@ jobs: source-directory: 'php/sqlcommenter-php/packages/sqlcommenter-laravel' destination-github-username: 'google' destination-repository-name: 'sqlcommenter-php' - target-branch: master + target-branch: main From 153fafb6e248d1783edede568ce38635c5209ab7 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Tue, 24 May 2022 18:06:40 +0530 Subject: [PATCH 014/108] Formatting ReadMe file --- .../packages/sqlcommenter-laravel/README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md index bfab2fdc..d3a07d7f 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md @@ -6,7 +6,7 @@ with comments that can be used later to correlate user code with SQL statements. ### Installation -Add this to your composer.json +Add this to your `composer.json` ```shell "repositories": [ { @@ -28,8 +28,8 @@ php artisan vendor:publish --provider="Google\GoogleSqlCommenterLaravel\GoogleSq ``` -Add the following class above ``Illuminate\Database\DatabaseServiceProvider::class, -`` in config/app.php +Add the following class above `Illuminate\Database\DatabaseServiceProvider::class`, + in `config/app.php` ```php 'providers' => [ ... From d00fa1b71587e53f1533e5b67bce8fdc2cd588cf Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Tue, 24 May 2022 19:14:40 +0530 Subject: [PATCH 015/108] Add LICENSE file (#132) As this repo's contents will be pushed to `sqlcommenter-php` repo to publish to PHP. --- .../packages/sqlcommenter-laravel/LICENSE | 202 ++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 php/sqlcommenter-php/packages/sqlcommenter-laravel/LICENSE diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/LICENSE b/php/sqlcommenter-php/packages/sqlcommenter-laravel/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. From 7561463e182085fe2a127eeb020e1d8c750570b3 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:40:06 +0530 Subject: [PATCH 016/108] Added dummy workflow tests for non laravel code changes (#135) Add Dummy tests for all libraries except laravel-sqlcommenter. When we are adding status check to checkin code for PHP SQLCommenter, the same status check is added for all other libraries also, as this is a mono-repo. To avoid that, we are following a strategy of selective filtering instead and tests will have same name but selectively filter what to run on the basis of path. --- .github/workflows/integration-tests.yaml | 17 +++++++++++++++++ .../workflows/laravel-integration-tests.yaml | 4 ++-- .github/workflows/laravel-unit-tests.yaml | 4 ++-- .github/workflows/unit-tests.yaml | 17 +++++++++++++++++ 4 files changed, 38 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/integration-tests.yaml create mode 100644 .github/workflows/unit-tests.yaml diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml new file mode 100644 index 00000000..88dde349 --- /dev/null +++ b/.github/workflows/integration-tests.yaml @@ -0,0 +1,17 @@ +name: Integration Tests +on: + push: + branches: + - master + paths-ignore: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + pull_request: + paths-ignore: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** +jobs: + integrationtests: + runs-on: ubuntu-latest + steps: + - run: 'echo "No build required" ' diff --git a/.github/workflows/laravel-integration-tests.yaml b/.github/workflows/laravel-integration-tests.yaml index 913aa0d3..a5132bec 100644 --- a/.github/workflows/laravel-integration-tests.yaml +++ b/.github/workflows/laravel-integration-tests.yaml @@ -1,4 +1,4 @@ -name: Laravel Integration Tests +name: Integration Tests on: push: branches: @@ -11,7 +11,7 @@ on: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** jobs: - run-integrationtests: + integrationtests: runs-on: ubuntu-latest container: image: kirschbaumdevelopment/laravel-test-runner:8.0 diff --git a/.github/workflows/laravel-unit-tests.yaml b/.github/workflows/laravel-unit-tests.yaml index 2b44fb9c..36f2911d 100644 --- a/.github/workflows/laravel-unit-tests.yaml +++ b/.github/workflows/laravel-unit-tests.yaml @@ -1,4 +1,4 @@ -name: Laravel Unit Tests +name: Unit Tests on: push: branches: @@ -12,7 +12,7 @@ on: - php/sqlcommenter-php/samples/sqlcommenter-laravel/** jobs: - run-unittests: + unittests: runs-on: ubuntu-latest container: image: kirschbaumdevelopment/laravel-test-runner:8.0 diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml new file mode 100644 index 00000000..bff1e212 --- /dev/null +++ b/.github/workflows/unit-tests.yaml @@ -0,0 +1,17 @@ +name: Unit Tests +on: + push: + branches: + - master + paths-ignore: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + pull_request: + paths-ignore: + - php/sqlcommenter-php/packages/sqlcommenter-laravel/** + - php/sqlcommenter-php/samples/sqlcommenter-laravel/** +jobs: + unittests: + runs-on: ubuntu-latest + steps: + - run: 'echo "No build required" ' From 0c309fccbd7272a89e026b2b3ae6b47f83e321b0 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 17 Jun 2022 12:43:20 +0530 Subject: [PATCH 017/108] 117 django middleware only applies to default database connections ignoring other databases (#127) Add support for multiple connection in django sqlcommenter We used the `connections` middleware instead of `connections` to support multiple databases instead of only the default database. TESTED=unittests --- .../cloud/sqlcommenter/django/middleware.py | 10 +++++++--- .../tests/django/settings.py | 4 ++++ .../sqlcommenter-python/tests/django/tests.py | 18 ++++++++++++++++-- .../sqlcommenter-python/tests/django/urls.py | 1 + .../sqlcommenter-python/tests/django/views.py | 7 ++++++- 5 files changed, 34 insertions(+), 6 deletions(-) diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py index cf271a48..f92fed6f 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py @@ -15,9 +15,11 @@ # limitations under the License. import logging +from contextlib import ExitStack import django -from django.db import connection +from django.db import connections + from django.db.backends.utils import CursorDebugWrapper from google.cloud.sqlcommenter import add_sql_comment from google.cloud.sqlcommenter.opencensus import get_opencensus_values @@ -36,7 +38,9 @@ def __init__(self, get_response): self.get_response = get_response def __call__(self, request): - with connection.execute_wrapper(QueryWrapper(request)): + with ExitStack() as stack: + for db_alias in connections: + stack.enter_context(connections[db_alias].execute_wrapper(QueryWrapper(request))) return self.get_response(request) @@ -88,7 +92,7 @@ def __call__(self, execute, sql, params, many, context): # * https://github.com/basecamp/marginalia/pull/80 # Add the query to the query log if debugging. - if context['cursor'].__class__ is CursorDebugWrapper: + if isinstance(context['cursor'], CursorDebugWrapper): context['connection'].queries_log.append(sql) return execute(sql, params, many, context) diff --git a/python/sqlcommenter-python/tests/django/settings.py b/python/sqlcommenter-python/tests/django/settings.py index 04eedf66..d59a47ed 100644 --- a/python/sqlcommenter-python/tests/django/settings.py +++ b/python/sqlcommenter-python/tests/django/settings.py @@ -18,6 +18,10 @@ 'default': { 'ENGINE': 'django.db.backends.sqlite3', }, + + 'other': { + 'ENGINE': 'django.db.backends.sqlite3', + }, } INSTALLED_APPS = ['tests.django'] diff --git a/python/sqlcommenter-python/tests/django/tests.py b/python/sqlcommenter-python/tests/django/tests.py index b7c388c6..5f0f4b73 100644 --- a/python/sqlcommenter-python/tests/django/tests.py +++ b/python/sqlcommenter-python/tests/django/tests.py @@ -15,7 +15,7 @@ # limitations under the License. import django -from django.db import connection +from django.db import connection, connections from django.http import HttpRequest from django.test import TestCase, override_settings, modify_settings from django.urls import resolve, reverse @@ -41,7 +41,7 @@ def __call__(self, request): # Query log only active if DEBUG=True. @override_settings(DEBUG=True) class Tests(TestCase): - + databases = '__all__' @staticmethod def get_request(path): request = HttpRequest() @@ -55,6 +55,13 @@ def get_query(self, path='/'): self.assertEqual(len(connection.queries), 2) return connection.queries[0] + def get_query_other_db(self, path='/', connection_name='default'): + SqlCommenter(views.home_other_db)(self.get_request(path)) + # Query with comment added by QueryWrapper and unaltered query added + # by Django's CursorDebugWrapper. + self.assertEqual(len(connections[connection_name].queries), 2) + return connections[connection_name].queries[0] + def assertRoute(self, route, query): # route available in Django 2.2 and later. if django.VERSION < (2, 2): @@ -69,6 +76,13 @@ def test_basic(self): self.assertIn("framework='django%%3A" + django.get_version(), query) self.assertRoute('', query) + def test_basic_multiple_db_support(self): + query = self.get_query_other_db(path='/other/', connection_name='other') + self.assertIn("/*controller='some-other-db-path'", query) + # Expecting url_quoted("framework='django:'") + self.assertIn("framework='django%%3A" + django.get_version(), query) + self.assertRoute('other/', query) + def test_basic_disabled(self): with self.settings( SQLCOMMENTER_WITH_CONTROLLER=False, SQLCOMMENTER_WITH_ROUTE=False, diff --git a/python/sqlcommenter-python/tests/django/urls.py b/python/sqlcommenter-python/tests/django/urls.py index af364642..0a641444 100644 --- a/python/sqlcommenter-python/tests/django/urls.py +++ b/python/sqlcommenter-python/tests/django/urls.py @@ -21,5 +21,6 @@ urlpatterns = [ path('', views.home, name='home'), path('path/', views.home, name='some-path'), + path('other/', views.home_other_db, name='some-other-db-path'), path('app-urls/', include('tests.django.app_urls')), ] diff --git a/python/sqlcommenter-python/tests/django/views.py b/python/sqlcommenter-python/tests/django/views.py index 03e2392c..badc9685 100644 --- a/python/sqlcommenter-python/tests/django/views.py +++ b/python/sqlcommenter-python/tests/django/views.py @@ -20,5 +20,10 @@ def home(request): - list(Author.objects.all()) + list(Author.objects.all().using('default')) + return HttpResponse() + + +def home_other_db(request): + list(Author.objects.all().using('other')) return HttpResponse() From 26d38da7e9ddc80ac6083451a5946eec7cf68abf Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 18:33:00 +0530 Subject: [PATCH 018/108] Added workflow for unittest --- .github/workflows/python-unit-tests.yaml | 31 ++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 .github/workflows/python-unit-tests.yaml diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml new file mode 100644 index 00000000..19407d3b --- /dev/null +++ b/.github/workflows/python-unit-tests.yaml @@ -0,0 +1,31 @@ +name: Contrib Repo Tests + +on: + push: + +jobs: + build: + env: + # We use these variables to convert between tox and GHA version literals + py36: 3.6 + py37: 3.7 + py38: 3.8 + py39: 3.9 + RUN_MATRIX_COMBINATION: ${{ matrix.python-version }}-${{ matrix.package }}-${{ matrix.os }} + runs-on: ${{ matrix.os }} + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + python-version: [ py36, py37, py38, py39 ] + os: [ ubuntu-20.04 ] + steps: + - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v2 + - name: Set up Python ${{ env[matrix.python-version] }} + uses: actions/setup-python@v2 + with: + python-version: ${{ env[matrix.python-version] }} + - name: Install tox + run: pip install -U tox-factor + - name: run tox + run: tox -e '${{ matrix.python-version }}-{django21,psycopg2,flask}' From 80887abc3f032d5375a39e5e8279d951cdf06af1 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:27:12 +0530 Subject: [PATCH 019/108] Change working directory of tox run --- .github/workflows/python-unit-tests.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml index 19407d3b..a88fbf50 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-unit-tests.yaml @@ -29,3 +29,5 @@ jobs: run: pip install -U tox-factor - name: run tox run: tox -e '${{ matrix.python-version }}-{django21,psycopg2,flask}' + working-directory: ./python/sqlcommenter-python + From d87d3370e6016e213b5a4f7f64b8a58058df57e8 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:29:38 +0530 Subject: [PATCH 020/108] Check failure case --- python/sqlcommenter-python/tests/flask/tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/sqlcommenter-python/tests/flask/tests.py b/python/sqlcommenter-python/tests/flask/tests.py index 5daebe3d..97ff0d5b 100644 --- a/python/sqlcommenter-python/tests/flask/tests.py +++ b/python/sqlcommenter-python/tests/flask/tests.py @@ -40,7 +40,7 @@ def test_get_flask_info_in_request_context(client): 'route': '/flask-info', } resp = client.get('/flask-info') - assert json.loads(resp.data.decode('utf-8')) == expected + assert json.loads(resp.data.decode('utf-8')) == {} def test_get_flask_info_in_404_error_context(client): From 0fa41634a136b771d702c6ce16be71cf9fcb6c3a Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:31:34 +0530 Subject: [PATCH 021/108] Check failure case --- .github/workflows/python-unit-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml index a88fbf50..c3f8c585 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-unit-tests.yaml @@ -28,6 +28,6 @@ jobs: - name: Install tox run: pip install -U tox-factor - name: run tox - run: tox -e '${{ matrix.python-version }}-{django21,psycopg2,flask}' + run: tox -e '${{ matrix.python-version }}-{flask,django21,psycopg2}' working-directory: ./python/sqlcommenter-python From 7671d6f20adf742a53959acea29d625f129b9277 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:42:09 +0530 Subject: [PATCH 022/108] Added support for all packages --- .github/workflows/python-unit-tests.yaml | 7 ++++--- python/sqlcommenter-python/tests/flask/tests.py | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml index c3f8c585..3211e56e 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-unit-tests.yaml @@ -1,10 +1,10 @@ -name: Contrib Repo Tests +name: Python Packages Test on: push: jobs: - build: + unittests: env: # We use these variables to convert between tox and GHA version literals py36: 3.6 @@ -28,6 +28,7 @@ jobs: - name: Install tox run: pip install -U tox-factor - name: run tox - run: tox -e '${{ matrix.python-version }}-{flask,django21,psycopg2}' + run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32, + psycopg2,flask,generic,sqlalchemy}' working-directory: ./python/sqlcommenter-python diff --git a/python/sqlcommenter-python/tests/flask/tests.py b/python/sqlcommenter-python/tests/flask/tests.py index 97ff0d5b..5daebe3d 100644 --- a/python/sqlcommenter-python/tests/flask/tests.py +++ b/python/sqlcommenter-python/tests/flask/tests.py @@ -40,7 +40,7 @@ def test_get_flask_info_in_request_context(client): 'route': '/flask-info', } resp = client.get('/flask-info') - assert json.loads(resp.data.decode('utf-8')) == {} + assert json.loads(resp.data.decode('utf-8')) == expected def test_get_flask_info_in_404_error_context(client): From 68cfdb4b16bb11e0cb10153e343a6b17516fb0db Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:42:55 +0530 Subject: [PATCH 023/108] Added support for all packages --- .github/workflows/python-unit-tests.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml index 3211e56e..d7b264a6 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-unit-tests.yaml @@ -28,7 +28,6 @@ jobs: - name: Install tox run: pip install -U tox-factor - name: run tox - run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32, - psycopg2,flask,generic,sqlalchemy}' + run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32,psycopg2,flask,generic,sqlalchemy}' working-directory: ./python/sqlcommenter-python From 3a965cc967685cac66a38f8771d64795606207e4 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:47:37 +0530 Subject: [PATCH 024/108] Added paths --- .github/workflows/python-unit-tests.yaml | 8 +++++++- .github/workflows/unit-tests.yaml | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-unit-tests.yaml index d7b264a6..32bdb162 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-unit-tests.yaml @@ -2,6 +2,13 @@ name: Python Packages Test on: push: + branches: + - master + paths: + - python/sqlcommenter-python/** + pull_request: + paths: + - python/sqlcommenter-python/** jobs: unittests: @@ -30,4 +37,3 @@ jobs: - name: run tox run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32,psycopg2,flask,generic,sqlalchemy}' working-directory: ./python/sqlcommenter-python - diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index bff1e212..1e642688 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -6,10 +6,12 @@ on: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + - python/sqlcommenter-python/** pull_request: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + - python/sqlcommenter-python/** jobs: unittests: runs-on: ubuntu-latest From 9441d8b148f1c9154b79e7d554cf863d6ddddcc5 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:51:23 +0530 Subject: [PATCH 025/108] Test paths build --- python/sqlcommenter-python/google/cloud/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/sqlcommenter-python/google/cloud/__init__.py b/python/sqlcommenter-python/google/cloud/__init__.py index 79c6a2fa..0738f0a5 100644 --- a/python/sqlcommenter-python/google/cloud/__init__.py +++ b/python/sqlcommenter-python/google/cloud/__init__.py @@ -13,3 +13,5 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + + From 354e8a082d39fe183e1c2e799630091955df855a Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:53:50 +0530 Subject: [PATCH 026/108] Test paths build --- .github/workflows/integration-tests.yaml | 3 +++ .github/workflows/unit-tests.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index 88dde349..d40cdd54 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -6,10 +6,13 @@ on: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + - python/sqlcommenter-python/** pull_request: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** + - python/sqlcommenter-python/** + jobs: integrationtests: runs-on: ubuntu-latest diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 1e642688..ed558546 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -1,4 +1,5 @@ name: Unit Tests + on: push: branches: @@ -12,6 +13,7 @@ on: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - python/sqlcommenter-python/** + jobs: unittests: runs-on: ubuntu-latest From 0f47500a3c9ade77513119972e1305b3a52d1fad Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:55:35 +0530 Subject: [PATCH 027/108] Reverting back --- python/sqlcommenter-python/google/cloud/__init__.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/python/sqlcommenter-python/google/cloud/__init__.py b/python/sqlcommenter-python/google/cloud/__init__.py index 0738f0a5..79c6a2fa 100644 --- a/python/sqlcommenter-python/google/cloud/__init__.py +++ b/python/sqlcommenter-python/google/cloud/__init__.py @@ -13,5 +13,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - - From 8ef4a00f354da5522bf0f31b62b860bcdabc6cd5 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 19:57:25 +0530 Subject: [PATCH 028/108] Reverting testr --- python/sqlcommenter-python/google/cloud/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/python/sqlcommenter-python/google/cloud/__init__.py b/python/sqlcommenter-python/google/cloud/__init__.py index 79c6a2fa..e207cf94 100644 --- a/python/sqlcommenter-python/google/cloud/__init__.py +++ b/python/sqlcommenter-python/google/cloud/__init__.py @@ -13,3 +13,4 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + From c44ca5fce52b8d96104ec14b039f13fa2d062577 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 27 Jun 2022 20:00:43 +0530 Subject: [PATCH 029/108] Reverting testrh --- python/sqlcommenter-python/google/cloud/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/python/sqlcommenter-python/google/cloud/__init__.py b/python/sqlcommenter-python/google/cloud/__init__.py index e207cf94..79c6a2fa 100644 --- a/python/sqlcommenter-python/google/cloud/__init__.py +++ b/python/sqlcommenter-python/google/cloud/__init__.py @@ -13,4 +13,3 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. - From 57122944ae46bb74e87bdc9091ee293a47a9b25d Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Tue, 28 Jun 2022 11:52:05 +0530 Subject: [PATCH 030/108] Added lint --- .github/workflows/integration-tests.yaml | 2 -- ...thon-unit-tests.yaml => python-tests.yaml} | 35 +++++++++++++++---- 2 files changed, 28 insertions(+), 9 deletions(-) rename .github/workflows/{python-unit-tests.yaml => python-tests.yaml} (59%) diff --git a/.github/workflows/integration-tests.yaml b/.github/workflows/integration-tests.yaml index d40cdd54..ac1c4cca 100644 --- a/.github/workflows/integration-tests.yaml +++ b/.github/workflows/integration-tests.yaml @@ -6,12 +6,10 @@ on: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - - python/sqlcommenter-python/** pull_request: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - - python/sqlcommenter-python/** jobs: integrationtests: diff --git a/.github/workflows/python-unit-tests.yaml b/.github/workflows/python-tests.yaml similarity index 59% rename from .github/workflows/python-unit-tests.yaml rename to .github/workflows/python-tests.yaml index 32bdb162..357d7df8 100644 --- a/.github/workflows/python-unit-tests.yaml +++ b/.github/workflows/python-tests.yaml @@ -2,13 +2,13 @@ name: Python Packages Test on: push: - branches: - - master - paths: - - python/sqlcommenter-python/** - pull_request: - paths: - - python/sqlcommenter-python/** +# branches: +# - master +# paths: +# - python/sqlcommenter-python/** +# pull_request: +# paths: +# - python/sqlcommenter-python/** jobs: unittests: @@ -37,3 +37,24 @@ jobs: - name: run tox run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32,psycopg2,flask,generic,sqlalchemy}' working-directory: ./python/sqlcommenter-python + + misc: + strategy: + fail-fast: false + matrix: + tox-environment: [ "lint" ] + name: ${{ matrix.tox-environment }} + runs-on: ubuntu-20.04 + steps: + - name: Checkout Contrib Repo @ SHA - ${{ github.sha }} + uses: actions/checkout@v2 + - name: Set up Python 3.9 + uses: actions/setup-python@v2 + with: + python-version: 3.9 + - name: Install tox + run: pip install -U tox + - name: run tox + run: tox -e flake8 + working-directory: ./python/sqlcommenter-python + From 31336cd7c347e2d6d243cd5401591e3ec59e66c4 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Tue, 28 Jun 2022 12:05:48 +0530 Subject: [PATCH 031/108] Lint changes --- .github/workflows/unit-tests.yaml | 5 +++++ .../google/cloud/sqlcommenter/django/middleware.py | 1 - python/sqlcommenter-python/tests/django/tests.py | 10 ++++++++-- python/sqlcommenter-python/tests/fastapi/app.py | 5 +++-- python/sqlcommenter-python/tests/fastapi/tests.py | 3 +-- .../tests/generic/test_add_sql_comment.py | 6 +++--- 6 files changed, 20 insertions(+), 10 deletions(-) diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index ed558546..9d71c97f 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -19,3 +19,8 @@ jobs: runs-on: ubuntu-latest steps: - run: 'echo "No build required" ' + + lint: + runs-on: ubuntu-latest + steps: + - run: 'echo "No build required" ' diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py index f92fed6f..90d80995 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/django/middleware.py @@ -19,7 +19,6 @@ import django from django.db import connections - from django.db.backends.utils import CursorDebugWrapper from google.cloud.sqlcommenter import add_sql_comment from google.cloud.sqlcommenter.opencensus import get_opencensus_values diff --git a/python/sqlcommenter-python/tests/django/tests.py b/python/sqlcommenter-python/tests/django/tests.py index 5f0f4b73..e61cc205 100644 --- a/python/sqlcommenter-python/tests/django/tests.py +++ b/python/sqlcommenter-python/tests/django/tests.py @@ -17,9 +17,11 @@ import django from django.db import connection, connections from django.http import HttpRequest -from django.test import TestCase, override_settings, modify_settings +from django.test import TestCase, modify_settings, override_settings from django.urls import resolve, reverse -from google.cloud.sqlcommenter.django.middleware import SqlCommenter, QueryWrapper +from google.cloud.sqlcommenter.django.middleware import ( + QueryWrapper, SqlCommenter, +) from ..compat import mock from ..opencensus_mock import mock_opencensus_tracer @@ -30,6 +32,8 @@ # Adding the middleware twice in modify_settings # doesn't work. The middleware is only used once # if used in modify_settings + + class TestMiddleware: def __init__(self, get_response): self.get_response = get_response @@ -38,10 +42,12 @@ def __call__(self, request): with connection.execute_wrapper(QueryWrapper(request)): return self.get_response(request) + # Query log only active if DEBUG=True. @override_settings(DEBUG=True) class Tests(TestCase): databases = '__all__' + @staticmethod def get_request(path): request = HttpRequest() diff --git a/python/sqlcommenter-python/tests/fastapi/app.py b/python/sqlcommenter-python/tests/fastapi/app.py index e699ba46..24dcc8ce 100644 --- a/python/sqlcommenter-python/tests/fastapi/app.py +++ b/python/sqlcommenter-python/tests/fastapi/app.py @@ -2,10 +2,11 @@ from fastapi import FastAPI, status from fastapi.responses import JSONResponse +from google.cloud.sqlcommenter.fastapi import ( + SQLCommenterMiddleware, get_fastapi_info, +) from starlette.exceptions import HTTPException as StarletteHTTPException -from google.cloud.sqlcommenter.fastapi import SQLCommenterMiddleware, get_fastapi_info - app = FastAPI(title="SQLCommenter") app.add_middleware(SQLCommenterMiddleware) diff --git a/python/sqlcommenter-python/tests/fastapi/tests.py b/python/sqlcommenter-python/tests/fastapi/tests.py index 1c586e98..d2edb9f5 100644 --- a/python/sqlcommenter-python/tests/fastapi/tests.py +++ b/python/sqlcommenter-python/tests/fastapi/tests.py @@ -18,9 +18,8 @@ import fastapi import pytest -from starlette.testclient import TestClient - from google.cloud.sqlcommenter.fastapi import get_fastapi_info +from starlette.testclient import TestClient from .app import app diff --git a/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py b/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py index 69de6068..2cb2a6c8 100644 --- a/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py +++ b/python/sqlcommenter-python/tests/generic/test_add_sql_comment.py @@ -27,10 +27,10 @@ def test_end_comment_escaping(self): self.assertEqual("Select 1 /*a='%%2A/abc'*/", add_sql_comment("Select 1", a='*/abc')) def test_bytes(self): - self.assertIn("Select 1 /*a='%%2A/abc'*/", add_sql_comment("Select 1",a=b'*/abc')) + self.assertIn("Select 1 /*a='%%2A/abc'*/", add_sql_comment("Select 1", a=b'*/abc')) def test_url_quoting(self): - self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/", add_sql_comment("Select 1",foo='bar,baz')) + self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/", add_sql_comment("Select 1", foo='bar,baz')) def test_sql_with_semicolon(self): - self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/;", add_sql_comment("Select 1;",foo='bar,baz')) + self.assertIn("Select 1 /*foo='bar%%2Cbaz'*/;", add_sql_comment("Select 1;", foo='bar,baz')) From e8d79ead3444e62cbf3fd55992ea6c131e11a8c7 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Tue, 28 Jun 2022 12:17:38 +0530 Subject: [PATCH 032/108] test dummy lint --- php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md index 59b1982c..e6bcd605 100644 --- a/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md @@ -1,4 +1,4 @@ -# sqlcommenter-laravel-sample + # sqlcommenter-laravel-sample sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel with comments that can be used later to correlate user code with SQL statements. From c57852dfd74b8d5c1d0fc3e5d721ba477b47fd77 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Tue, 28 Jun 2022 12:19:04 +0530 Subject: [PATCH 033/108] test dummy lint --- php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md index e6bcd605..59b1982c 100644 --- a/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/samples/sqlcommenter-laravel/README.md @@ -1,4 +1,4 @@ - # sqlcommenter-laravel-sample +# sqlcommenter-laravel-sample sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel with comments that can be used later to correlate user code with SQL statements. From 2d7fcdfa17da8294b93f65a38f59ba8fccbb7a79 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Tue, 28 Jun 2022 12:20:12 +0530 Subject: [PATCH 034/108] test dummy lint --- .github/workflows/python-tests.yaml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-tests.yaml b/.github/workflows/python-tests.yaml index 357d7df8..be1a9be9 100644 --- a/.github/workflows/python-tests.yaml +++ b/.github/workflows/python-tests.yaml @@ -2,13 +2,13 @@ name: Python Packages Test on: push: -# branches: -# - master -# paths: -# - python/sqlcommenter-python/** -# pull_request: -# paths: -# - python/sqlcommenter-python/** + branches: + - master + paths: + - python/sqlcommenter-python/** + pull_request: + paths: + - python/sqlcommenter-python/** jobs: unittests: From e036bc40febfc4d3c5f1a85ff4407d889e89ed26 Mon Sep 17 00:00:00 2001 From: Thiyagu55 Date: Mon, 11 Jul 2022 11:24:46 +0530 Subject: [PATCH 035/108] pr changes --- .github/workflows/python-tests.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-tests.yaml b/.github/workflows/python-tests.yaml index be1a9be9..c267c0d9 100644 --- a/.github/workflows/python-tests.yaml +++ b/.github/workflows/python-tests.yaml @@ -38,7 +38,7 @@ jobs: run: tox -e '${{ matrix.python-version }}-{django21,django22,django30,django31,django32,psycopg2,flask,generic,sqlalchemy}' working-directory: ./python/sqlcommenter-python - misc: + lint: strategy: fail-fast: false matrix: From b6d3d75df865262c191c2cf4cd02d92dae50265c Mon Sep 17 00:00:00 2001 From: Yoshi Yamaguchi Date: Thu, 14 Jul 2022 02:05:26 +0900 Subject: [PATCH 036/108] Add comment about the donation in README (#118) Add comment about SQLCommenter donation to OpenTelemetry in README --- README.md | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c885873e..4246d7c5 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,22 @@ ## sqlcommenter +**sqlcommenter is donated to [OpenTelemetry](https://opentelemetry.io/). We will continue to maintain this repository until opentelemetry SQLCommenter feature stabilizes. Further updates will be added here in due time. See the migration plans in [this comment](https://github.com/open-telemetry/opentelemetry-java-contrib/issues/205#issuecomment-1018136934). ** + [Documentation](https://google.github.io/sqlcommenter/) Contains all the various `sqlcommenter-*` implementations. - [X] [Python](python/sqlcommenter-python/README.md) - - [X] [django](python/sqlcommenter-python/README.md#django) - - [X] [psycopg2](python/sqlcommenter-python/README.md#psycopg2) - - [X] [sqlalchemy](python/sqlcommenter-python/README.md#sqlalchemy) + - [X] [django](python/sqlcommenter-python/README.md#django) + - [X] [psycopg2](python/sqlcommenter-python/README.md#psycopg2) + - [X] [sqlalchemy](python/sqlcommenter-python/README.md#sqlalchemy) - [X] [Java](java/sqlcommenter-java/README.md) - - [X] [Hibernate](java/sqlcommenter-java/README.md#hibernate) - - [X] [Spring+Hibernate](java/sqlcommenter-java/README.md#spring-hibernate) + - [X] [Hibernate](java/sqlcommenter-java/README.md#hibernate) + - [X] [Spring+Hibernate](java/sqlcommenter-java/README.md#spring-hibernate) - [X] Ruby - - [X] [Rails](ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md) + - [X] [Rails](ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md) - [X] [Node.js](nodejs/sqlcommenter-nodejs/README.md) - - [X] [Knex.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/README.md) - - [X] [Sequelize.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/README.md) + - [X] [Knex.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/README.md) + - [X] [Sequelize.js](nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/README.md) - [X] Php - [X] [Laravel](php/sqlcommenter-php/packages/sqlcommenter-laravel) From b17410ca003966ec4565e76166f552d069eb4144 Mon Sep 17 00:00:00 2001 From: memory Date: Sat, 20 Aug 2022 04:02:28 +0900 Subject: [PATCH 037/108] Refactor: Remove/Replace unnecessary implementations in PHP (Laravel) (#144) * Refactor: Remove/Replace unnecessary implementations * Revert function name and add static prefix to a callback in the Utils.php * Replace to modern array --- .../src/Database/Connection.php | 124 ++++-------------- .../sqlcommenter-laravel/src/Utils.php | 32 +++-- .../tests/Unit/UtilsTest.php | 18 ++- 3 files changed, 58 insertions(+), 116 deletions(-) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php index 0914952e..790783fa 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Database/Connection.php @@ -26,119 +26,51 @@ class Connection extends BaseConnection { /** - * Run a select statement and return a single result. - * - * @param string $query - * @param array $bindings - * @param bool $useReadPdo - * @return mixed + * @inheritDoc */ - public function selectOne($query, $bindings = [], $useReadPdo = true) + protected function run($query, $bindings, \Closure $callback) { - $query = $this->getSqlComments($query); - $records = parent::select($query, $bindings, $useReadPdo); - - if (count($records) > 0) { - return $records; - } - return null; - } - - /** - * Run a select statement against the database. - * - * @param string $query - * @param array $bindings - * @param bool $useReadPdo - * @return array - */ - public function select($query, $bindings = [], $useReadPdo = true) - { - $query = $this->getSqlComments($query); - $records = parent::select($query, $bindings, $useReadPdo); - return $records; + return parent::run( + $this->appendSqlComments($query), + $bindings, + $callback + ); } - /** - * Run an insert statement against the database. - * - * @param string $query - * @param array $bindings - * @return bool - */ - public function insert($query, $bindings = []) + private function appendSqlComments(string $query): string { - $query = $this->getSqlComments($query); - $records = parent::insert($query, $bindings); - - return $records; - } - - /** - * Run an update statement against the database. - * - * @param string $query - * @param array $bindings - * @return int - */ - public function update($query, $bindings = []) - { - $query = $this->getSqlComments($query); - - return $this->affectingStatement($query, $bindings); - } - - /** - * Run a delete statement against the database. - * - * @param string $query - * @param array $bindings - * @return int - */ - public function delete($query, $bindings = []) - { - - $query = $this->getSqlComments($query); - - return $this->affectingStatement($query, $bindings); - } - - private function getSqlComments($query) - { - $configurationKey = 'google_sqlcommenter.include.'; - $comment = []; + static $configurationKey = 'google_sqlcommenter.include'; + $comments = []; $action = null; - if (!empty(app('request')->route())) { - $action = app('request')->route()->getAction(); + if (!empty(request()->route())) { + $action = request()->route()->getAction(); } - if (config($configurationKey . 'framework', true)) { - $comment['framework'] = "laravel-" . app()->version(); + if (config("{$configurationKey}.framework", true)) { + $comments['framework'] = "laravel-" . app()->version(); } - if (config($configurationKey . 'controller', true) and !empty($action['controller'])) { - $comment['controller'] = explode("@", class_basename($action['controller']))[0]; + if (config("{$configurationKey}.controller", true) && !empty($action['controller'])) { + $comments['controller'] = explode("@", class_basename($action['controller']))[0]; } - if (config($configurationKey . 'action', true) and !empty($action and $action['controller'] and str_contains($action['controller'], '@'))) { - $comment['action'] = explode("@", class_basename($action['controller']))[1]; + if (config("{$configurationKey}.action", true) && !empty($action and $action['controller'] && str_contains($action['controller'], '@'))) { + $comments['action'] = explode("@", class_basename($action['controller']))[1]; } - if (config($configurationKey . 'route', true)) { - $comment['route'] = request()->getRequestUri(); + if (config("{$configurationKey}.route", true)) { + $comments['route'] = request()->getRequestUri(); } - if (config($configurationKey . 'db_driver', true)) { + if (config("{$configurationKey}.db_driver", true)) { $connection = config('database.default'); - $comment['db_driver'] = config("database.connections.{$connection}.driver"); + $comments['db_driver'] = config("database.connections.{$connection}.driver"); } - if (config($configurationKey . 'opentelemetry', true)) { + if (config("{$configurationKey}.opentelemetry", true)) { $carrier = Opentelemetry::getOpentelemetryValues(); - $comment = array_merge($comment, $carrier); + $comments = $comments + $carrier; } - $query=trim($query); - - if ($query[-1] == ';'){ - return rtrim($query ,";"). Utils::formatComments(array_filter(($comment))). ';'; - } - return $query . Utils::formatComments(array_filter(($comment))); + $query = trim($query); + $hasSemicolon = $query[-1] === ';'; + $query = rtrim($query, ';'); + return $query . Utils::formatComments(array_filter($comments)) . ($hasSemicolon ? ';' : ''); } } diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php index 1931d151..387835ab 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/src/Utils.php @@ -19,31 +19,29 @@ class Utils { - public static function formatComments($comment) + public static function formatComments(array $comments): string { - if (empty($comment)) { + if (empty($comments)) { return ""; } - $lastElement = array_key_last($comment); - $sql_comment = "/*"; - foreach ($comment as $key => $value) { - if ($key == $lastElement) { - $sql_comment .= Utils::customUrlEncode($key) . "=" . "'" . Utils::customUrlEncode($value) . "'*/"; - } else { - $sql_comment .= Utils::customUrlEncode($key) . "=" . "'" . Utils::customUrlEncode($value) . "',"; - } - } - return $sql_comment; + + return "/*" . implode( + ',', + array_map( + static fn (string $value, string $key) => Utils::customUrlEncode($key) . "='" . Utils::customUrlEncode($value) . "'", $comments, + array_keys($comments) + ), + ) . "*/"; } - private static function customUrlEncode($input) + private static function customUrlEncode(string $input): string { $encodedString = urlencode($input); - # Since SQL uses '%' as a keyword, '%' is a by-product of url quoting - # e.g. foo,bar --> foo%2Cbar - # thus in our quoting, we need to escape it too to finally give - # foo,bar --> foo%%2Cbar + // Since SQL uses '%' as a keyword, '%' is a by-product of url quoting + // e.g. foo,bar --> foo%2Cbar + // thus in our quoting, we need to escape it too to finally give + // foo,bar --> foo%%2Cbar return str_replace("%", "%%", $encodedString); } diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php b/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php index 51ed3e1a..ac9b8ae2 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/tests/Unit/UtilsTest.php @@ -22,14 +22,26 @@ final class UtilsTest extends TestCase { public function testFormatCommentsWithKeys(): void { - $this->assertEquals("/*key1='value1',key2='value2'*/", Utils::formatComments(array("key1" => "value1", "key2" => "value2"))); + $this->assertEquals("/*key1='value1',key2='value2'*/", Utils::formatComments(["key1" => "value1", "key2" => "value2"])); } + public function testFormatCommentsWithoutKeys(): void { - $this->assertEquals("", Utils::formatComments(array())); + $this->assertEquals("", Utils::formatComments([])); } + public function testFormatCommentsWithSpecialCharKeys(): void { - $this->assertEquals("/*key1='value1%%40',key2='value2'*/", Utils::formatComments(array("key1" => "value1@", "key2" => "value2"))); + $this->assertEquals("/*key1='value1%%40',key2='value2'*/", Utils::formatComments(["key1" => "value1@", "key2" => "value2"])); + } + + public function testFormatCommentsWithPlaceholder(): void + { + $this->assertEquals("/*key1='value1%%3F',key2='value2'*/", Utils::formatComments(["key1" => "value1?", "key2" => "value2"])); + } + + public function testFormatCommentsWithNamedPlaceholder(): void + { + $this->assertEquals("/*key1='%%3Anamed',key2='value2'*/", Utils::formatComments(["key1" => ":named", "key2" => "value2"])); } } From b6d52b76639a72397cadefb4966529758c93eebc Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Sat, 20 Aug 2022 00:37:49 +0530 Subject: [PATCH 038/108] Update Laravel publish workflow destination repo (#149) --- .github/workflows/laravel-publish-to-repo.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/laravel-publish-to-repo.yml b/.github/workflows/laravel-publish-to-repo.yml index a8176484..62d0006d 100644 --- a/.github/workflows/laravel-publish-to-repo.yml +++ b/.github/workflows/laravel-publish-to-repo.yml @@ -1,4 +1,4 @@ -name: Publish to Sqlcommenter-php repository +name: Publish to "sqlcommenter-laravel-php" repository on: push: branches: @@ -17,5 +17,5 @@ jobs: with: source-directory: 'php/sqlcommenter-php/packages/sqlcommenter-laravel' destination-github-username: 'google' - destination-repository-name: 'sqlcommenter-php' + destination-repository-name: 'sqlcommenter-laravel-php' target-branch: main From 2fa907ece93f713cc3888db14ab860c71bc244c0 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Sat, 20 Aug 2022 00:55:01 +0530 Subject: [PATCH 039/108] Update description in composer.json (#150) Update description in composer.json --- .../packages/sqlcommenter-laravel/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json b/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json index 1e2fbd07..483e318b 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/composer.json @@ -1,6 +1,6 @@ { "name": "google/sqlcommenter-laravel", - "description": "Laravel middleware to send events to OpenTelemetry", + "description": "SQLCommenter implementation for Laravel. SQLCommenter is a set of tools that augments SQL Statements with comments containing information about the code that caused its execution. These information can be action, controller, framework, db_driver, route and opentelemetry traceparent.", "type": "library", "license": "MIT", "authors": [ From 2290ef49e644cde1dd84749a6bd18ce06ba771ff Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Mon, 29 Aug 2022 14:02:25 +0530 Subject: [PATCH 040/108] Nodejs knex: Remove opencensus functionalities (#146) * Decouple opencensus * Remove opencensus from package.json --- .../sqlcommenter-knex/package-lock.json | 5816 +++++++++++++++-- .../packages/sqlcommenter-knex/package.json | 6 +- .../sqlcommenter-knex/provider/index.js | 6 +- .../sqlcommenter-knex/provider/opencensus.js | 22 - .../sqlcommenter-knex/test/comment.test.js | 85 +- .../sqlcommenter-knex/test/unit/provider.js | 33 +- .../sqlcommenter-knex/test/unit/util.js | 75 +- .../packages/sqlcommenter-knex/util.js | 49 +- 8 files changed, 5173 insertions(+), 919 deletions(-) delete mode 100644 nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/opencensus.js diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package-lock.json b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package-lock.json index 6406a012..3c7b1400 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package-lock.json @@ -1,158 +1,5165 @@ { "name": "@google-cloud/sqlcommenter-knex", - "version": "0.0.3", - "lockfileVersion": 1, + "version": "1.0.0", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", + "packages": { + "": { + "name": "@google-cloud/sqlcommenter-knex", + "version": "1.0.0", + "license": "Apache-2.0", + "devDependencies": { + "@opentelemetry/api": "^1.0.3", + "@opentelemetry/core": "^0.24.0", + "@opentelemetry/node": "^0.24.0", + "chai": "^4.2.0", + "chai-http": "^4.3.0", + "express": "^4.17.0", + "knex": "^0.19.5", + "mocha": "^8.2.0", + "rewiremock": "^3.14.3", + "sequelize": "^6.3.3", + "sinon": "^9.0.3", + "sinon-chai": "^3.5.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "@opentelemetry/core": "^0.24.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz", + "integrity": "sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.24.0.tgz", + "integrity": "sha512-Db8AgMByBEFKLJGSUBlNq4Un/Tqzj5W0hTxx3hIic8DvBwqbvUvkMGuiQYLKE2Ay21cLYMT01xK4TEKz0OxADw==", + "dev": true, + "engines": { + "node": ">=8.1.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/node": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/node/-/node-0.24.0.tgz", + "integrity": "sha512-Sy8QooZFOeVUcJIKetw5xsq15/1ivZovWg0RnKWtzURMQrcOxmQ3bGrXPORklOJxOtf5snDHgT37Y7dBgr+c+g==", + "deprecated": "Package renamed to @opentelemetry/sdk-trace-node", + "dev": true, + "dependencies": { + "@opentelemetry/context-async-hooks": "0.24.0", + "@opentelemetry/core": "0.24.0", + "@opentelemetry/propagator-b3": "0.24.0", + "@opentelemetry/propagator-jaeger": "0.24.0", + "@opentelemetry/tracing": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/node/node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-0.24.0.tgz", + "integrity": "sha512-iV7KSN0LkEAkeVCbhaIJAgTEb7HCnVkprmpgkL6q79rP3vTW4dylwfBYgIwod7y0GT4Ofgomm0NrwwWiuGLbQA==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-b3/node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-0.24.0.tgz", + "integrity": "sha512-QXCxBwuSka+vXbBZdumtF7YKO84gwTyKy3GelZV5BPlgWoge0AbLR3DfsO9Beu13pmD+4PyuwMw3LfYsgG1+3g==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-jaeger/node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.24.0.tgz", + "integrity": "sha512-uEr2m13IRkjQAjX6fsYqJ21aONCspRvuQunaCl8LbH1NS1Gj82TuRUHF6TM82ulBPK8pU+nrrqXKuky2cMcIzw==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0", + "@opentelemetry/semantic-conventions": "0.24.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/resources/node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.24.0.tgz", + "integrity": "sha512-a/szuMQV0Quy0/M7kKdglcbRSoorleyyOwbTNNJ32O+RBN766wbQlMTvdimImTmwYWGr+NJOni1EcC242WlRcA==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/tracing": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.24.0.tgz", + "integrity": "sha512-sTLEs1SIon3xV8vLe53PzfbU0FahoxL9NPY/CYvA1mwGbMu4zHkHAjqy1Tc8JmqRrfa+XrHkmzeSM4hrvloBaA==", + "deprecated": "Package renamed to @opentelemetry/sdk-trace-base", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0", + "@opentelemetry/resources": "0.24.0", + "@opentelemetry/semantic-conventions": "0.24.0", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/tracing/node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", + "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/formatio": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", + "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^5.0.2" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.2.0.tgz", + "integrity": "sha512-CaIcyX5cDsjcW/ab7HposFWzV1kC++4HNsfnEdFJa7cP1QIuILAKV+BgfeqRXhcnSAc76r/Rh/O5C+300BwUIw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", + "integrity": "sha512-G+ITQPXkwTrslfG5L/BksmbLUA0M1iybEsmCWPqzSxsRRhJZimBKJkoMi8fr/CPygPTj4zO5pJH7I2/cm9M7SQ==", + "dev": true + }, + "node_modules/@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, + "node_modules/@types/node": { + "version": "14.14.7", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz", + "integrity": "sha512-Zw1vhUSQZYw+7u5dAwNbIA9TuTotpzY/OF7sJM9FqPOF3SPjKnxrjoTktXDZgUjybf4cWVBP7O8wvKdSaGHweg==", + "dev": true + }, + "node_modules/@types/superagent": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", + "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", + "dev": true, + "dependencies": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "node_modules/@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/any-promise": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", + "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", + "dev": true + }, + "node_modules/anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-each": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/array-slice": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.0.tgz", + "integrity": "sha512-Jrdy04F2EKcNggUDfubMUPNAZg2vMquLQSm8sKLYJvz40ClFL1S8GKyDshGkNsbNNE5Z+fQavzU7nSK1I9JUGA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/binary-extensions": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.1.0.tgz", + "integrity": "sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bn.js": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.3.tgz", + "integrity": "sha512-GkTiFpjFtUzU9CbMeJ5iazkCzGL3jrhzerzZIuqLABjbwRaFt33I9tUdSNryIptM+RxDet6OKm2WnLXzW51KsQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-rsa/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-sign/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-http": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", + "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", + "dev": true, + "dependencies": { + "@types/chai": "4", + "@types/superagent": "^3.8.3", + "cookiejar": "^2.1.1", + "is-ip": "^2.0.0", + "methods": "^1.1.2", + "qs": "^6.5.1", + "superagent": "^3.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/chokidar": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.3.tgz", + "integrity": "sha512-DtM3g7juCXQxFVSNPNByEC2+NImtBuxQQvWlHunpJIS5Ocr0lG306cC7FCi7cEA0fzmybPUIl4txBIobk1gGOQ==", + "dev": true, + "dependencies": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "optionalDependencies": { + "fsevents": "~2.1.2" + } + }, + "node_modules/chokidar/node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/chokidar/node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/chokidar/node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/colorette": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.1.0.tgz", + "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + }, + "node_modules/compare-module-exports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", + "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", + "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-property/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/dottie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", + "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", + "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "dependencies": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/node_modules/qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extend-shallow/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fined": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz", + "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "is-plain-object": "^2.0.3", + "object.defaults": "^1.1.0", + "object.pick": "^1.2.0", + "parse-filepath": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flagged-respawn": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz", + "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/for-own": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", + "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, + "dependencies": { + "for-in": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formidable": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.2.tgz", + "integrity": "sha512-V8gLm+41I/8kguQ4/o1D3RIHRmhYFG4pnNyonvua+40rqcEmT4+V71yaZ3B457xbbgCsCfjSPi65u/W6vK1U5Q==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "dev": true, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "deprecated": "\"Please update to latest v2.3 or v2.2\"", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/getopts": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", + "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", + "dev": true + }, + "node_modules/glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash-base/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/http-errors/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflection": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", + "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", + "dev": true, + "engines": [ + "node >= 0.4.0" + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "node_modules/is-core-module": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.1.0.tgz", + "integrity": "sha512-YcV7BgVMRFRua2FqQzKtTDMz8iCuLEyGKjr70q8Zm1yy2qKcurbFEd79PAdHV77oL3NrAaOVQIbMmiHQCHB7ZA==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "dependencies": { + "number-is-nan": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", + "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", + "dev": true, + "dependencies": { + "ip-regex": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/just-extend": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.1.tgz", + "integrity": "sha512-aWgeGFW67BP3e5181Ep1Fv2v8z//iBJfrvyTnq8wG86vEESwmonn1zPBJ0VfmT9CJq2FIT0VsETtrNFm2a+SHA==", + "dev": true + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/knex": { + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/knex/-/knex-0.19.5.tgz", + "integrity": "sha512-Hy258avCVircQq+oj3WBqPzl8jDIte438Qlq+8pt1i/TyLYVA4zPh2uKc7Bx0t+qOpa6D42HJ2jjtl2vagzilw==", + "dev": true, + "dependencies": { + "bluebird": "^3.7.0", + "colorette": "1.1.0", + "commander": "^3.0.2", + "debug": "4.1.1", + "getopts": "2.2.5", + "inherits": "~2.0.4", + "interpret": "^1.2.0", + "liftoff": "3.1.0", + "lodash": "^4.17.15", + "mkdirp": "^0.5.1", + "pg-connection-string": "2.1.0", + "tarn": "^2.0.0", + "tildify": "2.0.0", + "uuid": "^3.3.3", + "v8flags": "^3.1.3" + }, + "bin": { + "knex": "bin/cli.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/knex/node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/knex/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", + "dev": true, + "bin": { + "uuid": "bin/uuid" + } + }, + "node_modules/liftoff": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", + "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "findup-sync": "^3.0.0", + "fined": "^1.0.1", + "flagged-respawn": "^1.0.0", + "is-plain-object": "^2.0.4", + "object.map": "^1.0.0", + "rechoir": "^0.6.2", + "resolve": "^1.1.7" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-iterator": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", + "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "dependencies": { + "mime-db": "1.44.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mixin-deep/node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.2.1.tgz", + "integrity": "sha512-cuLBVfyFfFqbNR0uUKbDGXKGk+UDFe6aR4os78XIrMQpZl/nv7JYHcvP5MFIAb374b2zFXsdgEGwmzMtP0Xg8w==", + "dev": true, + "dependencies": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.4.3", + "debug": "4.2.0", + "diff": "4.0.2", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.14.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.2", + "nanoid": "3.1.12", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "7.2.0", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.0.2", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "2.0.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 10.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/mochajs" + } + }, + "node_modules/mocha/node_modules/ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/mocha/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/mocha/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/mocha/node_modules/debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/mocha/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mocha/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mocha/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mocha/node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/mocha/node_modules/y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", + "dev": true + }, + "node_modules/mocha/node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "dependencies": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + }, + "node_modules/mocha/node_modules/yargs/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.31", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz", + "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==", + "dev": true, + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/nanoid": { + "version": "3.1.12", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", + "integrity": "sha512-1qstj9z5+x491jfiC4Nelk+f8XBad7LN20PmyWINJEMRSf3wcAjAWysw1qaA8z6NSKe2sjq1hRSDpBH5paCb6A==", + "dev": true, + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || >=13.7" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nise": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", + "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/node-libs-browser/node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.defaults": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", + "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, + "dependencies": { + "array-each": "^1.0.1", + "array-slice": "^1.0.0", + "for-own": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", + "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, + "dependencies": { + "for-own": "^1.0.0", + "make-iterator": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "node_modules/p-limit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", + "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parse-filepath": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", + "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "map-cache": "^0.2.0", + "path-root": "^0.1.1" + }, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true + }, + "node_modules/path-root": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", + "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, + "dependencies": { + "path-root-regex": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-root-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pg-connection-string": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.1.0.tgz", + "integrity": "sha512-bhlV7Eq09JrRIvo1eKngpwuqKtJnNhZdpdOlvrPrA4dxqXPjxSrbNrfnIDmTpwMyRszrcV4kU5ZA4mMsQUrjdg==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "dependencies": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "node_modules/qs": { + "version": "6.9.4", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.9.4.tgz", + "integrity": "sha512-A1kFqHekCTM7cz0udomYUoYNWjBebHm/5wzU/XqrBRBNWectVH0QIiN+NEcZ0Dte5hvzHwbr8+XQmguPhJ6WdQ==", + "dev": true, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "dependencies": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", + "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, + "dependencies": { + "resolve": "^1.1.6" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/resolve": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.19.0.tgz", + "integrity": "sha512-rArEXAgsBG4UgRGcynxWIWKFvh/XZCcS8UJdHhwy91zwAvCZIbcs+vAbflgBnNjYMs/i/i+/Ux6IZhML1yPvxg==", + "dev": true, + "dependencies": { + "is-core-module": "^2.1.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry-as-promised": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", + "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", + "dev": true, + "dependencies": { + "any-promise": "^1.3.0" + } + }, + "node_modules/rewiremock": { + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.3.tgz", + "integrity": "sha512-6BaUGfp7NtxBjisxcGN73nNiA2fS2AwhEk/9DMUqxfv5v0aDM1wpOYpj5GSArqsJi07YCfLhkD8C74LAN7+FkQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "compare-module-exports": "^2.1.0", + "lodash.some": "^4.6.0", + "lodash.template": "^4.4.0", + "node-libs-browser": "^2.1.0", + "path-parse": "^1.0.5", + "wipe-node-cache": "^2.1.2", + "wipe-webpack-cache": "^2.1.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/sequelize": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.3.5.tgz", + "integrity": "sha512-MiwiPkYSA8NWttRKAXdU9h0TxP6HAc1fl7qZmMO/VQqQOND83G4nZLXd0kWILtAoT9cxtZgFqeb/MPYgEeXwsw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "dottie": "^2.0.0", + "inflection": "1.12.0", + "lodash": "^4.17.15", + "moment": "^2.26.0", + "moment-timezone": "^0.5.31", + "retry-as-promised": "^3.2.0", + "semver": "^7.3.2", + "sequelize-pool": "^6.0.0", + "toposort-class": "^1.0.1", + "uuid": "^8.1.0", + "validator": "^10.11.0", + "wkx": "^0.5.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependenciesMeta": { + "mariadb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-hstore": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/sequelize-pool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", + "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/sequelize/node_modules/debug": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", + "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/sinon": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz", + "integrity": "sha512-naPfsamB5KEE1aiioaoqJ6MEhdUs/2vtI5w1hPAXX/UwvoPjXcwh1m5HiKx0HGgKR8lQSoFIgY5jM6KK8VrS9w==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/formatio": "^5.0.1", + "@sinonjs/samsam": "^5.2.0", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon-chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", + "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0 <10.0.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "dependencies": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "dependencies": { + "ansi-regex": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dev": true, + "dependencies": { + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tarn": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tarn/-/tarn-2.0.0.tgz", + "integrity": "sha512-7rNMCZd3s9bhQh47ksAQd92ADFcJUjjbyOvyFjNLwTPpGieFHMC84S+LOzw0fx1uh6hnDz/19r8CPMnIjJlMMA==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/tildify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tildify/-/tildify-2.0.0.tgz", + "integrity": "sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, + "dependencies": { + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/instrumentation-all": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-all/-/instrumentation-all-0.0.22.tgz", - "integrity": "sha512-HqeZPpjubUpQxEAi2L2uBtWcKDbvYDqB3qS1lNsEJg1cjcRBBiVKYhceM6rMcXcBGqzZlce87LyKe4HkDboXhg==", + "node_modules/toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", "dev": true, - "requires": { - "@opencensus/instrumentation-grpc": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "@opencensus/instrumentation-http2": "^0.0.22", - "@opencensus/instrumentation-https": "^0.0.22", - "@opencensus/instrumentation-ioredis": "^0.0.22", - "@opencensus/instrumentation-mongodb": "^0.0.22", - "@opencensus/instrumentation-redis": "^0.0.22" + "engines": { + "node": ">=0.6" } }, - "@opencensus/instrumentation-grpc": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-grpc/-/instrumentation-grpc-0.0.22.tgz", - "integrity": "sha512-28jq9x+vgwmC8GHi1ZbC7KOQyOXTobnIgiHPpm7mHSaqF6NqBsdbts8HoMSirDDdJOrfTXDiu1Muz1wPLhcuRQ==", + "node_modules/toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=", + "dev": true + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/propagation-binaryformat": "^0.0.22", - "grpc": "^1.24.2", - "lodash": "^4.17.11", - "object-sizeof": "^1.3.0", - "shimmer": "^1.2.0" + "engines": { + "node": ">=4" } }, - "@opencensus/instrumentation-http": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-http/-/instrumentation-http-0.0.22.tgz", - "integrity": "sha512-I/ysuBPpZecidJmt3kLe6/k5pz8GK6QvhyZj7AxxHi6z21zRQjsWYblHXjBpaAkpqvj3bPXjJ14aIntHB/x5mQ==", + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "@opencensus/instrumentation-http2": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-http2/-/instrumentation-http2-0.0.22.tgz", - "integrity": "sha512-cauishqr8zCR8B3mCAGWqOvHQ2DJAlqoGWgeRQB/NqEnrKyoeEiIb4pNqAmoa6uKmMhggS+dGD10Kln7iAbG8A==", + "node_modules/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/instrumentation-https": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-https/-/instrumentation-https-0.0.22.tgz", - "integrity": "sha512-a4S1hN2Z5bXNu4E3O3cqhqk5EdU4MJBkzaSV1Wbn3KuUEQno1Zl4m6++/tL8cbDMRm1r7jIDu1PiVGuLW597Nw==", + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/instrumentation-ioredis": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-ioredis/-/instrumentation-ioredis-0.0.22.tgz", - "integrity": "sha512-0fK6ew3hzHkPLLPE+A2fNSuu/4zx7f3nxVk/6nKFx4VRyLgaX69Pxd7jVlr1XH0T8sgiRjE4vZBaCy5gV/Sb0A==", + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "engines": { + "node": ">= 0.8" } }, - "@opencensus/instrumentation-mongodb": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-mongodb/-/instrumentation-mongodb-0.0.22.tgz", - "integrity": "sha512-GXbKnGYpVN+/uFso4TZ3RjORqyawsmcEY1zqkiX3n16b9i9K4s8jO/9iwvsuMfOe+DJWo+s+eP23enpNYMz9rw==", + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "shimmer": "^1.2.0" + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/instrumentation-redis": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-redis/-/instrumentation-redis-0.0.22.tgz", - "integrity": "sha512-yws+jq2SSdShG5Ak1mVb0KQ05Yxehi3oW2CcY6h0DD48Kb92qIWwHxRPihQnkXO9n40IFOUFYVCpr2FjwrwnVw==", + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/nodejs": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/nodejs/-/nodejs-0.0.22.tgz", - "integrity": "sha512-CnOgSSJhmpkEGD2n1M5RAx32VSHM10EjZzzXIa29Lwdu4zwgo5oiEGUSjXQ4chYj/6tToe+hcIJMlqvNPJ35cQ==", + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-all": "^0.0.22", - "@opencensus/nodejs-base": "^0.0.22" + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/nodejs-base": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/nodejs-base/-/nodejs-base-0.0.22.tgz", - "integrity": "sha512-pSxrV7q0kwAtjbFdOYTb4NaVV1wt7eXzBBAdVhlImDiyzZeSlOXmDAmlHOzIJSSXCcou2gspN7Pf6L9HarJe3w==", + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "extend": "^3.0.2", - "require-in-the-middle": "^4.0.0" + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/propagation-binaryformat": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-binaryformat/-/propagation-binaryformat-0.0.22.tgz", - "integrity": "sha512-11aJINuxtaFt5/SmHD+YiaQZjdgc9iIXcby9gL6bqbpceETJDUGeeV0mK2RkW+no5hemokO2SvBvbM/gkJSMeg==", + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22" + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" } }, - "@opencensus/propagation-tracecontext": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-tracecontext/-/propagation-tracecontext-0.0.22.tgz", - "integrity": "sha512-y8U0hCXQwx9WZ5yYh63b37R3+MBmbhQ0xx9AySDDLszcI8IlhcXEuQvmXnirskINiJCBLK9rLryrN4r+wWwUmw==", + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22" + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", + "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8flags": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.2.0.tgz", + "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==", + "dev": true, + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wipe-node-cache": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.2.tgz", + "integrity": "sha512-m7NXa8qSxBGMtdQilOu53ctMaIBXy93FOP04EC1Uf4bpsE+r+adfLKwIMIvGbABsznaSNxK/ErD4xXDyY5og9w==", + "dev": true + }, + "node_modules/wipe-webpack-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", + "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", + "dev": true, + "dependencies": { + "wipe-node-cache": "^2.1.0" + } + }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/workerpool": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.0.2.tgz", + "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", + "dev": true + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "node_modules/yargs-parser/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "dependencies": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs-unparser/node_modules/camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yargs-unparser/node_modules/decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { "@opentelemetry/api": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz", @@ -163,7 +5170,8 @@ "version": "0.24.0", "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.24.0.tgz", "integrity": "sha512-Db8AgMByBEFKLJGSUBlNq4Un/Tqzj5W0hTxx3hIic8DvBwqbvUvkMGuiQYLKE2Ay21cLYMT01xK4TEKz0OxADw==", - "dev": true + "dev": true, + "requires": {} }, "@opentelemetry/core": { "version": "0.24.0", @@ -340,16 +5348,6 @@ "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", "dev": true }, - "@types/bytebuffer": { - "version": "5.0.42", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.42.tgz", - "integrity": "sha512-lEgKojWUAc/MG2t649oZS5AfYFP2xRNPoDuwDBlBMjHXd8MaGPgFgtCXUK7inZdBOygmVf10qxc1Us8GXC96aw==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, "@types/chai": { "version": "4.2.14", "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.14.tgz", @@ -362,12 +5360,6 @@ "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", - "dev": true - }, "@types/node": { "version": "14.14.7", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.14.7.tgz", @@ -390,12 +5382,6 @@ "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", "dev": true }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -440,23 +5426,7 @@ "dev": true, "requires": { "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" + "picomatch": "^2.0.4" } }, "argparse": { @@ -510,16 +5480,6 @@ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", "dev": true }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", - "dev": true, - "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" - } - }, "asn1.js": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", @@ -579,24 +5539,6 @@ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", "dev": true }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "dev": true, - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -896,16 +5838,6 @@ "pako": "~1.0.5" } }, - "buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", @@ -918,15 +5850,6 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", - "dev": true, - "requires": { - "long": "~3" - } - }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -950,12 +5873,6 @@ "unset-value": "^1.0.0" } }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, "chai": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", @@ -1052,12 +5969,6 @@ } } }, - "chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "dev": true - }, "cipher-base": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", @@ -1091,17 +6002,6 @@ } } }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", @@ -1139,12 +6039,6 @@ "integrity": "sha512-6S062WDQUXi6hOfkO/sBPVwE5ASXY4G2+b4atvhJfSsuUUhIaUKlkjLe9692Ipyt5/a+IPF5aVTu3V5gvXq5cg==", "dev": true }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", - "dev": true - }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -1184,12 +6078,6 @@ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", @@ -1211,16 +6099,6 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "dev": true, - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, "cookie": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", @@ -1351,12 +6229,6 @@ "type-detect": "^4.0.0" } }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, "define-property": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", @@ -1404,12 +6276,6 @@ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", "dev": true }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, "depd": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", @@ -1438,12 +6304,6 @@ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", "dev": true }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", - "dev": true - }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -1510,15 +6370,6 @@ } } }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "dev": true, - "requires": { - "shimmer": "^1.2.0" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -1938,15 +6789,6 @@ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", "dev": true }, - "fs-minipass": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", - "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", - "dev": true, - "requires": { - "minipass": "^2.6.0" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -1966,22 +6808,6 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", - "dev": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -2059,20 +6885,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "grpc": { - "version": "1.24.4", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.4.tgz", - "integrity": "sha512-mHRAwuitCMuSHo1tp1+Zc0sz3cYa7pkhVJ77pkIXD5gcVORtkRiyW6msXYqTDT+35jazg98lbO3XzuTo2+XrcA==", - "dev": true, - "requires": { - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "node-pre-gyp": "^0.16.0", - "protobufjs": "^5.0.3" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -2088,12 +6900,6 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, "has-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", @@ -2234,15 +7040,6 @@ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, - "ignore-walk": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.3.tgz", - "integrity": "sha512-m7o6xuOaT1aqheYHKf8W6J5pYH85ZI9w077erOzLje3JsB1gkafkAhHHY19dqjulgIZHFm32Cp5uNZgcQqdJKw==", - "dev": true, - "requires": { - "minimatch": "^3.0.4" - } - }, "inflection": { "version": "1.12.0", "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", @@ -2277,12 +7074,6 @@ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", "dev": true }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -2566,15 +7357,6 @@ } } }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, "liftoff": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz", @@ -2612,18 +7394,6 @@ "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", "dev": true }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", - "dev": true - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -2661,12 +7431,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, "log-symbols": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", @@ -2676,12 +7440,6 @@ "chalk": "^4.0.0" } }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true - }, "make-iterator": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", @@ -2822,25 +7580,6 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, - "minipass": { - "version": "2.9.0", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", - "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", - "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", - "dev": true, - "requires": { - "minipass": "^2.9.0" - } - }, "mixin-deep": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", @@ -3077,12 +7816,6 @@ } } }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=", - "dev": true - }, "moment": { "version": "2.29.1", "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", @@ -3104,12 +7837,6 @@ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true }, - "nan": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.2.tgz", - "integrity": "sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==", - "dev": true - }, "nanoid": { "version": "3.1.12", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.12.tgz", @@ -3135,17 +7862,6 @@ "to-regex": "^3.0.1" } }, - "needle": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/needle/-/needle-2.5.2.tgz", - "integrity": "sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==", - "dev": true, - "requires": { - "debug": "^3.2.6", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, "negotiator": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", @@ -3226,86 +7942,12 @@ } } }, - "node-pre-gyp": { - "version": "0.16.0", - "resolved": "https://registry.npmjs.org/node-pre-gyp/-/node-pre-gyp-0.16.0.tgz", - "integrity": "sha512-4efGA+X/YXAHLi1hN8KaPrILULaUn2nWecFrn1k2I+99HpoyvcOGEbtcOxpDiUwPF2ZANMJDh32qwOUPenuR1g==", - "dev": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.3", - "needle": "^2.5.0", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4.4.2" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "nopt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-4.0.3.tgz", - "integrity": "sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==", - "dev": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, "normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", "dev": true }, - "npm-bundled": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.1.1.tgz", - "integrity": "sha512-gqkfgGePhTpAEgUsGEgcq1rqPXA+tv/aVBlgEzfXwA1yiUJF7xtEt3CtVwOjNYQOVknDk0F20w58Fnm3EtG0fA==", - "dev": true, - "requires": { - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npm-normalize-package-bin": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", - "integrity": "sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==", - "dev": true - }, - "npm-packlist": { - "version": "1.4.8", - "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.4.8.tgz", - "integrity": "sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==", - "dev": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1", - "npm-normalize-package-bin": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, "number-is-nan": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", @@ -3349,15 +7991,6 @@ } } }, - "object-sizeof": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/object-sizeof/-/object-sizeof-1.6.1.tgz", - "integrity": "sha512-gNKGcRnDRXwEpAdwUY3Ef+aVZIrcQVXozSaVzHz6Pv4JxysH8vf5F+nIgsqW5T/YNwZNveh0mIW7PEH1O2MrDw==", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, "object-visit": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", @@ -3416,49 +8049,12 @@ "wrappy": "1" } }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "osenv": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", - "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", - "dev": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, "p-limit": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz", @@ -3625,18 +8221,6 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - } - }, "proxy-addr": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", @@ -3730,18 +8314,6 @@ "unpipe": "1.0.0" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -3809,28 +8381,6 @@ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, - "require-in-the-middle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.1.tgz", - "integrity": "sha512-EfkM2zANyGkrfIExsECMeNn/uzjvHrE9h36yLXSavmrDiH4tgDNvltAmEKnt4PNLbqKPHZz+uszW2wTKrLUX0w==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.2.0.tgz", - "integrity": "sha512-IX2ncY78vDTjZMFUdmsvIRFY2Cf4FnD0wRs+nQwJU8Lu99/tPFdb0VybiiMTPe3I6rQmwsqQqRBvxU+bZ/I8sg==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } - } - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -3894,15 +8444,6 @@ "wipe-webpack-cache": "^2.1.0" } }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "ripemd160": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", @@ -3934,12 +8475,6 @@ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", "dev": true }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", - "dev": true - }, "semver": { "version": "7.3.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", @@ -4102,18 +8637,6 @@ "safe-buffer": "^5.0.1" } }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", - "dev": true - }, - "signal-exit": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true - }, "sinon": { "version": "9.2.1", "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.1.tgz", @@ -4133,7 +8656,8 @@ "version": "3.5.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true + "dev": true, + "requires": {} }, "snapdragon": { "version": "0.8.2", @@ -4347,6 +8871,15 @@ "xtend": "^4.0.0" } }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, "string-width": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", @@ -4358,15 +8891,6 @@ "strip-ansi": "^3.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, "strip-ansi": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", @@ -4376,12 +8900,6 @@ "ansi-regex": "^2.0.0" } }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "superagent": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", @@ -4409,29 +8927,6 @@ "has-flag": "^4.0.0" } }, - "tar": { - "version": "4.4.19", - "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.19.tgz", - "integrity": "sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==", - "dev": true, - "requires": { - "chownr": "^1.1.4", - "fs-minipass": "^1.2.7", - "minipass": "^2.9.0", - "minizlib": "^1.3.3", - "mkdirp": "^0.5.5", - "safe-buffer": "^5.2.1", - "yallist": "^3.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true - } - } - }, "tarn": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/tarn/-/tarn-2.0.0.tgz", @@ -4715,12 +9210,6 @@ "string-width": "^1.0.2 || 2" } }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, "wipe-node-cache": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.2.tgz", @@ -4751,16 +9240,6 @@ "integrity": "sha512-DSNyvOpFKrNusaaUwk+ej6cBj1bmhLcBfj80elGk+ZIo5JSkq+unB1dLKEOcNfJDZgjGICfhQ0Q5TbP0PvF4+Q==", "dev": true }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -4773,33 +9252,6 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, - "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", - "dev": true - }, - "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - }, "yargs-parser": { "version": "13.1.2", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package.json b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package.json index c8c51640..af56a2a4 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package.json +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/package.json @@ -7,8 +7,6 @@ "test": "test" }, "devDependencies": { - "@opencensus/nodejs": "^0.0.22", - "@opencensus/propagation-tracecontext": "^0.0.22", "@opentelemetry/api": "^1.0.3", "@opentelemetry/core": "^0.24.0", "@opentelemetry/node": "^0.24.0", @@ -23,8 +21,6 @@ "sinon-chai": "^3.5.0" }, "peerDependencies": { - "@opencensus/nodejs": "^0.0.22", - "@opencensus/propagation-tracecontext": "^0.0.22", "@opentelemetry/core": "^0.24.0" }, "engines": { @@ -39,4 +35,4 @@ }, "author": "Google, LLC.", "license": "Apache-2.0" -} +} \ No newline at end of file diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/index.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/index.js index e0196eef..70006baf 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/index.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/index.js @@ -12,12 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -const OpenCensus = require('./opencensus'); const OpenTelemetry = require('./opentelemetry'); const providers = { - 'opentelemetry': OpenTelemetry, - 'opencensus': OpenCensus, + 'opentelemetry': OpenTelemetry } exports.attachComments = function attachComments(providerName, comments) { @@ -25,6 +23,6 @@ exports.attachComments = function attachComments(providerName, comments) { if (!comments || typeof comments !== 'object') return; // Lookup the provider by name, or use the default. - let provider = providers[String(providerName).toLowerCase()] || OpenCensus; + let provider = providers[String(providerName).toLowerCase()] || OpenTelemetry; provider.addW3CTraceContext(comments); } diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/opencensus.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/opencensus.js deleted file mode 100644 index c36cb6de..00000000 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/provider/opencensus.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -const {tracer} = require('@opencensus/nodejs'); -const {toW3CTraceContext} = require('../util'); - -exports.addW3CTraceContext = function(comments) { - if (tracer.active) { - toW3CTraceContext(tracer.currentRootSpan, comments); - } -}; diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/comment.test.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/comment.test.js index 90e4efde..a3ac3aa4 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/comment.test.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/comment.test.js @@ -14,14 +14,12 @@ "use strict"; -const {wrapMainKnex} = require('../index'); -const opencensus_tracing = require('@opencensus/nodejs'); +const { wrapMainKnex } = require('../index'); const chai = require("chai"); -const {fields} = require('../util'); -const {context, trace} = require('@opentelemetry/api'); -const {NodeTracerProvider} = require('@opentelemetry/node'); -const {AsyncHooksContextManager} = require('@opentelemetry/context-async-hooks'); -const {InMemorySpanExporter, SimpleSpanProcessor} = require('@opentelemetry/tracing'); +const { context, trace } = require('@opentelemetry/api'); +const { NodeTracerProvider } = require('@opentelemetry/node'); +const { AsyncHooksContextManager } = require('@opentelemetry/context-async-hooks'); +const { InMemorySpanExporter, SimpleSpanProcessor } = require('@opentelemetry/tracing'); const expect = chai.expect; @@ -30,7 +28,7 @@ describe("Comments for Knex", () => { let fakeKnex = { Client: { prototype: { - config: { connection: { database: 'fake'}, client: 'fakesql'}, + config: { connection: { database: 'fake' }, client: 'fakesql' }, version: 'fake-server:0.0.X', query: (conn, obj) => { return Promise.resolve(obj); // simply returns a resolved promise for inspection. @@ -43,24 +41,24 @@ describe("Comments for Knex", () => { }; before(() => { - wrapMainKnex(fakeKnex, {db_driver: true}) + wrapMainKnex(fakeKnex, { db_driver: true }) }); describe("Cases", () => { it("should add comment to generated sql", (done) => { - + const want = "SELECT CURRENT_TIMESTAMP /*db_driver='knex%3Afake%3A0.0.1'*/"; - const obj = {sql: 'SELECT CURRENT_TIMESTAMP'}; + const obj = { sql: 'SELECT CURRENT_TIMESTAMP' }; - fakeKnex.Client.prototype.query(null, obj).then(({sql}) => { + fakeKnex.Client.prototype.query(null, obj).then(({ sql }) => { expect(sql).equals(want); }); done(); }); it("should NOT affix comments to statements with existing comments", (done) => { - + const queries = [ 'SELECT * FROM people /* existing */', 'SELECT * FROM people -- existing' @@ -80,7 +78,7 @@ describe("Comments for Knex", () => { const want = [ "db_driver", ]; - fakeKnex.Client.prototype.query(null, 'SELECT * from foo').then(({sql}) => { + fakeKnex.Client.prototype.query(null, 'SELECT * from foo').then(({ sql }) => { want.forEach((key) => { expect(sql.indexOf(key)).to.be.gt(-1); }); @@ -90,17 +88,17 @@ describe("Comments for Knex", () => { it("should deterministically sort keys alphabetically", (done) => { const want = "SELECT * from foo /*db_driver='knex%3Afake%3A0.0.1'*/"; - fakeKnex.Client.prototype.query(null, {sql: 'SELECT * from foo'}).then(({sql}) => { + fakeKnex.Client.prototype.query(null, { sql: 'SELECT * from foo' }).then(({ sql }) => { expect(sql).equals(want); }); done(); }); it("chaining and repeated calls should NOT indefinitely chain SQL", (done) => { - + const want = "SELECT * from foo /*db_driver='knex%3Afake%3A0.0.1'*/"; - - const obj = {sql: 'SELECT * from foo'}; + + const obj = { sql: 'SELECT * from foo' }; fakeKnex.Client.prototype.query(null, obj) .then((a) => fakeKnex.Client.prototype.query(null, a)) @@ -109,61 +107,19 @@ describe("Comments for Knex", () => { .then((d) => { expect(d.sql).equals(want); }); - + done(); }); }); }); -describe("With OpenCensus tracing", () => { - - let fakeKnex = { - Client: { - prototype: { - config: { connection: { database: 'fake'}, client: 'fakesql'}, - version: 'fake-server:0.0.X', - query: (conn, obj) => { - return Promise.resolve(obj); // simply returns a resolved promise for inspection. - } - } - }, - VERSION: () => { - return 'fake:0.0.1'; - } - }; - - before(() => { - wrapMainKnex(fakeKnex, {db_driver: true, traceparent: true, tracestate: true}, {TraceProvider: "OpenCensus"}); - }); - - it('Starting an OpenCensus trace should produce `traceparent`', (done) => { - // Let's remember https://github.com/census-instrumentation/opencensus-node/issues/580 - - const traceOptions = { - samplingRate: 1, // Always sample - }; - const tracer = opencensus_tracing.start(traceOptions).tracer; - - tracer.startRootSpan({ name: 'with-tracing' }, rootSpan => { - const obj = {sql: 'SELECT * FROM foo'}; - fakeKnex.Client.prototype.query(null, obj).then((got) => { - const augmentedSQL = got.sql; - const wantSQL = `SELECT * FROM foo /*db_driver='knex%3Afake%3A0.0.1',traceparent='00-${rootSpan.traceId}-${rootSpan.id}-01'*/`; - expect(augmentedSQL).equals(wantSQL); - opencensus_tracing.tracer.stop(); - done(); - }); - }); - }); -}); - describe("With OpenTelemetry tracing", () => { let fakeKnex = { Client: { prototype: { - config: { connection: { database: 'fake'}, client: 'fakesql'}, + config: { connection: { database: 'fake' }, client: 'fakesql' }, version: 'fake-server:0.0.X', query: (conn, obj) => { return Promise.resolve(obj); // simply returns a resolved promise for inspection. @@ -187,7 +143,7 @@ describe("With OpenTelemetry tracing", () => { before(() => { contextManager = new AsyncHooksContextManager(); context.setGlobalContextManager(contextManager.enable()); - wrapMainKnex(fakeKnex, {db_driver: true, traceparent: true, tracestate: true}, {TraceProvider: "OpenTelemetry"}); + wrapMainKnex(fakeKnex, { db_driver: true, traceparent: true, tracestate: true }, { TraceProvider: "" }); }); after(() => { @@ -198,10 +154,11 @@ describe("With OpenTelemetry tracing", () => { it('Starting an OpenTelemetry trace should produce `traceparent`', (done) => { const rootSpan = tracer.startSpan('rootSpan'); context.with(trace.setSpan(context.active(), rootSpan), async () => { - const obj = {sql: 'SELECT * FROM foo'}; + const obj = { sql: 'SELECT * FROM foo' }; fakeKnex.Client.prototype.query(null, obj).then((got) => { const augmentedSQL = got.sql; const wantSQL = `SELECT * FROM foo /*db_driver='knex%3Afake%3A0.0.1',traceparent='00-${rootSpan.spanContext().traceId}-${rootSpan.spanContext().spanId}-01'*/`; + console.log(augmentedSQL); expect(augmentedSQL).equals(wantSQL); rootSpan.end(); done(); diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/provider.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/provider.js index d11e1360..27065932 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/provider.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/provider.js @@ -26,15 +26,14 @@ const openCensusMock = sinon.spy(); const openTelemetryMock = sinon.spy(); // Mock the dependencies of provider to make use of faked methods for adding trace context -rewiremock('../../provider/opencensus').with({addW3CTraceContext: openCensusMock}); -rewiremock('../../provider/opentelemetry').with({addW3CTraceContext: openTelemetryMock}); +rewiremock('../../provider/opentelemetry').with({ addW3CTraceContext: openTelemetryMock }); // Load the provider module with the appropriate mocks rewiremock.enable(); const provider = require('../../provider'); // A helper method to test which provider was called -const verifyProviderUsed = function(traceProvider, spy, used) { +const verifyProviderUsed = function (traceProvider, spy, used) { provider.attachComments(traceProvider, {}); expect(spy.called).to.equal(used); }; @@ -43,42 +42,26 @@ describe("Provider", () => { describe("attachComment", () => { beforeEach(() => { - openCensusMock.resetHistory(); openTelemetryMock.resetHistory(); }) - it("should default to OpenCensus when no options are provided", () => { - verifyProviderUsed(undefined, openCensusMock, true); - verifyProviderUsed(undefined, openTelemetryMock, false); + it("should default to OpenTelemetry when no options are provided", () => { + verifyProviderUsed(undefined, openTelemetryMock, true); }); - it("should default to OpenCensus when null is provided", () => { - verifyProviderUsed(null, openCensusMock, true); - verifyProviderUsed(null, openTelemetryMock, false); + it("should default to OpenTelemetry when null is provided", () => { + verifyProviderUsed(null, openTelemetryMock, true); }); - it("should default to OpenCensus when invalid options are provided", () => { - verifyProviderUsed("bad trace library name", openCensusMock, true); - verifyProviderUsed("bad trace library name", openTelemetryMock, false); - }); - - it("should use OpenCensus when the name is provided", () => { - verifyProviderUsed("opencensus", openCensusMock, true); - verifyProviderUsed("opencensus", openTelemetryMock, false); - }); - - it("should accept an arbitrary capitalization of OpenCensus", () => { - verifyProviderUsed("oPeNceNSus", openCensusMock, true); - verifyProviderUsed("oPeNceNSus", openTelemetryMock, false); + it("should default to OpenTelemetry when invalid options are provided", () => { + verifyProviderUsed("bad trace library name", openTelemetryMock, true); }); it("should use OpenTelemetry when the name is provided", () => { - verifyProviderUsed("opentelemetry", openCensusMock, false); verifyProviderUsed("opentelemetry", openTelemetryMock, true); }); it("should accept an arbitrary capitalization of OpenTelemetry", () => { - verifyProviderUsed("OpenTeleMetRY", openCensusMock, false); verifyProviderUsed("OpenTeleMetRY", openTelemetryMock, true); }); diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/util.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/util.js index 3f11fed5..acde2914 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/util.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/test/unit/util.js @@ -14,7 +14,7 @@ "use strict"; -const {hasComment, toW3CTraceContext} = require('../../util'); +const { hasComment } = require('../../util'); const chai = require("chai"); const expect = chai.expect; @@ -23,7 +23,7 @@ describe("Unit", () => { describe("hasComment", () => { it("should return true for well-formed comments", () => { - + const queries = [ `SELECT * FROM foo /* existing */`, `SELECT * FROM foo -- existing` @@ -34,86 +34,21 @@ describe("Unit", () => { expect(hasComment(q)).to.equal(want) }); }); - + it("should return false when comment is undefined", () => { let comment; expect(hasComment(comment)).to.equal(false); }); - + it("should return false for malformed comments", () => { const queries = [ "SELECT * FROM people /*", "SELECT * FROM people */ /*" ]; - + queries.forEach(q => { expect(hasComment(q)).to.equal(false); }); }); }); - - describe("toW3CTraceContext", () => { - - it("should return undefined/null for undefined/null span", () => { - const badParams = [ - null, - undefined - ]; - const obj = {}; - expect(toW3CTraceContext(badParams[0], null)).to.be.null; - expect(toW3CTraceContext(badParams[1], null)).to.be.null; - expect(toW3CTraceContext(badParams[0], obj)).to.equal(obj); - expect(toW3CTraceContext(badParams[1], obj)).to.equal(obj); - }); - - it("should still extract the topSpanContext even if not root span", () => { - const fakeSpan = { - spanContext: { - traceId: 'ff00000000000001', - spanId: 'ee000002', - traceState: 'congo=t61rcWkgMzE,rojo=00f067aa0ba902b7', - }, - isRootSpan() { return false; } - }; - expect(toW3CTraceContext(fakeSpan, {}).traceparent).to.equal('00-ff00000000000001-ee000002-00'); - expect(toW3CTraceContext(fakeSpan, {}).tracestate).to.equal('congo=t61rcWkgMzE,rojo=00f067aa0ba902b7'); - }); - - it("should nothing if the latest span doesn't have children", () => { - const fakeSpan = { - spanContext: {}, - spans: [], - isRootSpan() { return true; } - }; - - const got = toW3CTraceContext(fakeSpan, {}); - expect(got.traceparent).to.equal(undefined); - expect(got.tracestate).to.equal(undefined); - }); - - it("should return the last span it has children", () => { - const fakeSpan = { - spans: [{ - spanContext: { - traceId: 'ff00000000000001', - spanId: 'ee000002', - traceState: 'congo=t61rcWkgMzE,rojo=00f067aa0ba902b7', - }, - }, - { - spanContext: { - traceId: '11000000000000ff', - spanId: '020000ee', - traceState: 'brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7', - options: 0x01, // It is sampled. - }, - }], - isRootSpan() { return true; } - }; - - const got = toW3CTraceContext(fakeSpan, {}); - expect(got.traceparent).to.equal('00-11000000000000ff-020000ee-01'); - expect(got.tracestate).to.equal('brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7'); - }); - }); }); diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/util.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/util.js index e6e78599..1f2651b3 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/util.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex/util.js @@ -12,12 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -const {TraceContextFormat} = require('@opencensus/propagation-tracecontext'); -const traceContext = new TraceContextFormat(); - /** * fields represent variables that can be made optional for commenter output - */ + */ exports.fields = { CLIENT_TIMEZONE: "client_timezone", DB_DRIVER: "db_driver", @@ -49,49 +46,7 @@ exports.hasComment = (sql) => { // Check if it is a well formed comment. const indexClosingSlashComment = sql.indexOf('*/'); - - /* c8 ignore next */ - return indexOpeningSlashComment < indexClosingSlashComment; -} - -const latestSpan = (span) => { - - if (!span || !span.isRootSpan()) - return span; - - // Otherwise if it is a root span, we'll try to grab its last child. - const children = span.spans; - if (children.length < 1) - return span; /* c8 ignore next */ - return children[children.length - 1]; -} - -/** - * Adds the required fields from span to dst for tracepropagation, ensuring - * comformance with any system that uses W3C Distributed Tracing context to propagate traces. - * In addition to adding a traceparent field, a tracestate is also added to dst - * - * @param {Object} span The span object if tracing is active - * @param {Object} dst The destination object to add trace propagation fields - * @return {void} - */ -exports.toW3CTraceContext = (span, dst) => { - // TODO: check if tracer.currentRootSpan can be null/undefined when tracer is active - const curSpan = latestSpan(span); - if (!curSpan) - return dst; - - const spanContext = curSpan.spanContext || {}; - if (!(spanContext.traceId && spanContext.spanId)) - return dst; - - const setHeader = { - setHeader: (key, value) => { - dst[key] = value; - } - }; - traceContext.inject(setHeader, curSpan.spanContext); - return dst; + return indexOpeningSlashComment < indexClosingSlashComment; } From be981831e9e458caa12606287d711fbd4244886d Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 30 Aug 2022 12:13:21 +0530 Subject: [PATCH 041/108] Remove opencenus from nodejs sequelize (#153) * Removed opencensus from package.json * Removed opencensus functionalities from nodejs squelize --- .../sqlcommenter-sequelize/package-lock.json | 5978 ++++++++++++----- .../sqlcommenter-sequelize/package.json | 6 +- .../sqlcommenter-sequelize/provider/index.js | 4 +- .../provider/opencensus.js | 22 - .../test/comment.test.js | 79 +- .../test/unit/provider.js | 34 +- .../sqlcommenter-sequelize/test/unit/util.js | 75 +- .../packages/sqlcommenter-sequelize/util.js | 34 +- 8 files changed, 4438 insertions(+), 1794 deletions(-) delete mode 100644 nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/opencensus.js diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package-lock.json b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package-lock.json index 437794e7..ffe95a6f 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package-lock.json +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package-lock.json @@ -1,553 +1,3638 @@ { "name": "@google-cloud/sqlcommenter-sequelize", - "version": "0.0.3", - "lockfileVersion": 1, + "version": "1.0.0", + "lockfileVersion": 2, "requires": true, - "dependencies": { - "@mapbox/node-pre-gyp": { + "packages": { + "": { + "name": "@google-cloud/sqlcommenter-sequelize", + "version": "1.0.0", + "license": "Apache-2.0", + "devDependencies": { + "@opentelemetry/api": "^1.0.3", + "@opentelemetry/core": "^0.24.0", + "@opentelemetry/node": "^0.24.0", + "chai": "^4.2.0", + "chai-http": "^4.3.0", + "express": "^4.17.0", + "mocha": "^6.1.4", + "rewiremock": "^3.14.3", + "sequelize": "^6.3.3", + "sinon": "^9.0.3", + "sinon-chai": "^3.5.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "@opentelemetry/core": "^0.24.0" + } + }, + "node_modules/@opentelemetry/api": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.1.0.tgz", + "integrity": "sha512-hf+3bwuBwtXsugA2ULBc95qxrOqP2pOekLz34BJhcAKawt94vfeNyUKpYc0lZQ/3sCP6LqRa7UAdHA7i5UODzQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/context-async-hooks": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.24.0.tgz", + "integrity": "sha512-Db8AgMByBEFKLJGSUBlNq4Un/Tqzj5W0hTxx3hIic8DvBwqbvUvkMGuiQYLKE2Ay21cLYMT01xK4TEKz0OxADw==", + "dev": true, + "engines": { + "node": ">=8.1.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/core": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-0.24.0.tgz", + "integrity": "sha512-KpsfxBbFTZT9zaB4Es/fFLbvSzVl9Io/8UUu/TYl4/HgqkmyVInNlWTgRiKyz9nsHzFpGP1kdZJj+YIut0IFsw==", + "dev": true, + "dependencies": { + "@opentelemetry/semantic-conventions": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/node": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/node/-/node-0.24.0.tgz", + "integrity": "sha512-Sy8QooZFOeVUcJIKetw5xsq15/1ivZovWg0RnKWtzURMQrcOxmQ3bGrXPORklOJxOtf5snDHgT37Y7dBgr+c+g==", + "deprecated": "Package renamed to @opentelemetry/sdk-trace-node", + "dev": true, + "dependencies": { + "@opentelemetry/context-async-hooks": "0.24.0", + "@opentelemetry/core": "0.24.0", + "@opentelemetry/propagator-b3": "0.24.0", + "@opentelemetry/propagator-jaeger": "0.24.0", + "@opentelemetry/tracing": "0.24.0", + "semver": "^7.1.3" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-b3": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-b3/-/propagator-b3-0.24.0.tgz", + "integrity": "sha512-iV7KSN0LkEAkeVCbhaIJAgTEb7HCnVkprmpgkL6q79rP3vTW4dylwfBYgIwod7y0GT4Ofgomm0NrwwWiuGLbQA==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/propagator-jaeger": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/propagator-jaeger/-/propagator-jaeger-0.24.0.tgz", + "integrity": "sha512-QXCxBwuSka+vXbBZdumtF7YKO84gwTyKy3GelZV5BPlgWoge0AbLR3DfsO9Beu13pmD+4PyuwMw3LfYsgG1+3g==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0" + }, + "engines": { + "node": ">=8.5.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/resources": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/resources/-/resources-0.24.0.tgz", + "integrity": "sha512-uEr2m13IRkjQAjX6fsYqJ21aONCspRvuQunaCl8LbH1NS1Gj82TuRUHF6TM82ulBPK8pU+nrrqXKuky2cMcIzw==", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0", + "@opentelemetry/semantic-conventions": "0.24.0" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@opentelemetry/semantic-conventions": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-0.24.0.tgz", + "integrity": "sha512-a/szuMQV0Quy0/M7kKdglcbRSoorleyyOwbTNNJ32O+RBN766wbQlMTvdimImTmwYWGr+NJOni1EcC242WlRcA==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/@opentelemetry/tracing": { + "version": "0.24.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/tracing/-/tracing-0.24.0.tgz", + "integrity": "sha512-sTLEs1SIon3xV8vLe53PzfbU0FahoxL9NPY/CYvA1mwGbMu4zHkHAjqy1Tc8JmqRrfa+XrHkmzeSM4hrvloBaA==", + "deprecated": "Package renamed to @opentelemetry/sdk-trace-base", + "dev": true, + "dependencies": { + "@opentelemetry/core": "0.24.0", + "@opentelemetry/resources": "0.24.0", + "@opentelemetry/semantic-conventions": "0.24.0", + "lodash.merge": "^4.6.2" + }, + "engines": { + "node": ">=8.0.0" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.1" + } + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-6.0.1.tgz", + "integrity": "sha512-MZPUxrmFubI36XS1DI3qmI0YdN1gks62JtFZvxR67ljjSNCeK6U08Zx4msEWOXuofgqUt6zPHSi1H9fbjR/NRA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@sinonjs/samsam": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.6.0", + "lodash.get": "^4.4.2", + "type-detect": "^4.0.8" + } + }, + "node_modules/@sinonjs/text-encoding": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", + "dev": true + }, + "node_modules/@types/chai": { + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", + "dev": true + }, + "node_modules/@types/cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", + "dev": true + }, + "node_modules/@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "18.7.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.11.tgz", + "integrity": "sha512-KZhFpSLlmK/sdocfSAjqPETTMd0ug6HIMIAwkwUpU79olnZdQtMxpQP+G1wDzCH7na+FltSIhbaZuKdwZ8RDrw==", + "dev": true + }, + "node_modules/@types/superagent": { + "version": "3.8.7", + "resolved": "https://registry.npmjs.org/@types/superagent/-/superagent-3.8.7.tgz", + "integrity": "sha512-9KhCkyXv268A2nZ1Wvu7rQWM+BmdYUVkycFeNnYrUL5Zwu7o8wPQ3wBfW59dDP+wuoxw0ww8YKgTNv8j/cgscA==", + "dev": true, + "dependencies": { + "@types/cookiejar": "*", + "@types/node": "*" + } + }, + "node_modules/@types/validator": { + "version": "13.7.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.5.tgz", + "integrity": "sha512-9rQHeAqz6Jw3gDhttkmWetoriW5FPbxylv/6h6mXtaj2NKRcOvOmvfcswVdLVpbuy10NrO486K3lCoLgoIhiIA==", + "dev": true + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-regex": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true + }, + "node_modules/array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/asn1.js": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-5.4.1.tgz", + "integrity": "sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "safer-buffer": "^2.1.0" + } + }, + "node_modules/asn1.js/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "util": "0.10.3" + } + }, + "node_modules/assert/node_modules/inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", + "dev": true + }, + "node_modules/assert/node_modules/util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.1" + } + }, + "node_modules/assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "dev": true + }, + "node_modules/babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", + "dev": true, + "dependencies": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/bn.js": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", + "dev": true + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", + "dev": true + }, + "node_modules/browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "node_modules/browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "dependencies": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "dependencies": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "node_modules/browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/browserify-rsa": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", + "dev": true, + "dependencies": { + "bn.js": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "node_modules/browserify-sign": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.1.tgz", + "integrity": "sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg==", + "dev": true, + "dependencies": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.3", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + } + }, + "node_modules/browserify-sign/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "dependencies": { + "pako": "~1.0.5" + } + }, + "node_modules/buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "dependencies": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "node_modules/buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", + "dev": true + }, + "node_modules/builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chai": { + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", + "dev": true, + "dependencies": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", + "type-detect": "^4.0.5" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chai-http": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/chai-http/-/chai-http-4.3.0.tgz", + "integrity": "sha512-zFTxlN7HLMv+7+SPXZdkd5wUlK+KxH6Q7bIEMiEx0FK3zuuMqL7cwICAQ0V1+yYRozBburYuxN1qZstgHpFZQg==", + "dev": true, + "dependencies": { + "@types/chai": "4", + "@types/superagent": "^3.8.3", + "cookiejar": "^2.1.1", + "is-ip": "^2.0.0", + "methods": "^1.1.2", + "qs": "^6.5.1", + "superagent": "^3.7.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "dependencies": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dev": true, + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/compare-module-exports": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/compare-module-exports/-/compare-module-exports-2.1.0.tgz", + "integrity": "sha512-3Lc0sTIuX1jmY2K2RrXRJOND6KsRTX2D4v3+eu1PDptsuJZVK4LZc852eZa9I+avj0NrUKlTNgqvccNOH6mbGg==", + "dev": true + }, + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "node_modules/console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "node_modules/constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", + "dev": true + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true + }, + "node_modules/cookiejar": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", + "dev": true + }, + "node_modules/core-js": { + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/create-ecdh": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.4.tgz", + "integrity": "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "elliptic": "^6.5.3" + } + }, + "node_modules/create-ecdh/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "node_modules/create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "dependencies": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "node_modules/crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "dependencies": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + }, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "dependencies": { + "type-detect": "^4.0.0" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "node_modules/diffie-hellman/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true, + "engines": { + "node": ">=0.4", + "npm": ">=1.2" + } + }, + "node_modules/dottie": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.2.tgz", + "integrity": "sha512-fmrwR04lsniq/uSr8yikThDTrM7epXHBAAjH9TbeH3rEA8tdCO7mRzB9hdmdGyJCxF8KERo9CITcm3kGuoyMhg==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true + }, + "node_modules/elliptic": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", + "integrity": "sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==", + "dev": true, + "dependencies": { + "bn.js": "^4.11.9", + "brorand": "^1.1.0", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.4", + "minimalistic-assert": "^1.0.1", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/elliptic/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/es-abstract": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "dependencies": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/express": { + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.5.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.2.0", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/flat": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.1.tgz", + "integrity": "sha512-FmTtBsHskrU6FJ2VxCnsDb84wu9zhmO3cUX2kGFb5tuwhfXxGciiT0oRY+cck35QmG+NmGh5eLz6lLCpWTqwpA==", + "dev": true, + "dependencies": { + "is-buffer": "~2.0.3" + }, + "bin": { + "flat": "cli.js" + } + }, + "node_modules/form-data": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/formidable": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", + "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", + "dev": true, + "funding": { + "url": "https://ko-fi.com/tunnckoCore/commissions" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true, + "engines": { + "node": ">=4.x" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-property-descriptors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/hash-base/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", + "dev": true, + "dependencies": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", + "dev": true + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/inflection": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.2.tgz", + "integrity": "sha512-cmZlljCRTBFouT8UzMzrGcVEvkv6D/wBdcdKG7J1QH5cXjtU75Dm+P27v9EKu/Y43UYyCJd1WC4zLebRrC8NBw==", + "dev": true, + "engines": [ + "node >= 0.4.0" + ] + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/is-callable": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-ip": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", + "integrity": "sha512-9MTn0dteHETtyUx8pxqMwg5hMBi3pvlyglJ+b79KOCca0po23337LbVV2Hl4xmMvfw++ljnO0/+5G6G+0Szh6g==", + "dev": true, + "dependencies": { + "ip-regex": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/just-extend": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", + "dev": true + }, + "node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", + "dev": true + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", + "dev": true + }, + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "node_modules/lodash.some": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", + "dev": true + }, + "node_modules/lodash.template": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.5.0.tgz", + "integrity": "sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "node_modules/lodash.templatesettings": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.2.0.tgz", + "integrity": "sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==", + "dev": true, + "dependencies": { + "lodash._reinterpolate": "^3.0.0" + } + }, + "node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "dependencies": { + "get-func-name": "^2.0.0" + } + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "dev": true + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "dependencies": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "bin": { + "miller-rabin": "bin/miller-rabin" + } + }, + "node_modules/miller-rabin/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "node_modules/minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", + "dev": true + }, + "node_modules/minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": true + }, + "node_modules/mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "deprecated": "Legacy versions of mkdirp are no longer supported. Please update to mkdirp 1.x. (Note that the API surface has changed to use Promises in 1.x.)", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mocha": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", + "integrity": "sha512-0R/3FvjIGH3eEuG17ccFPk117XL2rWxatr81a57D+r/x2uTYZRbdZ4oVidEUMh2W2TJDa7MdAb12Lm2/qrKajg==", + "dev": true, + "dependencies": { + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "debug": "3.2.6", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", + "mkdirp": "0.5.4", + "ms": "2.1.1", + "node-environment-flags": "1.0.5", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", + "yargs-unparser": "1.6.0" + }, + "bin": { + "_mocha": "bin/_mocha", + "mocha": "bin/mocha" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/mocha/node_modules/debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/mocha/node_modules/ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.34", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", + "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", + "dev": true, + "dependencies": { + "moment": ">= 2.9.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nise": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0", + "@sinonjs/fake-timers": "^6.0.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "path-to-regexp": "^1.7.0" + } + }, + "node_modules/nise/node_modules/isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true + }, + "node_modules/nise/node_modules/path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "dev": true, + "dependencies": { + "isarray": "0.0.1" + } + }, + "node_modules/node-environment-flags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", + "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "dev": true, + "dependencies": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, + "node_modules/node-environment-flags/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "dependencies": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.getownpropertydescriptors": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", + "dev": true, + "dependencies": { + "array.prototype.reduce": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" + }, + "engines": { + "node": ">= 0.8" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", + "dev": true + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/parse-asn1": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.6.tgz", + "integrity": "sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw==", + "dev": true, + "dependencies": { + "asn1.js": "^5.2.0", + "browserify-aes": "^1.0.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true + }, + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "dev": true + }, + "node_modules/pathval": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/pbkdf2": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", + "dev": true, + "dependencies": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==", + "dev": true + }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "dependencies": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "node_modules/public-encrypt/node_modules/bn.js": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", + "dev": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", + "deprecated": "The querystring API is considered Legacy. new code should use the URLSearchParams API instead.", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "dependencies": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/readable-stream/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/readable-stream/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "node_modules/retry-as-promised": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", + "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==", + "dev": true + }, + "node_modules/rewiremock": { + "version": "3.14.3", + "resolved": "https://registry.npmjs.org/rewiremock/-/rewiremock-3.14.3.tgz", + "integrity": "sha512-6BaUGfp7NtxBjisxcGN73nNiA2fS2AwhEk/9DMUqxfv5v0aDM1wpOYpj5GSArqsJi07YCfLhkD8C74LAN7+FkQ==", + "dev": true, + "dependencies": { + "babel-runtime": "^6.26.0", + "compare-module-exports": "^2.1.0", + "lodash.some": "^4.6.0", + "lodash.template": "^4.4.0", + "node-libs-browser": "^2.1.0", + "path-parse": "^1.0.5", + "wipe-node-cache": "^2.1.2", + "wipe-webpack-cache": "^2.1.0" + } + }, + "node_modules/ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "dependencies": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/sequelize": { + "version": "6.21.4", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.21.4.tgz", + "integrity": "sha512-5A0+giRhGHerTDRMsZ54TYRB8oQPWxeVscbc4USG9wRtw2Eqik0Vk0p2EVDrhoq7tmNBh2nHpd9YMfvGdwPEJw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/sequelize" + } + ], + "dependencies": { + "@types/debug": "^4.1.7", + "@types/validator": "^13.7.1", + "debug": "^4.3.3", + "dottie": "^2.0.2", + "inflection": "^1.13.2", + "lodash": "^4.17.21", + "moment": "^2.29.1", + "moment-timezone": "^0.5.34", + "pg-connection-string": "^2.5.0", + "retry-as-promised": "^5.0.0", + "semver": "^7.3.5", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.7.0", + "wkx": "^0.5.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependenciesMeta": { + "ibm_db": { + "optional": true + }, + "mariadb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-hstore": { + "optional": true + }, + "snowflake-sdk": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/sequelize/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dev": true, + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sequelize/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", + "dev": true + }, + "node_modules/setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", + "dev": true + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + }, + "bin": { + "sha.js": "bin.js" + } + }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/sinon": { + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.8.1", + "@sinonjs/fake-timers": "^6.0.1", + "@sinonjs/samsam": "^5.3.1", + "diff": "^4.0.2", + "nise": "^4.0.4", + "supports-color": "^7.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" + } + }, + "node_modules/sinon-chai": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "peerDependencies": { + "chai": "^4.0.0", + "sinon": ">=4.0.0" + } + }, + "node_modules/sinon/node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/sinon/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/sinon/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "dependencies": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "node_modules/stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "dependencies": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "dependencies": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/string.prototype.trimend": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz", - "integrity": "sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, - "requires": { - "detect-libc": "^1.0.3", - "https-proxy-agent": "^5.0.0", - "make-dir": "^3.1.0", - "node-fetch": "^2.6.1", - "nopt": "^5.0.0", - "npmlog": "^4.1.2", - "rimraf": "^3.0.2", - "semver": "^7.3.4", - "tar": "^6.1.0" + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, "dependencies": { - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", - "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - }, - "nopt": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-5.0.0.tgz", - "integrity": "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==", - "dev": true, - "requires": { - "abbrev": "1" - } - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "tar": { - "version": "6.1.11", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.11.tgz", - "integrity": "sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^3.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - } - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", + "node_modules/strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" + "dependencies": { + "ansi-regex": "^3.0.0" }, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/superagent": { + "version": "3.8.3", + "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.8.3.tgz", + "integrity": "sha512-GLQtLMCoEIK4eDv6OGtkOoSMt3D+oq0y3dsxMuYuDvaNUvuT8eFBuLmfR0iYYzHC1e8hpzC6ZsxbuP6DIalMFA==", + "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", + "dev": true, "dependencies": { - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - } + "component-emitter": "^1.2.0", + "cookiejar": "^2.1.0", + "debug": "^3.1.0", + "extend": "^3.0.0", + "form-data": "^2.3.1", + "formidable": "^1.2.0", + "methods": "^1.1.1", + "mime": "^1.4.1", + "qs": "^6.5.1", + "readable-stream": "^2.3.5" + }, + "engines": { + "node": ">= 4.0" } }, - "@opencensus/instrumentation-all": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-all/-/instrumentation-all-0.0.22.tgz", - "integrity": "sha512-HqeZPpjubUpQxEAi2L2uBtWcKDbvYDqB3qS1lNsEJg1cjcRBBiVKYhceM6rMcXcBGqzZlce87LyKe4HkDboXhg==", + "node_modules/superagent/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, - "requires": { - "@opencensus/instrumentation-grpc": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "@opencensus/instrumentation-http2": "^0.0.22", - "@opencensus/instrumentation-https": "^0.0.22", - "@opencensus/instrumentation-ioredis": "^0.0.22", - "@opencensus/instrumentation-mongodb": "^0.0.22", - "@opencensus/instrumentation-redis": "^0.0.22" + "dependencies": { + "ms": "^2.1.1" } }, - "@opencensus/instrumentation-grpc": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-grpc/-/instrumentation-grpc-0.0.22.tgz", - "integrity": "sha512-28jq9x+vgwmC8GHi1ZbC7KOQyOXTobnIgiHPpm7mHSaqF6NqBsdbts8HoMSirDDdJOrfTXDiu1Muz1wPLhcuRQ==", + "node_modules/superagent/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "node_modules/supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/propagation-binaryformat": "^0.0.22", - "grpc": "^1.24.2", - "lodash": "^4.17.11", - "object-sizeof": "^1.3.0", - "shimmer": "^1.2.0" + "dependencies": { + "has-flag": "^3.0.0" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/timers-browserify": { + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", + "dev": true, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "setimmediate": "^1.0.4" + }, + "engines": { + "node": ">=0.6.0" } }, - "@opencensus/instrumentation-http": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-http/-/instrumentation-http-0.0.22.tgz", - "integrity": "sha512-I/ysuBPpZecidJmt3kLe6/k5pz8GK6QvhyZj7AxxHi6z21zRQjsWYblHXjBpaAkpqvj3bPXjJ14aIntHB/x5mQ==", + "node_modules/to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", + "dev": true + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" + "engines": { + "node": ">=0.6" + } + }, + "node_modules/toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==", + "dev": true + }, + "node_modules/tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", + "dev": true + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", + "dev": true, + "dependencies": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, + "node_modules/url/node_modules/punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", + "dev": true + }, + "node_modules/util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "dependencies": { + "inherits": "2.0.3" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true + }, + "node_modules/util/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validator": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", + "dev": true + }, + "node_modules/wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2" + } + }, + "node_modules/wipe-node-cache": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.2.tgz", + "integrity": "sha512-m7NXa8qSxBGMtdQilOu53ctMaIBXy93FOP04EC1Uf4bpsE+r+adfLKwIMIvGbABsznaSNxK/ErD4xXDyY5og9w==", + "dev": true + }, + "node_modules/wipe-webpack-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wipe-webpack-cache/-/wipe-webpack-cache-2.1.0.tgz", + "integrity": "sha512-OXzQMGpA7MnQQ8AG+uMl5mWR2ezy6fw1+DMHY+wzYP1qkF1jrek87psLBmhZEj+er4efO/GD4R8jXWFierobaA==", + "dev": true, + "dependencies": { + "wipe-node-cache": "^2.1.0" + } + }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" } }, - "@opencensus/instrumentation-http2": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-http2/-/instrumentation-http2-0.0.22.tgz", - "integrity": "sha512-cauishqr8zCR8B3mCAGWqOvHQ2DJAlqoGWgeRQB/NqEnrKyoeEiIb4pNqAmoa6uKmMhggS+dGD10Kln7iAbG8A==", + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" } }, - "@opencensus/instrumentation-https": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-https/-/instrumentation-https-0.0.22.tgz", - "integrity": "sha512-a4S1hN2Z5bXNu4E3O3cqhqk5EdU4MJBkzaSV1Wbn3KuUEQno1Zl4m6++/tL8cbDMRm1r7jIDu1PiVGuLW597Nw==", + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-http": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } }, - "@opencensus/instrumentation-ioredis": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-ioredis/-/instrumentation-ioredis-0.0.22.tgz", - "integrity": "sha512-0fK6ew3hzHkPLLPE+A2fNSuu/4zx7f3nxVk/6nKFx4VRyLgaX69Pxd7jVlr1XH0T8sgiRjE4vZBaCy5gV/Sb0A==", + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" - }, - "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "engines": { + "node": ">=0.4" } }, - "@opencensus/instrumentation-mongodb": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-mongodb/-/instrumentation-mongodb-0.0.22.tgz", - "integrity": "sha512-GXbKnGYpVN+/uFso4TZ3RjORqyawsmcEY1zqkiX3n16b9i9K4s8jO/9iwvsuMfOe+DJWo+s+eP23enpNYMz9rw==", + "node_modules/y18n": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "shimmer": "^1.2.0" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" } }, - "@opencensus/instrumentation-redis": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/instrumentation-redis/-/instrumentation-redis-0.0.22.tgz", - "integrity": "sha512-yws+jq2SSdShG5Ak1mVb0KQ05Yxehi3oW2CcY6h0DD48Kb92qIWwHxRPihQnkXO9n40IFOUFYVCpr2FjwrwnVw==", + "node_modules/yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "semver": "^7.0.0", - "shimmer": "^1.2.0" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } }, - "@opencensus/nodejs": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/nodejs/-/nodejs-0.0.22.tgz", - "integrity": "sha512-CnOgSSJhmpkEGD2n1M5RAx32VSHM10EjZzzXIa29Lwdu4zwgo5oiEGUSjXQ4chYj/6tToe+hcIJMlqvNPJ35cQ==", + "node_modules/yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "@opencensus/instrumentation-all": "^0.0.22", - "@opencensus/nodejs-base": "^0.0.22" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.0" + }, + "engines": { + "node": ">=6" } }, - "@opencensus/nodejs-base": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/nodejs-base/-/nodejs-base-0.0.22.tgz", - "integrity": "sha512-pSxrV7q0kwAtjbFdOYTb4NaVV1wt7eXzBBAdVhlImDiyzZeSlOXmDAmlHOzIJSSXCcou2gspN7Pf6L9HarJe3w==", + "node_modules/yargs/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22", - "extend": "^3.0.2", - "require-in-the-middle": "^4.0.0" - }, - "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "engines": { + "node": ">=6" } }, - "@opencensus/propagation-binaryformat": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-binaryformat/-/propagation-binaryformat-0.0.22.tgz", - "integrity": "sha512-11aJINuxtaFt5/SmHD+YiaQZjdgc9iIXcby9gL6bqbpceETJDUGeeV0mK2RkW+no5hemokO2SvBvbM/gkJSMeg==", + "node_modules/yargs/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22" - }, "dependencies": { - "@opencensus/core": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/core/-/core-0.0.22.tgz", - "integrity": "sha512-ErazJtivjceNoOZI1bG9giQ6cWS45J4i6iPUtlp7dLNu58OLs/v+CD0FsaPCh47XgPxAI12vbBE8Ec09ViwHNA==", - "dev": true, - "requires": { - "continuation-local-storage": "^3.2.1", - "log-driver": "^1.2.7", - "semver": "^7.0.0", - "shimmer": "^1.2.0", - "uuid": "^8.0.0" - } - }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", - "dev": true - } + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" } }, - "@opencensus/propagation-tracecontext": { - "version": "0.0.22", - "resolved": "https://registry.npmjs.org/@opencensus/propagation-tracecontext/-/propagation-tracecontext-0.0.22.tgz", - "integrity": "sha512-y8U0hCXQwx9WZ5yYh63b37R3+MBmbhQ0xx9AySDDLszcI8IlhcXEuQvmXnirskINiJCBLK9rLryrN4r+wWwUmw==", + "node_modules/yargs/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, - "requires": { - "@opencensus/core": "^0.0.22" + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" } - }, + } + }, + "dependencies": { "@opentelemetry/api": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.0.3.tgz", - "integrity": "sha512-puWxACExDe9nxbBB3lOymQFrLYml2dVOrd7USiVRnSbgXE+KwBu+HxFvxrzfqsiSda9IWsXJG1ef7C1O2/GmKQ==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.1.0.tgz", + "integrity": "sha512-hf+3bwuBwtXsugA2ULBc95qxrOqP2pOekLz34BJhcAKawt94vfeNyUKpYc0lZQ/3sCP6LqRa7UAdHA7i5UODzQ==", "dev": true }, "@opentelemetry/context-async-hooks": { "version": "0.24.0", "resolved": "https://registry.npmjs.org/@opentelemetry/context-async-hooks/-/context-async-hooks-0.24.0.tgz", "integrity": "sha512-Db8AgMByBEFKLJGSUBlNq4Un/Tqzj5W0hTxx3hIic8DvBwqbvUvkMGuiQYLKE2Ay21cLYMT01xK4TEKz0OxADw==", - "dev": true + "dev": true, + "requires": {} }, "@opentelemetry/core": { "version": "0.24.0", @@ -557,17 +3642,6 @@ "requires": { "@opentelemetry/semantic-conventions": "0.24.0", "semver": "^7.1.3" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@opentelemetry/node": { @@ -582,17 +3656,6 @@ "@opentelemetry/propagator-jaeger": "0.24.0", "@opentelemetry/tracing": "0.24.0", "semver": "^7.1.3" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } } }, "@opentelemetry/propagator-b3": { @@ -642,9 +3705,9 @@ } }, "@sinonjs/commons": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.1.tgz", - "integrity": "sha512-892K+kWUUi3cl+LlqEWIDrhvLgdL79tECi8JZUyq6IviKy/DNhuzCRlbHUjxK89f4ypPMMaFnFuR9Ie6DoIMsw==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -659,20 +3722,10 @@ "@sinonjs/commons": "^1.7.0" } }, - "@sinonjs/formatio": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-5.0.1.tgz", - "integrity": "sha512-KaiQ5pBf1MpS09MuA0kp6KBQt2JUOQycqVG1NZXvzeaXe5LGFqAKueIS0bw4w0P9r7KuBSVdUk5QjXsUdu2CxQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1", - "@sinonjs/samsam": "^5.0.2" - } - }, "@sinonjs/samsam": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.1.0.tgz", - "integrity": "sha512-42nyaQOVunX5Pm6GRJobmzbS7iLI+fhERITnETXzzwDZh+TtDr/Au3yAvXVjFmZ4wEUaE4Y3NFZfKv0bV0cbtg==", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-5.3.1.tgz", + "integrity": "sha512-1Hc0b1TtyfBu8ixF/tpfSHTVWKwCBLY4QJbkgnE7HcwyvT2xArDxb4K7dMgqRm3szI+LJbzmW/s4xxEhv6hwDg==", "dev": true, "requires": { "@sinonjs/commons": "^1.6.0", @@ -681,43 +3734,42 @@ } }, "@sinonjs/text-encoding": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", - "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", + "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", "dev": true }, - "@types/bytebuffer": { - "version": "5.0.41", - "resolved": "https://registry.npmjs.org/@types/bytebuffer/-/bytebuffer-5.0.41.tgz", - "integrity": "sha512-Mdrv4YcaHvpkx25ksqqFaezktx3yZRcd51GZY0rY/9avyaqZdiT/GiWRhfrJhMpgzXqTOSHgGvsumGxJFNiZZA==", - "dev": true, - "requires": { - "@types/long": "*", - "@types/node": "*" - } - }, "@types/chai": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", - "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "version": "4.3.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.3.3.tgz", + "integrity": "sha512-hC7OMnszpxhZPduX+m+nrx+uFoLkWOMiR4oa/AZF3MuSETYTZmFfJAHqZEM8MVlvfG7BEUcgvtwoCTxBp6hm3g==", "dev": true }, "@types/cookiejar": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.1.tgz", - "integrity": "sha512-aRnpPa7ysx3aNW60hTiCtLHlQaIFsXFCgQlpakNgDNVFzbtusSY8PwjAQgRWfSk0ekNoBjO51eQRB6upA9uuyw==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@types/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-t73xJJrvdTjXrn4jLS9VSGRbz0nUY3cl2DMGDU48lKl+HR9dbbjW2A9r3g40VA++mQpy6uuHg33gy7du2BKpog==", "dev": true }, - "@types/long": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz", - "integrity": "sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w==", + "@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", "dev": true }, "@types/node": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.0.2.tgz", - "integrity": "sha512-5tabW/i+9mhrfEOUcLDu2xBPsHJ+X5Orqy9FKpale3SjDA17j5AEpYq5vfy3oAeAHGcvANRCO3NV3d2D6q3NiA==", + "version": "18.7.11", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.11.tgz", + "integrity": "sha512-KZhFpSLlmK/sdocfSAjqPETTMd0ug6HIMIAwkwUpU79olnZdQtMxpQP+G1wDzCH7na+FltSIhbaZuKdwZ8RDrw==", "dev": true }, "@types/superagent": { @@ -730,46 +3782,20 @@ "@types/node": "*" } }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "@types/validator": { + "version": "13.7.5", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.7.5.tgz", + "integrity": "sha512-9rQHeAqz6Jw3gDhttkmWetoriW5FPbxylv/6h6mXtaj2NKRcOvOmvfcswVdLVpbuy10NrO486K3lCoLgoIhiIA==", "dev": true }, "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", "dev": true, "requires": { - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } + "mime-types": "~2.1.34", + "negotiator": "0.6.3" } }, "ansi-colors": { @@ -779,9 +3805,9 @@ "dev": true }, "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", + "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==", "dev": true }, "ansi-styles": { @@ -793,28 +3819,6 @@ "color-convert": "^1.9.0" } }, - "any-promise": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", - "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", - "dev": true - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", - "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, "argparse": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", @@ -827,17 +3831,20 @@ "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", "dev": true }, - "ascli": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", - "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", + "array.prototype.reduce": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz", + "integrity": "sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==", "dev": true, "requires": { - "colour": "~0.7.1", - "optjs": "~3.2.2" + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-array-method-boxes-properly": "^1.0.0", + "is-string": "^1.0.7" } }, "asn1.js": { @@ -853,9 +3860,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -873,13 +3880,13 @@ "inherits": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "integrity": "sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA==", "dev": true }, "util": { "version": "0.10.3", "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "integrity": "sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ==", "dev": true, "requires": { "inherits": "2.0.1" @@ -893,26 +3900,16 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", "dev": true }, - "async-listener": { - "version": "0.6.10", - "resolved": "https://registry.npmjs.org/async-listener/-/async-listener-0.6.10.tgz", - "integrity": "sha512-gpuo6xOyF4D5DE5WvyqZdPA3NGhiT6Qf07l7DCB0wwDEsLvDIbCr6j9S5aj5Ch96dLace5tXVzWBZkxU/c5ohw==", - "dev": true, - "requires": { - "semver": "^5.3.0", - "shimmer": "^1.1.0" - } - }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "dev": true }, "babel-runtime": { "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "integrity": "sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==", "dev": true, "requires": { "core-js": "^2.4.0", @@ -920,55 +3917,51 @@ } }, "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", "dev": true }, "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", "dev": true }, "bn.js": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", - "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", + "integrity": "sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ==", "dev": true }, "body-parser": { - "version": "1.19.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", - "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", "dev": true, "requires": { - "bytes": "3.1.0", + "bytes": "3.1.2", "content-type": "~1.0.4", "debug": "2.6.9", - "depd": "~1.1.2", - "http-errors": "1.7.2", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", - "on-finished": "~2.3.0", - "qs": "6.7.0", - "raw-body": "2.4.0", - "type-is": "~1.6.17" + "on-finished": "2.4.1", + "qs": "6.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "dev": true, "requires": { - "ms": "2.0.0" + "side-channel": "^1.0.4" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -985,7 +3978,7 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "integrity": "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w==", "dev": true }, "browser-stdout": { @@ -1032,21 +4025,13 @@ } }, "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.1.0.tgz", + "integrity": "sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog==", "dev": true, "requires": { - "bn.js": "^4.1.0", + "bn.js": "^5.0.0", "randombytes": "^2.0.1" - }, - "dependencies": { - "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", - "dev": true - } } }, "browserify-sign": { @@ -1066,12 +4051,6 @@ "safe-buffer": "^5.2.0" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1082,12 +4061,6 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true } } }, @@ -1101,42 +4074,44 @@ } }, "buffer": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.6.0.tgz", - "integrity": "sha512-/gDYp/UtU0eA1ys8bOs9J6a+E/KWIY+DZ+Q2WESNUA0jFRsJOc0SNUO6xJ5SGA1xueg3NL65W6s+NY5l9cunuw==", + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, "requires": { "base64-js": "^1.0.2", - "ieee754": "^1.1.4" + "ieee754": "^1.1.4", + "isarray": "^1.0.0" } }, "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "integrity": "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ==", "dev": true }, "builtin-status-codes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "integrity": "sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ==", + "dev": true + }, + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true }, - "bytebuffer": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", - "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", "dev": true, "requires": { - "long": "~3" + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" } }, - "bytes": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", - "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", - "dev": true - }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -1144,16 +4119,17 @@ "dev": true }, "chai": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", - "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "version": "4.3.6", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.3.6.tgz", + "integrity": "sha512-bbcp3YfHCUzMOvKqsztczerVgBKSsEijCySNlHHbX3VG1nskvqjz5Rfso1gGwD6w6oOV3eI60pKuMOV5MV7p3Q==", "dev": true, "requires": { "assertion-error": "^1.1.0", "check-error": "^1.0.2", "deep-eql": "^3.0.1", "get-func-name": "^2.0.0", - "pathval": "^1.1.0", + "loupe": "^2.3.1", + "pathval": "^1.1.1", "type-detect": "^4.0.5" } }, @@ -1197,7 +4173,7 @@ "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", - "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "integrity": "sha512-BrgHpW9NURQgzoNyjfq0Wu6VFO6D7IZEmJNdtgNqpzGG8RuNFHt2jQxWlAs4HMe119chBnv+34syEZtc6IhLtA==", "dev": true }, "cipher-base": { @@ -1222,9 +4198,9 @@ }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true }, "string-width": { @@ -1246,26 +4222,9 @@ "requires": { "ansi-regex": "^4.1.0" } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } } } }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "color-convert": { "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", @@ -1278,13 +4237,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "colour": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", - "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "combined-stream": { @@ -1311,7 +4264,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", "dev": true }, "console-browserify": { @@ -1320,25 +4273,19 @@ "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", "dev": true }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, "constants-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "integrity": "sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ==", "dev": true }, "content-disposition": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", - "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", "dev": true, "requires": { - "safe-buffer": "5.1.2" + "safe-buffer": "5.2.1" } }, "content-type": { @@ -1347,44 +4294,34 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", "dev": true }, - "continuation-local-storage": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz", - "integrity": "sha512-jx44cconVqkCEEyLSKWwkvUXwO561jXMa3LPjTPsm5QR22PA0/mhe33FT4Xb5y74JDvt/Cq+5lm8S8rskLv9ZA==", - "dev": true, - "requires": { - "async-listener": "^0.6.0", - "emitter-listener": "^1.1.1" - } - }, "cookie": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", - "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", "dev": true }, "cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "dev": true }, "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.3.tgz", + "integrity": "sha512-JxbCBUdrfr6AQjOXrxoTvAMJO4HBTUIlBzslcJPAz+/KT8yk53fXun51u+RenNYvad/+Vc2DIz5o9UxlCDymFQ==", "dev": true }, "core-js": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", - "integrity": "sha512-5wjnpaT/3dV+XB4borEsnAYQchn00XSgTAWKDkEqv+K8KevjbzmofK6hfJ9TZIlpj2N0xQpazy7PiRQiWHqzWg==", + "version": "2.6.12", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz", + "integrity": "sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==", "dev": true }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, "create-ecdh": { @@ -1398,9 +4335,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -1452,18 +4389,18 @@ } }, "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.0.0" } }, "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", "dev": true }, "deep-eql": { @@ -1476,30 +4413,25 @@ } }, "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", "dev": true, "requires": { - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" } }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "dev": true }, "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true }, "des.js": { @@ -1513,15 +4445,9 @@ } }, "destroy": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", - "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", - "dev": true - }, - "detect-libc": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", - "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", "dev": true }, "diff": { @@ -1542,9 +4468,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -1564,7 +4490,7 @@ "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true }, "elliptic": { @@ -1587,24 +4513,9 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true } } }, - "emitter-listener": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/emitter-listener/-/emitter-listener-1.1.2.tgz", - "integrity": "sha512-Bt1sBAGFHY9DKY+4/2cV6izcKJUf5T7/gkdmkxzX/qv9CcGH8xSwVRW5mtX03SWJtRTWSOpzCuWN9rBFYZepZQ==", - "dev": true, - "requires": { - "shimmer": "^1.2.0" - } - }, "emoji-regex": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", @@ -1614,27 +4525,64 @@ "encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", "dev": true }, "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.1.tgz", + "integrity": "sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA==", "dev": true, "requires": { - "es-to-primitive": "^1.2.0", + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.1", + "get-symbol-description": "^1.0.0", "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.4", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.2", + "regexp.prototype.flags": "^1.4.3", + "string.prototype.trimend": "^1.0.5", + "string.prototype.trimstart": "^1.0.5", + "unbox-primitive": "^1.0.2" + }, + "dependencies": { + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + } } }, + "es-array-method-boxes-properly": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", + "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==", + "dev": true + }, "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", "dev": true, "requires": { "is-callable": "^1.1.4", @@ -1645,13 +4593,13 @@ "escape-html": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true }, "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "esprima": { @@ -1663,13 +4611,13 @@ "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true }, "events": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.2.0.tgz", - "integrity": "sha512-/46HWwbfCX2xTawVfkKLGxMifJYQBWMwY1mjywRtb4c9x8l5NP3KoJtnIOiL1hfdRkIuYhETxQlo62IF8tcnlg==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "dev": true }, "evp_bytestokey": { @@ -1683,57 +4631,52 @@ } }, "express": { - "version": "4.17.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", - "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "version": "4.18.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", + "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", "dev": true, "requires": { - "accepts": "~1.3.7", + "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.19.0", - "content-disposition": "0.5.3", + "body-parser": "1.20.0", + "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.4.0", + "cookie": "0.5.0", "cookie-signature": "1.0.6", "debug": "2.6.9", - "depd": "~1.1.2", + "depd": "2.0.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "~1.1.2", + "finalhandler": "1.2.0", "fresh": "0.5.2", + "http-errors": "2.0.0", "merge-descriptors": "1.0.1", "methods": "~1.1.2", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.5", - "qs": "6.7.0", + "proxy-addr": "~2.0.7", + "qs": "6.10.3", "range-parser": "~1.2.1", - "safe-buffer": "5.1.2", - "send": "0.17.1", - "serve-static": "1.14.1", - "setprototypeof": "1.1.1", - "statuses": "~1.5.0", + "safe-buffer": "5.2.1", + "send": "0.18.0", + "serve-static": "1.15.0", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", "dev": true, "requires": { - "ms": "2.0.0" + "side-channel": "^1.0.4" } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true } } }, @@ -1744,35 +4687,18 @@ "dev": true }, "finalhandler": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", - "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", "dev": true, "requires": { "debug": "2.6.9", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", - "on-finished": "~2.3.0", + "on-finished": "2.4.1", "parseurl": "~1.3.3", - "statuses": "~1.5.0", + "statuses": "2.0.1", "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } } }, "find-up": { @@ -1794,9 +4720,9 @@ } }, "form-data": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", - "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.1.tgz", + "integrity": "sha512-m21N3WOmEEURgk6B9GLOE4RuWOFf28Lhh9qGYeNlGq4VDXUlJy2th2slBNU8Gp8EzloYZOibZJ7t5ecIrFSjVA==", "dev": true, "requires": { "asynckit": "^0.4.0", @@ -1805,27 +4731,27 @@ } }, "formidable": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.1.tgz", - "integrity": "sha512-Fs9VRguL0gqGHkXS5GQiMCr1VhZBxz0JnJs4JmMp/2jL18Fmbzvv7vOFRU+U8TBkHEE/CX1qDXzJplVULgsLeg==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", + "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", "dev": true }, "forwarded": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", - "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true }, "fresh": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", "dev": true }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, "function-bind": { @@ -1834,59 +4760,24 @@ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, - "gauge": { - "version": "2.7.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", - "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", "dev": true, "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" } }, + "functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -1896,9 +4787,30 @@ "get-func-name": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", - "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "integrity": "sha512-Hm0ixYtaSZ/V7C8FJrtZIuBBI+iSgL+1Aq82zSu8VQNB4S3Gk8e7Qs3VwBDJAhmRZcFqkl3tQu36g/Foh5I5ig==", "dev": true }, + "get-intrinsic": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.2.tgz", + "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, "glob": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", @@ -1919,20 +4831,6 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, - "grpc": { - "version": "1.24.11", - "resolved": "https://registry.npmjs.org/grpc/-/grpc-1.24.11.tgz", - "integrity": "sha512-8/AQdFCzCeCDWW3SoaMNp6ccbRvTQEH1O1u1uFtt29eWsg5gSZCJ3m6fbkduEIh3smY7WAPP+LgVJ5n3nZRxcA==", - "dev": true, - "requires": { - "@mapbox/node-pre-gyp": "^1.0.4", - "@types/bytebuffer": "^5.0.40", - "lodash.camelcase": "^4.3.0", - "lodash.clone": "^4.5.0", - "nan": "^2.13.2", - "protobufjs": "^5.0.3" - } - }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1942,24 +4840,42 @@ "function-bind": "^1.1.1" } }, + "has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true + }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true }, - "has-symbols": { + "has-property-descriptors": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", + "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" + } }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", "dev": true }, + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, "hash-base": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", @@ -1971,12 +4887,6 @@ "safe-buffer": "^5.2.0" }, "dependencies": { - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, "readable-stream": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", @@ -1987,12 +4897,6 @@ "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } - }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "dev": true } } }, @@ -2015,7 +4919,7 @@ "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "integrity": "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg==", "dev": true, "requires": { "hash.js": "^1.0.3", @@ -2024,51 +4928,24 @@ } }, "http-errors": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", - "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", "dev": true, "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.1", - "statuses": ">= 1.5.0 < 2", - "toidentifier": "1.0.0" + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" } }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "integrity": "sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg==", "dev": true }, - "https-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", - "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - }, - "dependencies": { - "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", - "dev": true - } - } - }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -2079,21 +4956,21 @@ } }, "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "dev": true }, "inflection": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.12.0.tgz", - "integrity": "sha1-ogCTVlbW9fa8TcdQLhrstwMihBY=", + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.2.tgz", + "integrity": "sha512-cmZlljCRTBFouT8UzMzrGcVEvkv6D/wBdcdKG7J1QH5cXjtU75Dm+P27v9EKu/Y43UYyCJd1WC4zLebRrC8NBw==", "dev": true }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", "dev": true, "requires": { "once": "^1.3.0", @@ -2101,23 +4978,53 @@ } }, "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } + }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", - "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "integrity": "sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==", "dev": true }, "ipaddr.js": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz", - "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==", + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, "is-buffer": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", @@ -2125,60 +5032,106 @@ "dev": true }, "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.4.tgz", + "integrity": "sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w==", "dev": true }, "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", "dev": true }, "is-ip": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz", - "integrity": "sha1-aO6gfooKCpTC0IDdZ0xzGrKkYas=", + "integrity": "sha512-9MTn0dteHETtyUx8pxqMwg5hMBi3pvlyglJ+b79KOCca0po23337LbVV2Hl4xmMvfw++ljnO0/+5G6G+0Szh6g==", "dev": true, "requires": { "ip-regex": "^2.0.0" } }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", "dev": true, "requires": { - "has": "^1.0.1" + "has-tostringtag": "^1.0.0" } }, "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-weakref": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", "dev": true, "requires": { - "has-symbols": "^1.0.0" + "call-bind": "^1.0.2" } }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", "dev": true }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", "dev": true }, "js-yaml": { @@ -2192,9 +5145,9 @@ } }, "just-extend": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.1.0.tgz", - "integrity": "sha512-ApcjaOdVTJ7y4r08xI5wIqpvwS48Q0PBG4DJROcEkH1f8MdAiNFyFxz3xoL0LWAVwjrwPYZdVHHxhRHcx/uGLA==", + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", + "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", "dev": true }, "locate-path": { @@ -2216,25 +5169,13 @@ "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.clone": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", - "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "integrity": "sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==", "dev": true }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true }, "lodash.merge": { @@ -2246,7 +5187,7 @@ "lodash.some": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha1-G7nzFO9ri63tE7VJFpsqlF62jk0=", + "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==", "dev": true }, "lodash.template": { @@ -2268,12 +5209,6 @@ "lodash._reinterpolate": "^3.0.0" } }, - "log-driver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/log-driver/-/log-driver-1.2.7.tgz", - "integrity": "sha512-U7KCmLdqsGHBLeWqYlFA0V0Sl6P08EE1ZrmA9cxjUE0WVqT9qnyVDPz1kzpFEP0jdJuFnasWIfSd7fsaNXkpbg==", - "dev": true - }, "log-symbols": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", @@ -2283,11 +5218,14 @@ "chalk": "^2.0.1" } }, - "long": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", - "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", - "dev": true + "loupe": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-2.3.4.tgz", + "integrity": "sha512-OvKfgCC2Ndby6aSTREl5aCCPTNIzlDfQZvZxNUrBrihDhL3xcrYegTblhmEiCrg2kKQz4XsFIaemE5BF4ybSaQ==", + "dev": true, + "requires": { + "get-func-name": "^2.0.0" + } }, "lru-cache": { "version": "6.0.0", @@ -2296,31 +5234,6 @@ "dev": true, "requires": { "yallist": "^4.0.0" - }, - "dependencies": { - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "dev": true - } - } - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } } }, "md5.js": { @@ -2337,19 +5250,19 @@ "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", "dev": true }, "merge-descriptors": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", "dev": true }, "methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", "dev": true }, "miller-rabin": { @@ -2363,9 +5276,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -2377,18 +5290,18 @@ "dev": true }, "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", "dev": true }, "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", "dev": true, "requires": { - "mime-db": "1.40.0" + "mime-db": "1.52.0" } }, "minimalistic-assert": { @@ -2400,7 +5313,7 @@ "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "integrity": "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg==", "dev": true }, "minimatch": { @@ -2413,11 +5326,20 @@ } }, "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", "dev": true }, + "mkdirp": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", + "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, "mocha": { "version": "6.2.3", "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.3.tgz", @@ -2449,60 +5371,54 @@ "yargs-unparser": "1.6.0" }, "dependencies": { - "mkdirp": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.4.tgz", - "integrity": "sha512-iG9AK/dJLtJ0XNgTuDbSyNS3zECqDlAhnQW4CsNxBG3LQJBbHmRX1egw39DmtOdCAqY+dKXV+sgPgilNWUKMVw==", + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", "dev": true, "requires": { - "minimist": "^1.2.5" + "ms": "^2.1.1" } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true } } }, - "module-details-from-path": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", - "integrity": "sha1-EUyUlnPiqKNenTV4hSeqN7Z52is=", - "dev": true - }, "moment": { - "version": "2.27.0", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", - "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==", + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", "dev": true }, "moment-timezone": { - "version": "0.5.31", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.31.tgz", - "integrity": "sha512-+GgHNg8xRhMXfEbv81iDtrVeTcWt0kWmTEY1XQK14dICTXnWJnT0dxdlPspwqF3keKMVPXwayEsk1DI0AA/jdA==", + "version": "0.5.34", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.34.tgz", + "integrity": "sha512-3zAEHh2hKUs3EXLESx/wsgw6IQdusOT8Bxm3D9UrHPQR7zlMmzwybC8zHEM1tQ4LJwP7fcxrWr8tuBg05fFCbg==", "dev": true, "requires": { "moment": ">= 2.9.0" } }, "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "nan": { - "version": "2.14.1", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", - "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "dev": true }, "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", "dev": true }, "nise": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/nise/-/nise-4.0.4.tgz", - "integrity": "sha512-bTTRUNlemx6deJa+ZyoCUTRvH3liK5+N6VQZ4NIw90AgDXY6iPnsqplNFf6STcj+ePk0H/xqxnP75Lr0J0Fq3A==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-4.1.0.tgz", + "integrity": "sha512-eQMEmGN/8arp0xsvGoQ+B1qvSkR73B1nWSCh7nOt5neMCtwcQVYQGdzQMhcNscktTsWB54xnlSQFzOAPJD8nXA==", "dev": true, "requires": { "@sinonjs/commons": "^1.7.0", @@ -2515,7 +5431,7 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", "dev": true }, "path-to-regexp": { @@ -2537,14 +5453,16 @@ "requires": { "object.getownpropertydescriptors": "^2.0.3", "semver": "^5.7.0" + }, + "dependencies": { + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } } }, - "node-fetch": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.1.tgz", - "integrity": "sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==", - "dev": true - }, "node-libs-browser": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", @@ -2574,43 +5492,18 @@ "url": "^0.11.0", "util": "^0.11.0", "vm-browserify": "^1.0.1" - }, - "dependencies": { - "buffer": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", - "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - } - } - }, - "npmlog": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", - "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", - "dev": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", "dev": true }, "object-keys": { @@ -2619,15 +5512,6 @@ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", "dev": true }, - "object-sizeof": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/object-sizeof/-/object-sizeof-1.6.1.tgz", - "integrity": "sha512-gNKGcRnDRXwEpAdwUY3Ef+aVZIrcQVXozSaVzHz6Pv4JxysH8vf5F+nIgsqW5T/YNwZNveh0mIW7PEH1O2MrDw==", - "dev": true, - "requires": { - "buffer": "^5.6.0" - } - }, "object.assign": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", @@ -2641,19 +5525,21 @@ } }, "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz", + "integrity": "sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==", "dev": true, "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" + "array.prototype.reduce": "^1.0.4", + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.1" } }, "on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "requires": { "ee-first": "1.1.1" @@ -2662,22 +5548,16 @@ "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", "dev": true, "requires": { "wrappy": "1" } }, - "optjs": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", - "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=", - "dev": true - }, "os-browserify": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "integrity": "sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A==", "dev": true }, "p-limit": { @@ -2738,13 +5618,13 @@ "path-exists": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", "dev": true }, "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", "dev": true }, "path-parse": { @@ -2756,19 +5636,19 @@ "path-to-regexp": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", "dev": true }, "pathval": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", - "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.1.tgz", + "integrity": "sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==", "dev": true }, "pbkdf2": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", - "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.2.tgz", + "integrity": "sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA==", "dev": true, "requires": { "create-hash": "^1.1.2", @@ -2778,131 +5658,32 @@ "sha.js": "^2.4.8" } }, + "pg-connection-string": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", + "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==", + "dev": true + }, "process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "dev": true }, "process-nextick-args": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", - "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "dev": true }, - "protobufjs": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.3.tgz", - "integrity": "sha512-55Kcx1MhPZX0zTbVosMQEO5R6/rikNXd9b6RQK4KSPcrSIIwoXTtebIczUrXlwaSrbz4x8XUVThGPob1n8I4QA==", - "dev": true, - "requires": { - "ascli": "~1", - "bytebuffer": "~5", - "glob": "^7.0.5", - "yargs": "^3.10.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, "proxy-addr": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz", - "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==", + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "requires": { - "forwarded": "~0.1.2", - "ipaddr.js": "1.9.0" + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" } }, "public-encrypt": { @@ -2920,9 +5701,9 @@ }, "dependencies": { "bn.js": { - "version": "4.11.9", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", - "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", + "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==", "dev": true } } @@ -2930,25 +5711,28 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", "dev": true }, "qs": { - "version": "6.7.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", - "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", - "dev": true + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } }, "querystring": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "integrity": "sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g==", "dev": true }, "querystring-es3": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "integrity": "sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA==", "dev": true }, "randombytes": { @@ -2977,21 +5761,21 @@ "dev": true }, "raw-body": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", - "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", + "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dev": true, "requires": { - "bytes": "3.1.0", - "http-errors": "1.7.2", + "bytes": "3.1.2", + "http-errors": "2.0.0", "iconv-lite": "0.4.24", "unpipe": "1.0.0" } }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -3001,6 +5785,23 @@ "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + } } }, "regenerator-runtime": { @@ -3009,57 +5810,34 @@ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", "dev": true }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, - "require-in-the-middle": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-4.0.1.tgz", - "integrity": "sha512-EfkM2zANyGkrfIExsECMeNn/uzjvHrE9h36yLXSavmrDiH4tgDNvltAmEKnt4PNLbqKPHZz+uszW2wTKrLUX0w==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "module-details-from-path": "^1.0.3", - "resolve": "^1.12.0" - }, - "dependencies": { - "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, "require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, - "resolve": { - "version": "1.17.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", - "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, - "requires": { - "path-parse": "^1.0.6" - } - }, "retry-as-promised": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-3.2.0.tgz", - "integrity": "sha512-CybGs60B7oYU/qSQ6kuaFmRd9sTZ6oXSc0toqePvV74Ac6/IFZSI1ReFQmtCN+uvW1Mtqdwpvt/LGOiCBAY2Mg==", - "dev": true, - "requires": { - "any-promise": "^1.3.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-5.0.0.tgz", + "integrity": "sha512-6S+5LvtTl2ggBumk04hBo/4Uf6fRJUwIgunGZ7CYEBCeufGFW1Pu6ucUf/UskHeWOIsUcLOGLFXPig5tR5V1nA==", + "dev": true }, "rewiremock": { "version": "3.14.3", @@ -3088,9 +5866,9 @@ } }, "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", "dev": true }, "safer-buffer": { @@ -3100,129 +5878,118 @@ "dev": true }, "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", - "dev": true + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } }, "send": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", - "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", "dev": true, "requires": { "debug": "2.6.9", - "depd": "~1.1.2", - "destroy": "~1.0.4", + "depd": "2.0.0", + "destroy": "1.2.0", "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "etag": "~1.8.1", "fresh": "0.5.2", - "http-errors": "~1.7.2", + "http-errors": "2.0.0", "mime": "1.6.0", - "ms": "2.1.1", - "on-finished": "~2.3.0", + "ms": "2.1.3", + "on-finished": "2.4.1", "range-parser": "~1.2.1", - "statuses": "~1.5.0" + "statuses": "2.0.1" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true } } }, "sequelize": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.3.3.tgz", - "integrity": "sha512-WO/b1ehjSFKlBCHzwZoaPhoW3WyXXy9x74yPrOP8NpE67wzbv0dIucDO4a+THLVyl3lnv3nFMZdJRdkUgb/ZAw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "dottie": "^2.0.0", - "inflection": "1.12.0", - "lodash": "^4.17.15", - "moment": "^2.26.0", - "moment-timezone": "^0.5.31", - "retry-as-promised": "^3.2.0", - "semver": "^7.3.2", - "sequelize-pool": "^6.0.0", + "version": "6.21.4", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.21.4.tgz", + "integrity": "sha512-5A0+giRhGHerTDRMsZ54TYRB8oQPWxeVscbc4USG9wRtw2Eqik0Vk0p2EVDrhoq7tmNBh2nHpd9YMfvGdwPEJw==", + "dev": true, + "requires": { + "@types/debug": "^4.1.7", + "@types/validator": "^13.7.1", + "debug": "^4.3.3", + "dottie": "^2.0.2", + "inflection": "^1.13.2", + "lodash": "^4.17.21", + "moment": "^2.29.1", + "moment-timezone": "^0.5.34", + "pg-connection-string": "^2.5.0", + "retry-as-promised": "^5.0.0", + "semver": "^7.3.5", + "sequelize-pool": "^7.1.0", "toposort-class": "^1.0.1", - "uuid": "^8.1.0", - "validator": "^10.11.0", + "uuid": "^8.3.2", + "validator": "^13.7.0", "wkx": "^0.5.0" }, "dependencies": { "debug": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", - "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { - "ms": "^2.1.1" + "ms": "2.1.2" } }, - "semver": { - "version": "7.3.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", - "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", - "dev": true - }, - "uuid": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.0.tgz", - "integrity": "sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ==", + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", "dev": true } } }, "sequelize-pool": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-6.1.0.tgz", - "integrity": "sha512-4YwEw3ZgK/tY/so+GfnSgXkdwIJJ1I32uZJztIEgZeAO6HMgj64OzySbWLgxj+tXhZCJnzRfkY9gINw8Ft8ZMg==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", "dev": true }, "serve-static": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", - "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", "dev": true, "requires": { "encodeurl": "~1.0.2", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.17.1" + "send": "0.18.0" } }, "set-blocking": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", "dev": true }, "setimmediate": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "dev": true }, "setprototypeof": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", - "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true }, "sha.js": { @@ -3235,28 +6002,26 @@ "safe-buffer": "^5.0.1" } }, - "shimmer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", - "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + } }, "sinon": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.0.3.tgz", - "integrity": "sha512-IKo9MIM111+smz9JGwLmw5U1075n1YXeAq8YeSFlndCLhAL5KGn6bLgu7b/4AYHTV/LcEMcRm2wU2YiL55/6Pg==", + "version": "9.2.4", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-9.2.4.tgz", + "integrity": "sha512-zljcULZQsJxVra28qIAL6ow1Z9tpattkCTEJR4RBP3TGc00FcttsP5pK284Nas5WjMZU5Yzy3kAIp3B3KRf5Yg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.7.2", + "@sinonjs/commons": "^1.8.1", "@sinonjs/fake-timers": "^6.0.1", - "@sinonjs/formatio": "^5.0.1", - "@sinonjs/samsam": "^5.1.0", + "@sinonjs/samsam": "^5.3.1", "diff": "^4.0.2", "nise": "^4.0.4", "supports-color": "^7.1.0" @@ -3275,9 +6040,9 @@ "dev": true }, "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "requires": { "has-flag": "^4.0.0" @@ -3286,21 +6051,22 @@ } }, "sinon-chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.5.0.tgz", - "integrity": "sha512-IifbusYiQBpUxxFJkR3wTU68xzBN0+bxCScEaKMjBvAQERg6FnTTc1F17rseLb1tjmkJ23730AXpFI0c47FgAg==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", + "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", + "dev": true, + "requires": {} }, "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", "dev": true }, "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", "dev": true }, "stream-browserify": { @@ -3326,6 +6092,15 @@ "xtend": "^4.0.0" } }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + }, "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", @@ -3336,19 +6111,32 @@ "strip-ansi": "^4.0.0" } }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "string.prototype.trimend": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz", + "integrity": "sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==", "dev": true, "requires": { - "safe-buffer": "~5.1.0" + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz", + "integrity": "sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.19.5" } }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==", "dev": true, "requires": { "ansi-regex": "^3.0.0" @@ -3357,7 +6145,7 @@ "strip-json-comments": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", "dev": true }, "superagent": { @@ -3376,6 +6164,23 @@ "mime": "^1.4.1", "qs": "^6.5.1", "readable-stream": "^2.3.5" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + } } }, "supports-color": { @@ -3388,9 +6193,9 @@ } }, "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "version": "2.0.12", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.12.tgz", + "integrity": "sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ==", "dev": true, "requires": { "setimmediate": "^1.0.4" @@ -3399,25 +6204,25 @@ "to-arraybuffer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "integrity": "sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA==", "dev": true }, "toidentifier": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", - "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true }, "toposort-class": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", - "integrity": "sha1-f/0feMi+KMO6Rc1OGj9e4ZO9mYg=", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==", "dev": true }, "tty-browserify": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "integrity": "sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==", "dev": true }, "type-detect": { @@ -3436,16 +6241,28 @@ "mime-types": "~2.1.24" } }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true }, "url": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "integrity": "sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ==", "dev": true, "requires": { "punycode": "1.3.2", @@ -3455,7 +6272,7 @@ "punycode": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "integrity": "sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw==", "dev": true } } @@ -3467,36 +6284,44 @@ "dev": true, "requires": { "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true + } } }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", "dev": true }, "utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", "dev": true }, "uuid": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.1.tgz", - "integrity": "sha512-FOmRr+FmWEIG8uhZv6C2bTgEVXsHk08kE7mPlrBbEe+c3r9pjceVPgupIfNIhc4yx55H69OXANrUaSuu9eInKg==", + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", "dev": true }, "validator": { - "version": "10.11.0", - "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", - "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==", + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.7.0.tgz", + "integrity": "sha512-nYXQLCBkpJ8X6ltALua9dRrZDHVYxjJ1wgskNt1lH9fzGjs3tgojGSCBjmEPwkWS1y29+DrizMTW19Pr9uB2nw==", "dev": true }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true }, "vm-browserify": { @@ -3514,10 +6339,23 @@ "isexe": "^2.0.0" } }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, "which-module": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", "dev": true }, "wide-align": { @@ -3529,12 +6367,6 @@ "string-width": "^1.0.2 || 2" } }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, "wipe-node-cache": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/wipe-node-cache/-/wipe-node-cache-2.1.2.tgz", @@ -3560,48 +6392,40 @@ } }, "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", "dev": true, "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" }, "dependencies": { "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", "dev": true, "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" } }, "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", "dev": true, "requires": { - "ansi-regex": "^2.0.0" + "ansi-regex": "^4.1.0" } } } @@ -3609,7 +6433,7 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true }, "xtend": { @@ -3619,9 +6443,15 @@ "dev": true }, "y18n": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.2.tgz", - "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", + "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", "dev": true }, "yargs": { @@ -3643,9 +6473,9 @@ }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", "dev": true }, "string-width": { @@ -3667,12 +6497,6 @@ "requires": { "ansi-regex": "^4.1.0" } - }, - "y18n": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", - "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==", - "dev": true } } }, diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package.json b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package.json index 33104efc..a38c7f8a 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package.json +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/package.json @@ -7,8 +7,6 @@ "test": "test" }, "devDependencies": { - "@opencensus/nodejs": "^0.0.22", - "@opencensus/propagation-tracecontext": "^0.0.22", "@opentelemetry/api": "^1.0.3", "@opentelemetry/core": "^0.24.0", "@opentelemetry/node": "^0.24.0", @@ -22,8 +20,6 @@ "sinon-chai": "^3.5.0" }, "peerDependencies": { - "@opencensus/nodejs": "^0.0.22", - "@opencensus/propagation-tracecontext": "^0.0.22", "@opentelemetry/core": "^0.24.0" }, "engines": { @@ -38,4 +34,4 @@ }, "author": "Google, LLC.", "license": "Apache-2.0" -} +} \ No newline at end of file diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/index.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/index.js index e0196eef..027802e0 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/index.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/index.js @@ -12,12 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -const OpenCensus = require('./opencensus'); const OpenTelemetry = require('./opentelemetry'); const providers = { 'opentelemetry': OpenTelemetry, - 'opencensus': OpenCensus, } exports.attachComments = function attachComments(providerName, comments) { @@ -25,6 +23,6 @@ exports.attachComments = function attachComments(providerName, comments) { if (!comments || typeof comments !== 'object') return; // Lookup the provider by name, or use the default. - let provider = providers[String(providerName).toLowerCase()] || OpenCensus; + let provider = providers[String(providerName).toLowerCase()] || OpenTelemetry; provider.addW3CTraceContext(comments); } diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/opencensus.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/opencensus.js deleted file mode 100644 index c36cb6de..00000000 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/provider/opencensus.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -const {tracer} = require('@opencensus/nodejs'); -const {toW3CTraceContext} = require('../util'); - -exports.addW3CTraceContext = function(comments) { - if (tracer.active) { - toW3CTraceContext(tracer.currentRootSpan, comments); - } -}; diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/comment.test.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/comment.test.js index 9ea788b1..ff11d5e1 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/comment.test.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/comment.test.js @@ -19,16 +19,14 @@ let sequelize_version = require('sequelize').version; if (!sequelize_version) sequelize_version = require('sequelize/package').version; -const {wrapSequelize} = require('../index'); -const {fields} = require('../util'); +const { wrapSequelize } = require('../index'); const chai = require("chai"); const expect = chai.expect; const seq_version = require('sequelize').version; -const opencensus_tracing = require('@opencensus/nodejs'); -const {context, trace} = require('@opentelemetry/api'); -const {NodeTracerProvider} = require('@opentelemetry/node'); -const {AsyncHooksContextManager} = require('@opentelemetry/context-async-hooks'); -const {InMemorySpanExporter, SimpleSpanProcessor} = require('@opentelemetry/tracing'); +const { context, trace } = require('@opentelemetry/api'); +const { NodeTracerProvider } = require('@opentelemetry/node'); +const { AsyncHooksContextManager } = require('@opentelemetry/context-async-hooks'); +const { InMemorySpanExporter, SimpleSpanProcessor } = require('@opentelemetry/tracing'); const createFakeSequelize = () => { return { @@ -42,11 +40,11 @@ const createFakeSequelize = () => { config: { database: 'fake', client: 'fakesql', }, - options: { - databaseVersion: 'fakesql-server:0.0.X', - dialect: 'fakesql', - timezone: '+00:00', - }, + options: { + databaseVersion: 'fakesql-server:0.0.X', + dialect: 'fakesql', + timezone: '+00:00', + }, }, }, }, @@ -59,17 +57,16 @@ describe("Comments for Sequelize", () => { const fakeSequelize = createFakeSequelize(); before(() => { - wrapSequelize(fakeSequelize, {client_timezone:true, db_driver:true}); + wrapSequelize(fakeSequelize, { client_timezone: true, db_driver: true }); }); after(() => { - opencensus_tracing.stop(); }); describe("Cases", () => { it("should add comment to generated sql", (done) => { - + const want = `SELECT * FROM foo /*client_timezone='%2B00%3A00',db_driver='sequelize%3A${seq_version}'*/`; const query = 'SELECT * FROM foo'; @@ -81,7 +78,7 @@ describe("Comments for Sequelize", () => { }); it("should NOT affix comments to statements with existing comments", (done) => { - + const q = [ 'SELECT * FROM people /* existing */', 'SELECT * FROM people -- existing' @@ -120,9 +117,9 @@ describe("Comments for Sequelize", () => { }); it("chaining and repeated calls should NOT indefinitely chain SQL", (done) => { - + const want = `SELECT * FROM foo /*client_timezone='%2B00%3A00',db_driver='sequelize%3A${seq_version}'*/`; - + const sql = 'SELECT * FROM foo'; fakeSequelize.dialect.Query.prototype.run(sql) @@ -142,20 +139,19 @@ describe("Excluding all variables", () => { const fakeSequelize = createFakeSequelize(); before(() => { - wrapSequelize(fakeSequelize, {non_existent: true}); + wrapSequelize(fakeSequelize, { non_existent: true }); }); after(() => { - opencensus_tracing.stop(); }); it("when all variables are excluded, no comment should be generated", (done) => { // Allow a re-wrap. fakeSequelize.___alreadySQLCommenterWrapped___ = false; - wrapSequelize(fakeSequelize, {foo:true}); + wrapSequelize(fakeSequelize, { foo: true }); const want = `SELECT * FROM foo`; - const sql = `SELECT * FROM foo`; + const sql = `SELECT * FROM foo`; fakeSequelize.dialect.Query.prototype.run(sql).then((got) => { expect(got).equals(want); @@ -164,41 +160,6 @@ describe("Excluding all variables", () => { }); }); -describe("With OpenCensus tracing", () => { - - const fakeSequelize = createFakeSequelize(); - - before(() => { - wrapSequelize(fakeSequelize, {traceparent: true, tracestate: true}, {TraceProvider: "OpenCensus"}); - }); - - after(() => { - opencensus_tracing.stop(); - }); - - it('Starting an OpenCensus trace should produce `traceparent`', (done) => { - // TODO: Follow-up with https://github.com/census-instrumentation/opencensus-node/issues/580 - // and get a proper guide or file bugs against the project to get the proper - // way to retrieve spans. For now let's skip this test. - // Remember: https://github.com/census-instrumentation/opencensus-node/issues/580 - - const traceOptions = { - samplingRate: 1, // Always sample - }; - const tracer = opencensus_tracing.start(traceOptions).tracer; - - tracer.startRootSpan({ name: 'with-tracing' }, rootSpan => { - const sql = 'SELECT * FROM foo'; - fakeSequelize.dialect.Query.prototype.run(sql).then((augmentedSQL) => { - const wantSQL = `SELECT * FROM foo /*traceparent='00-${rootSpan.traceId}-${rootSpan.id}-01'*/`; - expect(augmentedSQL).equals(wantSQL); - opencensus_tracing.tracer.stop(); - done(); - }); - }); - }); -}); - describe("With OpenTelemetry tracing", () => { const fakeSequelize = createFakeSequelize(); @@ -215,7 +176,7 @@ describe("With OpenTelemetry tracing", () => { before(() => { contextManager = new AsyncHooksContextManager(); context.setGlobalContextManager(contextManager.enable()); - wrapSequelize(fakeSequelize, {traceparent: true, tracestate: true}, {TraceProvider: "OpenTelemetry"}); + wrapSequelize(fakeSequelize, { traceparent: true, tracestate: true }, { TraceProvider: "OpenTelemetry" }); }); after(() => { @@ -226,7 +187,7 @@ describe("With OpenTelemetry tracing", () => { it('Starting an OpenTelemetry trace should produce `traceparent`', (done) => { const rootSpan = tracer.startSpan('rootSpan'); - context.with(trace.setSpan(context.active(), rootSpan), async () => { + context.with(trace.setSpan(context.active(), rootSpan), async () => { const sql = 'SELECT * FROM foo'; let augmentedSQL = await fakeSequelize.dialect.Query.prototype.run(sql); const wantSQL = `SELECT * FROM foo /*traceparent='00-${rootSpan.spanContext().traceId}-${rootSpan.spanContext().spanId}-01'*/`; diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/provider.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/provider.js index a8717544..4ae5acdd 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/provider.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/provider.js @@ -22,19 +22,17 @@ const rewiremock = require('../rewiremock'); chai.use(sinonChai); // Mock the trace provider implementations -const openCensusMock = sinon.spy(); const openTelemetryMock = sinon.spy(); // Mock the dependencies of provider to make use of faked methods for adding trace context -rewiremock('../../provider/opencensus').with({addW3CTraceContext: openCensusMock}); -rewiremock('../../provider/opentelemetry').with({addW3CTraceContext: openTelemetryMock}); +rewiremock('../../provider/opentelemetry').with({ addW3CTraceContext: openTelemetryMock }); // Load the provider module with the appropriate mocks rewiremock.enable(); const provider = require('../../provider'); // A helper method to test which provider was called -const verifyProviderUsed = function(traceProvider, spy, used) { +const verifyProviderUsed = function (traceProvider, spy, used) { provider.attachComments(traceProvider, {}); expect(spy.called).to.equal(used); }; @@ -43,42 +41,26 @@ describe("Provider", () => { describe("attachComment", () => { beforeEach(() => { - openCensusMock.resetHistory(); openTelemetryMock.resetHistory(); }) - it("should default to OpenCensus when no options are provided", () => { - verifyProviderUsed(undefined, openCensusMock, true); - verifyProviderUsed(undefined, openTelemetryMock, false); + it("should default to OpenTelemetry when no options are provided", () => { + verifyProviderUsed(undefined, openTelemetryMock, true); }); - it("should default to OpenCensus when null is provided", () => { - verifyProviderUsed(null, openCensusMock, true); - verifyProviderUsed(null, openTelemetryMock, false); + it("should default to OpenTelemetry when null is provided", () => { + verifyProviderUsed(null, openTelemetryMock, true); }); - it("should default to OpenCensus when invalid options are provided", () => { - verifyProviderUsed("bad trace library name", openCensusMock, true); - verifyProviderUsed("bad trace library name", openTelemetryMock, false); - }); - - it("should use OpenCensus when the name is provided", () => { - verifyProviderUsed("opencensus", openCensusMock, true); - verifyProviderUsed("opencensus", openTelemetryMock, false); - }); - - it("should accept an arbitrary capitalization of OpenCensus", () => { - verifyProviderUsed("oPeNceNSus", openCensusMock, true); - verifyProviderUsed("oPeNceNSus", openTelemetryMock, false); + it("should default to OpenTelemetry when invalid options are provided", () => { + verifyProviderUsed("bad trace library name", openTelemetryMock, true); }); it("should use OpenTelemetry when the name is provided", () => { - verifyProviderUsed("opentelemetry", openCensusMock, false); verifyProviderUsed("opentelemetry", openTelemetryMock, true); }); it("should accept an arbitrary capitalization of OpenTelemetry", () => { - verifyProviderUsed("OpenTeleMetRY", openCensusMock, false); verifyProviderUsed("OpenTeleMetRY", openTelemetryMock, true); }); diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/util.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/util.js index 3f11fed5..ea529d7e 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/util.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/test/unit/util.js @@ -14,7 +14,7 @@ "use strict"; -const {hasComment, toW3CTraceContext} = require('../../util'); +const { hasComment, toW3CTraceContext } = require('../../util'); const chai = require("chai"); const expect = chai.expect; @@ -23,7 +23,7 @@ describe("Unit", () => { describe("hasComment", () => { it("should return true for well-formed comments", () => { - + const queries = [ `SELECT * FROM foo /* existing */`, `SELECT * FROM foo -- existing` @@ -34,86 +34,21 @@ describe("Unit", () => { expect(hasComment(q)).to.equal(want) }); }); - + it("should return false when comment is undefined", () => { let comment; expect(hasComment(comment)).to.equal(false); }); - + it("should return false for malformed comments", () => { const queries = [ "SELECT * FROM people /*", "SELECT * FROM people */ /*" ]; - + queries.forEach(q => { expect(hasComment(q)).to.equal(false); }); }); }); - - describe("toW3CTraceContext", () => { - - it("should return undefined/null for undefined/null span", () => { - const badParams = [ - null, - undefined - ]; - const obj = {}; - expect(toW3CTraceContext(badParams[0], null)).to.be.null; - expect(toW3CTraceContext(badParams[1], null)).to.be.null; - expect(toW3CTraceContext(badParams[0], obj)).to.equal(obj); - expect(toW3CTraceContext(badParams[1], obj)).to.equal(obj); - }); - - it("should still extract the topSpanContext even if not root span", () => { - const fakeSpan = { - spanContext: { - traceId: 'ff00000000000001', - spanId: 'ee000002', - traceState: 'congo=t61rcWkgMzE,rojo=00f067aa0ba902b7', - }, - isRootSpan() { return false; } - }; - expect(toW3CTraceContext(fakeSpan, {}).traceparent).to.equal('00-ff00000000000001-ee000002-00'); - expect(toW3CTraceContext(fakeSpan, {}).tracestate).to.equal('congo=t61rcWkgMzE,rojo=00f067aa0ba902b7'); - }); - - it("should nothing if the latest span doesn't have children", () => { - const fakeSpan = { - spanContext: {}, - spans: [], - isRootSpan() { return true; } - }; - - const got = toW3CTraceContext(fakeSpan, {}); - expect(got.traceparent).to.equal(undefined); - expect(got.tracestate).to.equal(undefined); - }); - - it("should return the last span it has children", () => { - const fakeSpan = { - spans: [{ - spanContext: { - traceId: 'ff00000000000001', - spanId: 'ee000002', - traceState: 'congo=t61rcWkgMzE,rojo=00f067aa0ba902b7', - }, - }, - { - spanContext: { - traceId: '11000000000000ff', - spanId: '020000ee', - traceState: 'brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7', - options: 0x01, // It is sampled. - }, - }], - isRootSpan() { return true; } - }; - - const got = toW3CTraceContext(fakeSpan, {}); - expect(got.traceparent).to.equal('00-11000000000000ff-020000ee-01'); - expect(got.tracestate).to.equal('brazzaville=t61rcWkgMzE,rondo=00f067aa0ba902b7'); - }); - }); }); diff --git a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/util.js b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/util.js index 2ffd8648..6643d566 100644 --- a/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/util.js +++ b/nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize/util.js @@ -12,12 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -const {TraceContextFormat} = require('@opencensus/propagation-tracecontext'); -const traceContext = new TraceContextFormat(); - /** * fields represent variables that can be made optional for commenter output - */ + */ exports.fields = { CLIENT_TIMEZONE: "client_timezone", DB_DRIVER: "db_driver", @@ -49,7 +46,7 @@ exports.hasComment = (sql) => { // Check if it is a well formed comment. const indexClosingSlashComment = sql.indexOf('*/'); - + /* c8 ignore next */ return indexOpeningSlashComment < indexClosingSlashComment; } @@ -67,30 +64,3 @@ const latestSpan = (span) => { /* c8 ignore next */ return children[children.length - 1]; } - -/** - * Adds the required fields from span to dst for tracepropagation, ensuring - * comformance with any system that uses W3C Distributed Tracing context to propagate traces. - * In addition to adding a traceparent field, a tracestate is also added to dst - * - * @param {Object} span The span object if tracing is active - * @param {Object} dst The destination object to add trace propagation fields - * @return {void} - */ -exports.toW3CTraceContext = (span, dst) => { - const curSpan = latestSpan(span); - if (!curSpan) - return dst; - - const spanContext = curSpan.spanContext || {}; - if (!(spanContext.traceId && spanContext.spanId)) - return dst; - - const setHeader = { - setHeader: (key, value) => { - dst[key] = value; - } - }; - traceContext.inject(setHeader, curSpan.spanContext); - return dst; -} From 3d35d46e48294efbfe48fe26731669bf89e86e8d Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Tue, 30 Aug 2022 12:15:47 +0530 Subject: [PATCH 042/108] Nodejs CI Pipeline (#151) * Implemented github workflows for unittesting nodejs-knex & nodejs-sequelize --- .github/workflows/nodejs-knex-tests.yaml | 32 +++++++++++++++++++ .github/workflows/nodejs-sequelize-tests.yaml | 32 +++++++++++++++++++ .github/workflows/unit-tests.yaml | 2 ++ 3 files changed, 66 insertions(+) create mode 100644 .github/workflows/nodejs-knex-tests.yaml create mode 100644 .github/workflows/nodejs-sequelize-tests.yaml diff --git a/.github/workflows/nodejs-knex-tests.yaml b/.github/workflows/nodejs-knex-tests.yaml new file mode 100644 index 00000000..e45d13b5 --- /dev/null +++ b/.github/workflows/nodejs-knex-tests.yaml @@ -0,0 +1,32 @@ +name: Nodejs Knex Packages Test + +on: + push: + branches: + - master + paths: + - nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex + pull_request: + paths: + - nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex +jobs: + unittests: + runs-on: ubuntu-latest + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + node-version: [ current, lts/* ] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex + - run: npm run build --if-present + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex + - run: npm test + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-knex + \ No newline at end of file diff --git a/.github/workflows/nodejs-sequelize-tests.yaml b/.github/workflows/nodejs-sequelize-tests.yaml new file mode 100644 index 00000000..9080edff --- /dev/null +++ b/.github/workflows/nodejs-sequelize-tests.yaml @@ -0,0 +1,32 @@ +name: Nodejs Sequelize Packages Test + +on: + push: + branches: + - master + paths: + - nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize + pull_request: + paths: + - nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize +jobs: + unittests: + runs-on: ubuntu-latest + strategy: + fail-fast: false # ensures the entire test matrix is run, even if one permutation fails + matrix: + node-version: [ current, lts/* ] + + steps: + - uses: actions/checkout@v3 + - name: Use Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v3 + with: + node-version: ${{ matrix.node-version }} + - run: npm ci + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize + - run: npm run build --if-present + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize + - run: npm test + working-directory: ./nodejs/sqlcommenter-nodejs/packages/sqlcommenter-sequelize + \ No newline at end of file diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 9d71c97f..684ee05d 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -8,11 +8,13 @@ on: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - python/sqlcommenter-python/** + - nodejs/** pull_request: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - python/sqlcommenter-python/** + - nodejs/** jobs: unittests: From 69039b83d20af913c13f1237e651030ae049c420 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Thu, 1 Sep 2022 16:08:53 +0530 Subject: [PATCH 043/108] Laravel Readme Update (#154) Added options column in php-laravel's Readme --- .../packages/sqlcommenter-laravel/README.md | 37 ++++++++----------- 1 file changed, 16 insertions(+), 21 deletions(-) diff --git a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md index d3a07d7f..d0e8255c 100644 --- a/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md +++ b/php/sqlcommenter-php/packages/sqlcommenter-laravel/README.md @@ -1,31 +1,19 @@ -# sqlcommenter-laravel [In Development] +# Sqlcommenter-laravel -sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel +Sqlcommenter is a plugin/middleware/wrapper to augment SQL statements from laravel with comments that can be used later to correlate user code with SQL statements. +## Installation -### Installation - -Add this to your `composer.json` -```shell -"repositories": [ - { - "type": "path", - "url": "/full/or/relative/path/to/sqlcommenter-laravel/package" - } -] -``` -Install the package ```shell composer require "google/sqlcommenter-laravel" ``` -### Usage +## Usage Publish the config file from library to into laravel app using below command ```shell php artisan vendor:publish --provider="Google\GoogleSqlCommenterLaravel\GoogleSqlCommenterServiceProvider" - ``` Add the following class above `Illuminate\Database\DatabaseServiceProvider::class`, @@ -38,9 +26,16 @@ Add the following class above `Illuminate\Database\DatabaseServiceProvider::clas ... ] ``` -### Run unit tests -Run unit tests using below command -```shell -./vendor/bin/phpunit tests -``` +## Options + +With Laravel SqlCommenter, we have configuration to choose which tags to be appended to the comment. It is configurable in `config/google_sqlcommenter.php` + +| Field | Included
by default? | Description | +| ------------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| `action` |
| The [application namespace](https://laravel.com/docs/9.x/controllers) of the matching URL pattern in your routes/api.php | +| `controller` |
| The [name](https://laravel.com/docs/9.x/controllers) of the matching URL pattern as described in your routes/api.php | +| `db_driver` |
| The name of the php [database engine](https://laravel.com/docs/9.x/database) | +| `framework` |
| The word "laravel" and the version of laravel being used | +| `route` |
| The [route](https://laravel.com/docs/9.x/routing) of the matching URL pattern as described in your routes/api.php | +| `traceparent` |
| The [W3C TraceContext.Traceparent field](https://www.w3.org/TR/trace-context/#traceparent-field) of the OpenTelemetry trace | From 89887ed5f3eddb5a8cf932aa09f0002c0a7a173e Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 09:41:08 +0530 Subject: [PATCH 044/108] Added support for go-sql-driver (#161) --- .github/workflows/go-sql-tests.yaml | 45 +++++++ .github/workflows/unit-tests.yaml | 2 + go/go-sql/README.md | 72 +++++++++++ go/go-sql/go-sql.go | 190 ++++++++++++++++++++++++++++ go/go-sql/go-sql_test.go | 87 +++++++++++++ go/go-sql/go.mod | 20 +++ go/go-sql/go.sum | 24 ++++ 7 files changed, 440 insertions(+) create mode 100644 .github/workflows/go-sql-tests.yaml create mode 100644 go/go-sql/README.md create mode 100644 go/go-sql/go-sql.go create mode 100644 go/go-sql/go-sql_test.go create mode 100644 go/go-sql/go.mod create mode 100644 go/go-sql/go.sum diff --git a/.github/workflows/go-sql-tests.yaml b/.github/workflows/go-sql-tests.yaml new file mode 100644 index 00000000..f7d92a45 --- /dev/null +++ b/.github/workflows/go-sql-tests.yaml @@ -0,0 +1,45 @@ +name: go-sql package test + +on: + push: + branches: + - master + paths: + - go/go-sql/** + pull_request: + paths: + - go/go-sql/** + +jobs: + unittests: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.19 + + - name: Build + run: go build -v ./... + working-directory: ./go/go-sql + + - name: Test + run: go test -v ./... + working-directory: ./go/go-sql + + gofmt: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + + - name: Set up Go + uses: actions/setup-go@v3 + with: + go-version: 1.19 + + # Verify go fmt standards are used + - name: Format + run: if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then exit 1; fi + diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 684ee05d..bc56b27b 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -9,12 +9,14 @@ on: - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - python/sqlcommenter-python/** - nodejs/** + - go/** pull_request: paths-ignore: - php/sqlcommenter-php/packages/sqlcommenter-laravel/** - php/sqlcommenter-php/samples/sqlcommenter-laravel/** - python/sqlcommenter-python/** - nodejs/** + - go/** jobs: unittests: diff --git a/go/go-sql/README.md b/go/go-sql/README.md new file mode 100644 index 00000000..d19afe0c --- /dev/null +++ b/go/go-sql/README.md @@ -0,0 +1,72 @@ +# Sqlcommenter [In development] + +SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. + +## Installation + +### Install from source + +* Clone the source +* In terminal go inside the client folder location where we need to import google-sqlcommenter package and enter the below commands + +```shell +go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/go + +go mod tiny +``` +### Install from github [To be added] + +## Usages + +### go-sql-driver +Please use the sqlcommenter's default database driver to execute statements. \ +Due to inherent nature of Go, the safer way to pass information from framework to database driver is via `context`. So, it is recommended to use the context based methods of `DB` interface like `QueryContext`, `ExecContext` and `PrepareContext`. + +```go +db, err := sqlcommenter.Open("", "", sqlcommenter.CommenterOptions{:}) +``` + +#### Configuration + +Users are given control over what tags they want to append by using `sqlcommenter.CommenterOptions` struct. + +```go +type CommenterOptions struct { + EnableDBDriver bool + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + } +``` + +### net/http +Populate the request context with sqlcommenter.AddHttpRouterTags(r) function in a custom middleware. + +#### Note +* We only support the `database/sql` driver and have provided an implementation for that. +* ORM related tags are added to the driver only when the tags are enabled in the commenter's driver's config and also the request context should passed to the querying functions + +#### Example +```go +// middleware is used to intercept incoming HTTP calls and populate request context with commenter tags. +func middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := sqlcommenter.AddHttpRouterTags(r, next) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} +``` + +## Options + +With Go SqlCommenter, we have configuration to choose which tags to be appended to the comment. + +| Options | Included by default? | go-sql-orm | net/http | Notes | +| --------------- | :------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---: | +| `DBDriver` | | [ go-sql-driver](https://pkg.go.dev/database/sql/driver) | | +| `Action` | | | [net/http handle](https://pkg.go.dev/net/http#Handle) | | +| `Route` | | | [net/http routing path](https://pkg.go.dev/github.com/gorilla/mux#Route.URLPath) | | +| `Framework` | | | [net/http](https://pkg.go.dev/net/http) | | +| `Opentelemetry` | | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | | diff --git a/go/go-sql/go-sql.go b/go/go-sql/go-sql.go new file mode 100644 index 00000000..05ddf6ca --- /dev/null +++ b/go/go-sql/go-sql.go @@ -0,0 +1,190 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package gosql + +import ( + "context" + "database/sql" + "fmt" + "net/http" + "net/url" + "reflect" + "runtime" + "sort" + "strings" + + "go.opentelemetry.io/otel/propagation" +) + +const ( + route string = "route" + controller string = "controller" + action string = "action" + framework string = "framework" + driver string = "driver" + traceparent string = "traceparent" +) + +type DB struct { + *sql.DB + options CommenterOptions +} + +type CommenterOptions struct { + EnableDBDriver bool + EnableRoute bool + EnableFramework bool + EnableController bool + EnableAction bool + EnableTraceparent bool +} + +func Open(driverName string, dataSourceName string, options CommenterOptions) (*DB, error) { + db, err := sql.Open(driverName, dataSourceName) + return &DB{DB: db, options: options}, err +} + +// ***** Query Functions ***** + +func (db *DB) Query(query string, args ...any) (*sql.Rows, error) { + return db.DB.Query(db.withComment(context.Background(), query), args...) +} + +func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row { + return db.DB.QueryRow(db.withComment(context.Background(), query), args...) +} + +func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { + return db.DB.QueryContext(ctx, db.withComment(ctx, query), args...) +} + +func (db *DB) Exec(query string, args ...any) (sql.Result, error) { + return db.DB.Exec(db.withComment(context.Background(), query), args...) +} + +func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { + return db.DB.ExecContext(ctx, db.withComment(ctx, query), args...) +} + +func (db *DB) Prepare(query string) (*sql.Stmt, error) { + return db.DB.Prepare(db.withComment(context.Background(), query)) +} + +func (db *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) { + return db.DB.PrepareContext(ctx, db.withComment(ctx, query)) +} + +// ***** Query Functions ***** + +// ***** Framework Functions ***** + +func AddHttpRouterTags(r *http.Request, next any) context.Context { // any type is set because we need to refrain from importing http-router package + ctx := context.Background() + ctx = context.WithValue(ctx, route, r.URL.Path) + ctx = context.WithValue(ctx, action, getFunctionName(next)) + ctx = context.WithValue(ctx, framework, "net/http") + return ctx +} + +// ***** Framework Functions ***** + +// ***** Commenter Functions ***** + +func (db *DB) withComment(ctx context.Context, query string) string { + var commentsMap = map[string]string{} + query = strings.TrimSpace(query) + + // Sorted alphabetically + if db.options.EnableAction && (ctx.Value(action) != nil) { + commentsMap[action] = ctx.Value(action).(string) + } + + // `driver` information should not be coming from framework. + // So, explicitly adding that here. + if db.options.EnableDBDriver { + commentsMap[driver] = "database/sql" + } + + if db.options.EnableFramework && (ctx.Value(framework) != nil) { + commentsMap[framework] = ctx.Value(framework).(string) + } + + if db.options.EnableRoute && (ctx.Value(route) != nil) { + commentsMap[route] = ctx.Value(route).(string) + } + + if db.options.EnableTraceparent { + carrier := extractTraceparent(ctx) + if val, ok := carrier["traceparent"]; ok { + commentsMap[traceparent] = val + } + } + + var commentsString string = "" + if len(commentsMap) > 0 { // Converts comments map to string and appends it to query + commentsString = fmt.Sprintf("/*%s*/", convertMapToComment(commentsMap)) + } + + // A semicolon at the end of the SQL statement means the query ends there. + // We need to insert the comment before that to be considered as part of the SQL statemtent. + if query[len(query)-1:] == ";" { + return fmt.Sprintf("%s%s;", strings.TrimSuffix(query, ";"), commentsString) + } + return fmt.Sprintf("%s%s", query, commentsString) +} + +// ***** Commenter Functions ***** + +// ***** Util Functions ***** + +func encodeURL(k string) string { + return url.QueryEscape(string(k)) +} + +func getFunctionName(i interface{}) string { + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() +} + +func convertMapToComment(tags map[string]string) string { + var sb strings.Builder + i, sz := 0, len(tags) + + //sort by keys + sortedKeys := make([]string, 0, len(tags)) + for k := range tags { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + + for _, key := range sortedKeys { + if i == sz-1 { + sb.WriteString(fmt.Sprintf("%s=%v", encodeURL(key), encodeURL(tags[key]))) + } else { + sb.WriteString(fmt.Sprintf("%s=%v,", encodeURL(key), encodeURL(tags[key]))) + } + i++ + } + return sb.String() +} + +func extractTraceparent(ctx context.Context) propagation.MapCarrier { + // Serialize the context into carrier + propgator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) + carrier := propagation.MapCarrier{} + propgator.Inject(ctx, carrier) + return carrier +} + +// ***** Util Functions ***** diff --git a/go/go-sql/go-sql_test.go b/go/go-sql/go-sql_test.go new file mode 100644 index 00000000..be03518a --- /dev/null +++ b/go/go-sql/go-sql_test.go @@ -0,0 +1,87 @@ +package gosql + +import ( + "context" + "net/http" + "regexp" + "testing" + + "github.com/DATA-DOG/go-sqlmock" + "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +var engine, connectionParams = "mysql", "root:root@/gotest" + +func TestDisabled(t *testing.T) { + mockDB, _, err := sqlmock.New() + + db := DB{DB: mockDB, options: CommenterOptions{}} + if err != nil { + t.Fatalf("MockSQL failed with unexpected error: %s", err) + } + + query := "SELECT 2" + if got, want := db.withComment(context.Background(), query), query; got != want { + t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) + } +} + +func TestHTTP_Net(t *testing.T) { + mockDB, _, err := sqlmock.New() + + db := DB{DB: mockDB, options: CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} + if err != nil { + t.Fatalf("MockSQL failed with unexpected error: %s", err) + } + + r, _ := http.NewRequest("GET", "hello/1", nil) + ctx := AddHttpRouterTags(r, context.Background()) + + got := db.withComment(ctx, "Select 1") + want := "Select 1/*driver=database%2Fsql,framework=net%2Fhttp,route=hello%2F1*/" + + if got != want { + t.Errorf("got %q, wanted %q", got, want) + } +} + +func TestQueryWithSemicolon(t *testing.T) { + mockDB, _, err := sqlmock.New() + + db := DB{DB: mockDB, options: CommenterOptions{EnableDBDriver: true}} + if err != nil { + t.Fatalf("MockSQL failed with unexpected error: %s", err) + } + got := db.withComment(context.Background(), "Select 1;") + want := "Select 1/*driver=database%2Fsql*/;" + + if got != want { + t.Errorf("got %q, wanted %q", got, want) + } +} + +func TestOtelIntegration(t *testing.T) { + mockDB, _, err := sqlmock.New() + + db := DB{DB: mockDB, options: CommenterOptions{EnableTraceparent: true}} + if err != nil { + t.Fatalf("MockSQL failed with unexpected error: %s", err) + } + + exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) + bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithSpanProcessor(bsp), + ) + + ctx, _ := tp.Tracer("").Start(context.Background(), "parent-span-name") + + got := db.withComment(ctx, "Select 1;") + r, _ := regexp.Compile("Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;") + + if !r.MatchString(got) { + t.Errorf("got %q", got) + } +} diff --git a/go/go-sql/go.mod b/go/go-sql/go.mod new file mode 100644 index 00000000..201245cb --- /dev/null +++ b/go/go-sql/go.mod @@ -0,0 +1,20 @@ +module google.com/sqlcommenter/gosql + +go 1.19 + +require ( + go.opentelemetry.io/otel v1.10.0 + go.opentelemetry.io/otel/sdk v1.10.0 +) + +require ( + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect +) + +require ( + github.com/DATA-DOG/go-sqlmock v1.5.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 + go.opentelemetry.io/otel/trace v1.10.0 // indirect +) diff --git a/go/go-sql/go.sum b/go/go-sql/go.sum new file mode 100644 index 00000000..14fae557 --- /dev/null +++ b/go/go-sql/go.sum @@ -0,0 +1,24 @@ +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= +go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= +golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= +golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From a35d545f87216dce39a4f1f7c9e049828f83319d Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 18:15:51 +0530 Subject: [PATCH 045/108] Added go core implementation (#163) --- .github/workflows/go-sql-tests.yaml | 8 +-- go/core/README.md | 28 ++++++++ go/core/core.go | 99 +++++++++++++++++++++++++++++ go/core/go.mod | 7 ++ go/core/go.sum | 11 ++++ 5 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 go/core/README.md create mode 100644 go/core/core.go create mode 100644 go/core/go.mod create mode 100644 go/core/go.sum diff --git a/.github/workflows/go-sql-tests.yaml b/.github/workflows/go-sql-tests.yaml index f7d92a45..e71b3e6b 100644 --- a/.github/workflows/go-sql-tests.yaml +++ b/.github/workflows/go-sql-tests.yaml @@ -1,14 +1,14 @@ -name: go-sql package test +name: go packages test on: push: branches: - master paths: - - go/go-sql/** + - go/** pull_request: paths: - - go/go-sql/** + - go/** jobs: unittests: @@ -25,7 +25,7 @@ jobs: run: go build -v ./... working-directory: ./go/go-sql - - name: Test + - name: Test go-sql run: go test -v ./... working-directory: ./go/go-sql diff --git a/go/core/README.md b/go/core/README.md new file mode 100644 index 00000000..326bc3b7 --- /dev/null +++ b/go/core/README.md @@ -0,0 +1,28 @@ +# SQLCommenter Core [In development] + +SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. + +This package contains configuration options, framework interface and support functions for all the sqlcommenter go modules + +## Installation + +This is a support package and will be installed indirectly by other go sqlcommenter packages + +## Usages + +### Configuration + +Users are given control over what tags they want to append by using `core.CommenterOptions` struct. + +```go +type CommenterOptions struct { + EnableDBDriver bool + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + } +``` + + diff --git a/go/core/core.go b/go/core/core.go new file mode 100644 index 00000000..65bf7194 --- /dev/null +++ b/go/core/core.go @@ -0,0 +1,99 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package core + +import ( + "context" + "fmt" + "net/url" + "reflect" + "runtime" + "sort" + "strings" + + "go.opentelemetry.io/otel/propagation" +) + +const ( + Route string = "route" + Controller string = "controller" + Action string = "action" + Framework string = "framework" + Driver string = "driver" + Traceparent string = "traceparent" +) + +type CommenterOptions struct { + EnableDBDriver bool + EnableRoute bool + EnableFramework bool + EnableController bool + EnableAction bool + EnableTraceparent bool +} + +func encodeURL(k string) string { + return url.QueryEscape(string(k)) +} + +func GetFunctionName(i interface{}) string { + if i == nil { + return "" + } + return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() +} + +func ConvertMapToComment(tags map[string]string) string { + var sb strings.Builder + i, sz := 0, len(tags) + + //sort by keys + sortedKeys := make([]string, 0, len(tags)) + for k := range tags { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + + for _, key := range sortedKeys { + if i == sz-1 { + sb.WriteString(fmt.Sprintf("%s=%v", encodeURL(key), encodeURL(tags[key]))) + } else { + sb.WriteString(fmt.Sprintf("%s=%v,", encodeURL(key), encodeURL(tags[key]))) + } + i++ + } + return sb.String() +} + +func ExtractTraceparent(ctx context.Context) propagation.MapCarrier { + // Serialize the context into carrier + textMapPropogator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) + carrier := propagation.MapCarrier{} + textMapPropogator.Inject(ctx, carrier) + return carrier +} + +type RequestExtractor interface { + Route() string + Action() string + Framework() string +} + +func ContextInject(ctx context.Context, h RequestExtractor) context.Context { + ctx = context.WithValue(ctx, Route, h.Route()) + ctx = context.WithValue(ctx, Action, h.Action()) + ctx = context.WithValue(ctx, Framework, h.Framework()) + return ctx +} diff --git a/go/core/go.mod b/go/core/go.mod new file mode 100644 index 00000000..0cb7633c --- /dev/null +++ b/go/core/go.mod @@ -0,0 +1,7 @@ +module github.com/google/sqlcommenter/go/core + +go 1.19 + +require go.opentelemetry.io/otel v1.10.0 + +require go.opentelemetry.io/otel/trace v1.10.0 // indirect diff --git a/go/core/go.sum b/go/core/go.sum new file mode 100644 index 00000000..c9ab1f94 --- /dev/null +++ b/go/core/go.sum @@ -0,0 +1,11 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From b29b610d675973672d38f33cf3bbe8d9dcc43a95 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:13:41 +0530 Subject: [PATCH 046/108] Go http net implementation (#164) Go HTTP initial implementation --- .gitignore | 3 +- go/net/http/README.md | 71 +++++++++++++++++++++++++++++++++++++++++++ go/net/http/go.mod | 10 ++++++ go/net/http/go.sum | 13 ++++++++ go/net/http/http.go | 42 +++++++++++++++++++++++++ 5 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 go/net/http/README.md create mode 100644 go/net/http/go.mod create mode 100644 go/net/http/go.sum create mode 100644 go/net/http/http.go diff --git a/.gitignore b/.gitignore index cc3016a8..c792cffb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ php/sqlcommenter-php/packages/sqlcommenter-laravel/vendor/* -.idea/** \ No newline at end of file +.idea/** +.DS_Store diff --git a/go/net/http/README.md b/go/net/http/README.md new file mode 100644 index 00000000..6c148954 --- /dev/null +++ b/go/net/http/README.md @@ -0,0 +1,71 @@ +# http-net [In development] + +SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. + +## Installation + +### Install from source + +* Clone the source +* In terminal go inside the client folder location where we need to import sqlcommenter http/net module and enter the below commands + +```shell +go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/http-net + +go mod tiny + +go get google.com/sqlcommenter/http-net +``` +### Install from github [To be added] + +## Usage + +Please use the sqlcommenter's default go-sql database driver to execute statements. \ +Due to inherent nature of Go, the safer way to pass information from framework to database driver is via `context`. So, it is recommended to use the context based methods of `DB` interface like `QueryContext`, `ExecContext` and `PrepareContext`. + +```go +db, err := gosql.Open("", "", sqlcommenter.CommenterOptions{:}) +``` + +### Configuration + +Users are given control over what tags they want to append by using `core.CommenterOptions` struct. + +```go +type CommenterOptions struct { + EnableDBDriver bool + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + } +``` + + +#### Note +* We only support the `database/sql` driver and have provided an implementation for that. +* ORM related tags are added to the driver only when the tags are enabled in the commenter's driver's config and also the request context should passed to the querying functions +* The middleware implementing this sqlcommenter http-net module should be added at the last + +#### Example +```go +// middleware is used to intercept incoming HTTP calls and populate request context with commenter tags. +func middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := httpnet.NewHttpNet(r, next).AddTags(r.Context()) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} +``` + +## Options + +With Go SqlCommenter, we have configuration to choose which tags to be appended to the comment. + +| Options | Included by default? | net/http | +| --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Action` | | [net/http handle](https://pkg.go.dev/net/http#Handle) | +| `Route` | | [net/http routing path](https://pkg.go.dev/github.com/gorilla/mux#Route.URLPath) | +| `Framework` | | [net/http](https://pkg.go.dev/net/http) | +| `Opentelemetry` | | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | diff --git a/go/net/http/go.mod b/go/net/http/go.mod new file mode 100644 index 00000000..42d8dd79 --- /dev/null +++ b/go/net/http/go.mod @@ -0,0 +1,10 @@ +module github.com/google/sqlcommenter/go/net/http + +go 1.19 + +require github.com/google/sqlcommenter/go/core v0.0.1-beta + +require ( + go.opentelemetry.io/otel v1.10.0 // indirect + go.opentelemetry.io/otel/trace v1.10.0 // indirect +) diff --git a/go/net/http/go.sum b/go/net/http/go.sum new file mode 100644 index 00000000..c0518c2b --- /dev/null +++ b/go/net/http/go.sum @@ -0,0 +1,13 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= +github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/go/net/http/http.go b/go/net/http/http.go new file mode 100644 index 00000000..5d762687 --- /dev/null +++ b/go/net/http/http.go @@ -0,0 +1,42 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package http + +import ( + "net/http" + + "github.com/google/sqlcommenter/go/core" +) + +type HTTPRequestExtractor struct { + r *http.Request + next any +} + +func NewHTTPRequestExtractor(r *http.Request, next any) *HTTPRequestExtractor { + return &HTTPRequestExtractor{r, next} +} + +func (h *HTTPRequestExtractor) Route() string { + return h.r.URL.Path +} + +func (h *HTTPRequestExtractor) Action() string { + return core.GetFunctionName(h.next) +} + +func (h *HTTPRequestExtractor) Framework() string { + return "net/http" +} From 7ba7ca1f51594db42819172b26b6064b615099ae Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:29:59 +0530 Subject: [PATCH 047/108] go-sql refactoring (#165) --- go/go-sql/README.md | 46 ++++++----------- go/go-sql/go-sql.go | 103 +++++---------------------------------- go/go-sql/go-sql_test.go | 54 ++++++++++++-------- go/go-sql/go.mod | 8 +-- go/go-sql/go.sum | 6 ++- 5 files changed, 70 insertions(+), 147 deletions(-) diff --git a/go/go-sql/README.md b/go/go-sql/README.md index d19afe0c..f8aeb1e2 100644 --- a/go/go-sql/README.md +++ b/go/go-sql/README.md @@ -1,4 +1,4 @@ -# Sqlcommenter [In development] +# go-sql-driver [In development] SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. @@ -7,28 +7,29 @@ SQLcommenter is a plugin/middleware/wrapper to augment application related infor ### Install from source * Clone the source -* In terminal go inside the client folder location where we need to import google-sqlcommenter package and enter the below commands +* In terminal go inside the client folder location where we need to import sqlcommenter go-sql module and enter the below commands ```shell -go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/go +go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/go-sql go mod tiny + +go get google.com/sqlcommenter/gosql ``` ### Install from github [To be added] -## Usages +## Usage -### go-sql-driver -Please use the sqlcommenter's default database driver to execute statements. \ +Please use the sqlcommenter's default go-sql database driver to execute statements. Due to inherent nature of Go, the safer way to pass information from framework to database driver is via `context`. So, it is recommended to use the context based methods of `DB` interface like `QueryContext`, `ExecContext` and `PrepareContext`. ```go -db, err := sqlcommenter.Open("", "", sqlcommenter.CommenterOptions{:}) +db, err := gosql.Open("", "", sqlcommenter.CommenterOptions{:}) ``` -#### Configuration +### Configuration -Users are given control over what tags they want to append by using `sqlcommenter.CommenterOptions` struct. +Users are given control over what tags they want to append by using `core.CommenterOptions` struct. ```go type CommenterOptions struct { @@ -41,32 +42,15 @@ type CommenterOptions struct { } ``` -### net/http -Populate the request context with sqlcommenter.AddHttpRouterTags(r) function in a custom middleware. -#### Note -* We only support the `database/sql` driver and have provided an implementation for that. -* ORM related tags are added to the driver only when the tags are enabled in the commenter's driver's config and also the request context should passed to the querying functions +### Framework Supported +* [http/net](.../../../http-net/README.md) -#### Example -```go -// middleware is used to intercept incoming HTTP calls and populate request context with commenter tags. -func middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := sqlcommenter.AddHttpRouterTags(r, next) - next.ServeHTTP(w, r.WithContext(ctx)) - }) -} -``` ## Options With Go SqlCommenter, we have configuration to choose which tags to be appended to the comment. -| Options | Included by default? | go-sql-orm | net/http | Notes | -| --------------- | :------------------: | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :---: | -| `DBDriver` | | [ go-sql-driver](https://pkg.go.dev/database/sql/driver) | | -| `Action` | | | [net/http handle](https://pkg.go.dev/net/http#Handle) | | -| `Route` | | | [net/http routing path](https://pkg.go.dev/github.com/gorilla/mux#Route.URLPath) | | -| `Framework` | | | [net/http](https://pkg.go.dev/net/http) | | -| `Opentelemetry` | | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | | +| Options | Included by default? | go-sql-driver | +| ---------- | -------------------- | -------------------------------------------------------- | +| `DBDriver` | | [ go-sql-driver](https://pkg.go.dev/database/sql/driver) | diff --git a/go/go-sql/go-sql.go b/go/go-sql/go-sql.go index 05ddf6ca..f4aae1b9 100644 --- a/go/go-sql/go-sql.go +++ b/go/go-sql/go-sql.go @@ -18,40 +18,17 @@ import ( "context" "database/sql" "fmt" - "net/http" - "net/url" - "reflect" - "runtime" - "sort" "strings" - "go.opentelemetry.io/otel/propagation" -) - -const ( - route string = "route" - controller string = "controller" - action string = "action" - framework string = "framework" - driver string = "driver" - traceparent string = "traceparent" + "github.com/google/sqlcommenter/go/core" ) type DB struct { *sql.DB - options CommenterOptions -} - -type CommenterOptions struct { - EnableDBDriver bool - EnableRoute bool - EnableFramework bool - EnableController bool - EnableAction bool - EnableTraceparent bool + options core.CommenterOptions } -func Open(driverName string, dataSourceName string, options CommenterOptions) (*DB, error) { +func Open(driverName string, dataSourceName string, options core.CommenterOptions) (*DB, error) { db, err := sql.Open(driverName, dataSourceName) return &DB{DB: db, options: options}, err } @@ -88,18 +65,6 @@ func (db *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, erro // ***** Query Functions ***** -// ***** Framework Functions ***** - -func AddHttpRouterTags(r *http.Request, next any) context.Context { // any type is set because we need to refrain from importing http-router package - ctx := context.Background() - ctx = context.WithValue(ctx, route, r.URL.Path) - ctx = context.WithValue(ctx, action, getFunctionName(next)) - ctx = context.WithValue(ctx, framework, "net/http") - return ctx -} - -// ***** Framework Functions ***** - // ***** Commenter Functions ***** func (db *DB) withComment(ctx context.Context, query string) string { @@ -107,34 +72,34 @@ func (db *DB) withComment(ctx context.Context, query string) string { query = strings.TrimSpace(query) // Sorted alphabetically - if db.options.EnableAction && (ctx.Value(action) != nil) { - commentsMap[action] = ctx.Value(action).(string) + if db.options.EnableAction && (ctx.Value(core.Action) != nil) { + commentsMap[core.Action] = ctx.Value(core.Action).(string) } // `driver` information should not be coming from framework. // So, explicitly adding that here. if db.options.EnableDBDriver { - commentsMap[driver] = "database/sql" + commentsMap[core.Driver] = "database/sql" } - if db.options.EnableFramework && (ctx.Value(framework) != nil) { - commentsMap[framework] = ctx.Value(framework).(string) + if db.options.EnableFramework && (ctx.Value(core.Framework) != nil) { + commentsMap[core.Framework] = ctx.Value(core.Framework).(string) } - if db.options.EnableRoute && (ctx.Value(route) != nil) { - commentsMap[route] = ctx.Value(route).(string) + if db.options.EnableRoute && (ctx.Value(core.Route) != nil) { + commentsMap[core.Route] = ctx.Value(core.Route).(string) } if db.options.EnableTraceparent { - carrier := extractTraceparent(ctx) + carrier := core.ExtractTraceparent(ctx) if val, ok := carrier["traceparent"]; ok { - commentsMap[traceparent] = val + commentsMap[core.Traceparent] = val } } var commentsString string = "" if len(commentsMap) > 0 { // Converts comments map to string and appends it to query - commentsString = fmt.Sprintf("/*%s*/", convertMapToComment(commentsMap)) + commentsString = fmt.Sprintf("/*%s*/", core.ConvertMapToComment(commentsMap)) } // A semicolon at the end of the SQL statement means the query ends there. @@ -146,45 +111,3 @@ func (db *DB) withComment(ctx context.Context, query string) string { } // ***** Commenter Functions ***** - -// ***** Util Functions ***** - -func encodeURL(k string) string { - return url.QueryEscape(string(k)) -} - -func getFunctionName(i interface{}) string { - return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() -} - -func convertMapToComment(tags map[string]string) string { - var sb strings.Builder - i, sz := 0, len(tags) - - //sort by keys - sortedKeys := make([]string, 0, len(tags)) - for k := range tags { - sortedKeys = append(sortedKeys, k) - } - sort.Strings(sortedKeys) - - for _, key := range sortedKeys { - if i == sz-1 { - sb.WriteString(fmt.Sprintf("%s=%v", encodeURL(key), encodeURL(tags[key]))) - } else { - sb.WriteString(fmt.Sprintf("%s=%v,", encodeURL(key), encodeURL(tags[key]))) - } - i++ - } - return sb.String() -} - -func extractTraceparent(ctx context.Context) propagation.MapCarrier { - // Serialize the context into carrier - propgator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) - carrier := propagation.MapCarrier{} - propgator.Inject(ctx, carrier) - return carrier -} - -// ***** Util Functions ***** diff --git a/go/go-sql/go-sql_test.go b/go/go-sql/go-sql_test.go index be03518a..fedbb7f6 100644 --- a/go/go-sql/go-sql_test.go +++ b/go/go-sql/go-sql_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package gosql import ( @@ -7,20 +21,18 @@ import ( "testing" "github.com/DATA-DOG/go-sqlmock" + "github.com/google/sqlcommenter/go/core" + httpnet "github.com/google/sqlcommenter/go/net/http" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdktrace "go.opentelemetry.io/otel/sdk/trace" ) -var engine, connectionParams = "mysql", "root:root@/gotest" - func TestDisabled(t *testing.T) { mockDB, _, err := sqlmock.New() - - db := DB{DB: mockDB, options: CommenterOptions{}} if err != nil { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - + db := DB{DB: mockDB, options: core.CommenterOptions{}} query := "SELECT 2" if got, want := db.withComment(context.Background(), query), query; got != want { t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) @@ -29,59 +41,61 @@ func TestDisabled(t *testing.T) { func TestHTTP_Net(t *testing.T) { mockDB, _, err := sqlmock.New() - - db := DB{DB: mockDB, options: CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} if err != nil { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - r, _ := http.NewRequest("GET", "hello/1", nil) - ctx := AddHttpRouterTags(r, context.Background()) + db := DB{DB: mockDB, options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} + r, err := http.NewRequest("GET", "hello/1", nil) + if err != nil { + t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) + } + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) got := db.withComment(ctx, "Select 1") want := "Select 1/*driver=database%2Fsql,framework=net%2Fhttp,route=hello%2F1*/" - if got != want { - t.Errorf("got %q, wanted %q", got, want) + t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) } } func TestQueryWithSemicolon(t *testing.T) { mockDB, _, err := sqlmock.New() - - db := DB{DB: mockDB, options: CommenterOptions{EnableDBDriver: true}} if err != nil { t.Fatalf("MockSQL failed with unexpected error: %s", err) } + + db := DB{DB: mockDB, options: core.CommenterOptions{EnableDBDriver: true}} got := db.withComment(context.Background(), "Select 1;") want := "Select 1/*driver=database%2Fsql*/;" - if got != want { - t.Errorf("got %q, wanted %q", got, want) + t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) } } func TestOtelIntegration(t *testing.T) { mockDB, _, err := sqlmock.New() - - db := DB{DB: mockDB, options: CommenterOptions{EnableTraceparent: true}} if err != nil { t.Fatalf("MockSQL failed with unexpected error: %s", err) } + db := DB{DB: mockDB, options: core.CommenterOptions{EnableTraceparent: true}} exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod tp := sdktrace.NewTracerProvider( sdktrace.WithSampler(sdktrace.AlwaysSample()), sdktrace.WithSpanProcessor(bsp), ) - ctx, _ := tp.Tracer("").Start(context.Background(), "parent-span-name") got := db.withComment(ctx, "Select 1;") - r, _ := regexp.Compile("Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;") + wantRegex := "Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;" + r, err := regexp.Compile(wantRegex) + if err != nil { + t.Errorf("regex.Compile() failed with error: %v", err) + } if !r.MatchString(got) { - t.Errorf("got %q", got) + t.Errorf("%q does not match the given regex %q", got, wantRegex) } } diff --git a/go/go-sql/go.mod b/go/go-sql/go.mod index 201245cb..060407c1 100644 --- a/go/go-sql/go.mod +++ b/go/go-sql/go.mod @@ -2,19 +2,19 @@ module google.com/sqlcommenter/gosql go 1.19 -require ( - go.opentelemetry.io/otel v1.10.0 - go.opentelemetry.io/otel/sdk v1.10.0 -) +require go.opentelemetry.io/otel/sdk v1.10.0 require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/sqlcommenter/go/core v0.0.1-beta // indirect + go.opentelemetry.io/otel v1.10.0 // indirect golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect ) require ( github.com/DATA-DOG/go-sqlmock v1.5.0 + github.com/google/sqlcommenter/go/net/http v0.0.1-beta go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 go.opentelemetry.io/otel/trace v1.10.0 // indirect ) diff --git a/go/go-sql/go.sum b/go/go-sql/go.sum index 14fae557..8db643f7 100644 --- a/go/go-sql/go.sum +++ b/go/go-sql/go.sum @@ -7,6 +7,10 @@ github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbV github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= +github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= +github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= @@ -17,8 +21,6 @@ go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpT go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7 h1:iGu644GcxtEcrInvDsQRCwJjtCIOlT2V7IRt6ah2Whw= -golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From 408a09e1fb2c8c43128dd31ed8a806fc48c793b8 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 19:58:28 +0530 Subject: [PATCH 048/108] Updating module name of go-sql to github.com/google/sqlcommenter/go/database/sql (#166) --- .github/workflows/go-sql-tests.yaml | 4 ++-- go/{go-sql => database/sql}/README.md | 0 go/{go-sql => database/sql}/go-sql.go | 2 +- go/{go-sql => database/sql}/go-sql_test.go | 2 +- go/{go-sql => database/sql}/go.mod | 8 +++++--- go/{go-sql => database/sql}/go.sum | 0 6 files changed, 9 insertions(+), 7 deletions(-) rename go/{go-sql => database/sql}/README.md (100%) rename go/{go-sql => database/sql}/go-sql.go (99%) rename go/{go-sql => database/sql}/go-sql_test.go (99%) rename go/{go-sql => database/sql}/go.mod (74%) rename go/{go-sql => database/sql}/go.sum (100%) diff --git a/.github/workflows/go-sql-tests.yaml b/.github/workflows/go-sql-tests.yaml index e71b3e6b..5f081e3a 100644 --- a/.github/workflows/go-sql-tests.yaml +++ b/.github/workflows/go-sql-tests.yaml @@ -23,11 +23,11 @@ jobs: - name: Build run: go build -v ./... - working-directory: ./go/go-sql + working-directory: ./go/database/sql - name: Test go-sql run: go test -v ./... - working-directory: ./go/go-sql + working-directory: ./go/database/sql gofmt: runs-on: ubuntu-latest diff --git a/go/go-sql/README.md b/go/database/sql/README.md similarity index 100% rename from go/go-sql/README.md rename to go/database/sql/README.md diff --git a/go/go-sql/go-sql.go b/go/database/sql/go-sql.go similarity index 99% rename from go/go-sql/go-sql.go rename to go/database/sql/go-sql.go index f4aae1b9..9742f24e 100644 --- a/go/go-sql/go-sql.go +++ b/go/database/sql/go-sql.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gosql +package sql import ( "context" diff --git a/go/go-sql/go-sql_test.go b/go/database/sql/go-sql_test.go similarity index 99% rename from go/go-sql/go-sql_test.go rename to go/database/sql/go-sql_test.go index fedbb7f6..78c1d5bf 100644 --- a/go/go-sql/go-sql_test.go +++ b/go/database/sql/go-sql_test.go @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -package gosql +package sql import ( "context" diff --git a/go/go-sql/go.mod b/go/database/sql/go.mod similarity index 74% rename from go/go-sql/go.mod rename to go/database/sql/go.mod index 060407c1..681d531f 100644 --- a/go/go-sql/go.mod +++ b/go/database/sql/go.mod @@ -1,13 +1,15 @@ -module google.com/sqlcommenter/gosql +module github.com/google/sqlcommenter/go/database/sql go 1.19 -require go.opentelemetry.io/otel/sdk v1.10.0 +require ( + github.com/google/sqlcommenter/go/core v0.0.1-beta + go.opentelemetry.io/otel/sdk v1.10.0 +) require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/sqlcommenter/go/core v0.0.1-beta // indirect go.opentelemetry.io/otel v1.10.0 // indirect golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect ) diff --git a/go/go-sql/go.sum b/go/database/sql/go.sum similarity index 100% rename from go/go-sql/go.sum rename to go/database/sql/go.sum From 14e94421301f01b2932d83a2857ee8068e3490c1 Mon Sep 17 00:00:00 2001 From: Thiyagu55 <64461612+Thiyagu55@users.noreply.github.com> Date: Fri, 30 Sep 2022 20:42:48 +0530 Subject: [PATCH 049/108] Sample module for go sqlcommenter-http (#167) * Sample module for sqlcommenter-http * Added Readme --- go/samples/http/README.md | 18 +++++++++++++ go/samples/http/go.mod | 21 +++++++++++++++ go/samples/http/go.sum | 29 +++++++++++++++++++++ go/samples/http/main.go | 55 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 123 insertions(+) create mode 100644 go/samples/http/README.md create mode 100644 go/samples/http/go.mod create mode 100644 go/samples/http/go.sum create mode 100644 go/samples/http/main.go diff --git a/go/samples/http/README.md b/go/samples/http/README.md new file mode 100644 index 00000000..6520fd32 --- /dev/null +++ b/go/samples/http/README.md @@ -0,0 +1,18 @@ +# sqlcommenter-http + + +## Installation + + +* Clone the source +* Update `connection` string in Index function +* Install dependencies + ``` + go build + ``` + +* Run the app + ``` + go run main.go + ```` +* Hit the url http://localhost:8080/ and observe the mysql logs to see comments appended diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod new file mode 100644 index 00000000..c8f2e7ad --- /dev/null +++ b/go/samples/http/go.mod @@ -0,0 +1,21 @@ +module sqlcommenter-http + +go 1.19 + +require ( + github.com/go-sql-driver/mysql v1.6.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 + go.opentelemetry.io/otel/sdk v1.10.0 +) + +require go.opentelemetry.io/otel v1.10.0 // indirect + +require ( + github.com/go-logr/logr v1.2.3 // indirect + github.com/go-logr/stdr v1.2.2 // indirect + github.com/google/sqlcommenter/go/core v0.0.1-beta + github.com/google/sqlcommenter/go/database/sql v0.0.1-beta + github.com/google/sqlcommenter/go/net/http v0.0.1-beta + go.opentelemetry.io/otel/trace v1.10.0 // indirect + golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect +) diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum new file mode 100644 index 00000000..35e93a6b --- /dev/null +++ b/go/samples/http/go.sum @@ -0,0 +1,29 @@ +github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= +github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= +github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= +github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= +github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/database/sql v0.0.1-beta h1:N680pEYaRwmOSrQWUd4A4aD4kj4WYxcJTQB9WLe69vY= +github.com/google/sqlcommenter/go/database/sql v0.0.1-beta/go.mod h1:VdswmF4SM0cbjJdD+3GyM5QuXpHhH6F5nSzcbikzCGY= +github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= +github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= +go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= +go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= +golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/go/samples/http/main.go b/go/samples/http/main.go new file mode 100644 index 00000000..960e7cd0 --- /dev/null +++ b/go/samples/http/main.go @@ -0,0 +1,55 @@ +package main + +import ( + "fmt" + "log" + "net/http" + + _ "github.com/go-sql-driver/mysql" + "github.com/google/sqlcommenter/go/core" + gosql "github.com/google/sqlcommenter/go/database/sql" + httpnet "github.com/google/sqlcommenter/go/net/http" + "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +func Index(w http.ResponseWriter, r *http.Request) { + + connection := "root:root@/gotest" + exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) + bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithSpanProcessor(bsp), + ) + + ctx, span := tp.Tracer("foo").Start(r.Context(), "parent-span-name") + defer span.End() + + db, err := gosql.Open("mysql", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) + if err != nil { + fmt.Println(err) + } else { + db.ExecContext(ctx, "Select 11;") + db.Exec("Select 2;") + db.Prepare("Select 10") + db.PrepareContext(ctx, "Select 10") + } + fmt.Fprintf(w, "Hello World!") +} + +// middleware is used to intercept incoming HTTP calls and apply general functions upon them. +func middleware(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, next)) + log.Printf("HTTP request sent to %s from %v", r.URL.Path, next) + next.ServeHTTP(w, r.WithContext(ctx)) + }) +} + +func main() { + mux := http.NewServeMux() + finalHandler := http.HandlerFunc(Index) + mux.Handle("/", middleware((finalHandler))) + log.Fatal(http.ListenAndServe(":8080", mux)) +} From d7e4758b642fe322bbdabe96b3e4ed7332f54b89 Mon Sep 17 00:00:00 2001 From: Martin Keogh Date: Mon, 14 Nov 2022 08:22:26 +0100 Subject: [PATCH 050/108] fix: handle Starlette routes in FastAPI middleware (#136) This commit changes the FastAPI middleware so that the `"route"` info is now optional. If it is not present, the SQL comment will not have the controller/route info. This info is always present in FastAPI routes. However, Starlette-based routes (FastAPI can mount Starlette apps as sub-applications) do not and would crash when the middleware tried to extract the information. Fixes #133 --- .../google/cloud/sqlcommenter/fastapi.py | 2 +- python/sqlcommenter-python/tests/fastapi/app.py | 14 ++++++++++++++ python/sqlcommenter-python/tests/fastapi/tests.py | 10 ++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py b/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py index 3013492a..0fcc5f36 100644 --- a/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py +++ b/python/sqlcommenter-python/google/cloud/sqlcommenter/fastapi.py @@ -95,5 +95,5 @@ def _get_fastapi_route(fastapi_app: FastAPI, scope) -> Optional[Route]: # and return the route name if found. match, child_scope = route.matches(scope) if match == Match.FULL: - return child_scope["route"] + return child_scope.get("route") return None diff --git a/python/sqlcommenter-python/tests/fastapi/app.py b/python/sqlcommenter-python/tests/fastapi/app.py index 24dcc8ce..6bb88625 100644 --- a/python/sqlcommenter-python/tests/fastapi/app.py +++ b/python/sqlcommenter-python/tests/fastapi/app.py @@ -5,7 +5,9 @@ from google.cloud.sqlcommenter.fastapi import ( SQLCommenterMiddleware, get_fastapi_info, ) +from starlette.applications import Starlette from starlette.exceptions import HTTPException as StarletteHTTPException +from starlette.routing import Route app = FastAPI(title="SQLCommenter") @@ -28,3 +30,15 @@ async def custom_http_exception_handler(request, exc): status_code=status.HTTP_404_NOT_FOUND, content=get_fastapi_info(), ) + + +def starlette_endpoint(_): + return JSONResponse({"from": "starlette"}) + + +starlette_subapi = Starlette(routes=[ + Route("/", starlette_endpoint), +]) + + +app.mount("/starlette", starlette_subapi) diff --git a/python/sqlcommenter-python/tests/fastapi/tests.py b/python/sqlcommenter-python/tests/fastapi/tests.py index d2edb9f5..2fb84945 100644 --- a/python/sqlcommenter-python/tests/fastapi/tests.py +++ b/python/sqlcommenter-python/tests/fastapi/tests.py @@ -52,3 +52,13 @@ def test_get_fastapi_info_in_404_error_context(client): def test_get_fastapi_info_outside_request_context(client): assert get_fastapi_info() == {} + + +def test_get_openapi_does_not_throw_an_error(client): + resp = client.get(app.docs_url) + assert resp.status_code == 200 + + +def test_get_starlette_endpoints_does_not_throw_an_error(client): + resp = client.get("/starlette") + assert resp.status_code == 200 From a7117f66a9b769209bb00250f8a97667c2113e4f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 14 Nov 2022 13:07:36 +0530 Subject: [PATCH 051/108] working go samples/http --- go/samples/http/.gitignore | 2 + go/samples/http/docker-compose.yml | 27 +++++++++ go/samples/http/go.mod | 5 +- go/samples/http/go.sum | 2 + go/samples/http/main.go | 73 +++++++++++++++++++++---- go/samples/http/mysqldb/mysql_driver.go | 23 ++++++++ go/samples/http/pgdb/pg_driver.go | 23 ++++++++ go/samples/http/tail_mysql_log.sh | 1 + 8 files changed, 143 insertions(+), 13 deletions(-) create mode 100644 go/samples/http/.gitignore create mode 100644 go/samples/http/docker-compose.yml create mode 100644 go/samples/http/mysqldb/mysql_driver.go create mode 100644 go/samples/http/pgdb/pg_driver.go create mode 100755 go/samples/http/tail_mysql_log.sh diff --git a/go/samples/http/.gitignore b/go/samples/http/.gitignore new file mode 100644 index 00000000..353eb76a --- /dev/null +++ b/go/samples/http/.gitignore @@ -0,0 +1,2 @@ +sqlcommenter-http +docker-data/ \ No newline at end of file diff --git a/go/samples/http/docker-compose.yml b/go/samples/http/docker-compose.yml new file mode 100644 index 00000000..c2846ae0 --- /dev/null +++ b/go/samples/http/docker-compose.yml @@ -0,0 +1,27 @@ +version: '3.8' +services: + sqlcommenter_mysql_db: + container_name: sqlcommenter_mysql_db + image: mysql:8 + command: + --general-log=TRUE + --general-log-file=/var/lib/mysql/mysql-log.log + ports: + - '3306:3306' + environment: + MYSQL_DATABASE: 'sqlcommenter_db' + MYSQL_ROOT_PASSWORD: 'password' + volumes: + - './docker-data/mysql:/var/lib/postgresql/data' + sqlcommenter_pg_db: + container_name: sqlcommenter_pg_db + image: postgres:14 + command: postgres -c log_statement=all + ports: + - '5432:5432' + environment: + POSTGRES_USER: dev + POSTGRES_PASSWORD: dev + POSTGRES_DB: sqlcommenter_db + volumes: + - './docker-data/pg:/var/lib/postgresql/data' \ No newline at end of file diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index c8f2e7ad..8e8621b6 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -8,7 +8,10 @@ require ( go.opentelemetry.io/otel/sdk v1.10.0 ) -require go.opentelemetry.io/otel v1.10.0 // indirect +require ( + github.com/lib/pq v1.10.7 // indirect + go.opentelemetry.io/otel v1.10.0 // indirect +) require ( github.com/go-logr/logr v1.2.3 // indirect diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum index 35e93a6b..8eb99546 100644 --- a/go/samples/http/go.sum +++ b/go/samples/http/go.sum @@ -14,6 +14,8 @@ github.com/google/sqlcommenter/go/database/sql v0.0.1-beta h1:N680pEYaRwmOSrQWUd github.com/google/sqlcommenter/go/database/sql v0.0.1-beta/go.mod h1:VdswmF4SM0cbjJdD+3GyM5QuXpHhH6F5nSzcbikzCGY= github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= diff --git a/go/samples/http/main.go b/go/samples/http/main.go index 960e7cd0..cd9aef55 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -1,21 +1,24 @@ package main import ( + "flag" "fmt" "log" "net/http" - _ "github.com/go-sql-driver/mysql" "github.com/google/sqlcommenter/go/core" gosql "github.com/google/sqlcommenter/go/database/sql" httpnet "github.com/google/sqlcommenter/go/net/http" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdktrace "go.opentelemetry.io/otel/sdk/trace" + + "sqlcommenter-http/mysqldb" + "sqlcommenter-http/pgdb" ) -func Index(w http.ResponseWriter, r *http.Request) { +var db *gosql.DB - connection := "root:root@/gotest" +func Index(w http.ResponseWriter, r *http.Request) { exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod tp := sdktrace.NewTracerProvider( @@ -26,16 +29,24 @@ func Index(w http.ResponseWriter, r *http.Request) { ctx, span := tp.Tracer("foo").Start(r.Context(), "parent-span-name") defer span.End() - db, err := gosql.Open("mysql", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) + db.ExecContext(ctx, "Select 1") + db.Exec("Select 2") + + stmt1, err := db.Prepare("Select 3") + if err != nil { + log.Fatal(err) + } + stmt1.QueryRow() + + stmt2, err := db.PrepareContext(ctx, "Select 4") if err != nil { - fmt.Println(err) - } else { - db.ExecContext(ctx, "Select 11;") - db.Exec("Select 2;") - db.Prepare("Select 10") - db.PrepareContext(ctx, "Select 10") + log.Fatal(err) } - fmt.Fprintf(w, "Hello World!") + stmt2.QueryRow() + + db.QueryContext(ctx, "Select 5") + + fmt.Fprintf(w, "Hello World!\r\n") } // middleware is used to intercept incoming HTTP calls and apply general functions upon them. @@ -47,9 +58,47 @@ func middleware(next http.Handler) http.Handler { }) } -func main() { +func runForMysql() *gosql.DB { + connection := "root:password@/sqlcommenter_db" + db = mysqldb.ConnectMySQL(connection) + + mux := http.NewServeMux() + finalHandler := http.HandlerFunc(Index) + mux.Handle("/", middleware((finalHandler))) + log.Fatal(http.ListenAndServe(":8080", mux)) + return db + return db +} + +func runForPg() *gosql.DB { + connection := "postgres://dev:dev@localhost/sqlcommenter_db?sslmode=disable" + db = pgdb.ConnectPG(connection) + mux := http.NewServeMux() finalHandler := http.HandlerFunc(Index) mux.Handle("/", middleware((finalHandler))) log.Fatal(http.ListenAndServe(":8080", mux)) + return db +} + +func main() { + var engine string + + flag.StringVar(&engine, "db_engine", "mysql", "db-engine to run the sample on") + flag.Parse() + + if engine != "mysql" && engine != "pg" { + log.Fatalf("invalid engine: %s", engine) + } + + var db *gosql.DB + + switch engine { + case "mysql": + db = runForMysql() + case "pg": + db = runForPg() + } + + db.Close() } diff --git a/go/samples/http/mysqldb/mysql_driver.go b/go/samples/http/mysqldb/mysql_driver.go new file mode 100644 index 00000000..2b8da0e5 --- /dev/null +++ b/go/samples/http/mysqldb/mysql_driver.go @@ -0,0 +1,23 @@ +package mysqldb + +import ( + "log" + + _ "github.com/go-sql-driver/mysql" + "github.com/google/sqlcommenter/go/core" + gosql "github.com/google/sqlcommenter/go/database/sql" +) + +func ConnectMySQL(connection string) *gosql.DB { + db, err := gosql.Open("mysql", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) + if err != nil { + log.Fatal(err) + } + + err = db.Ping() + if err != nil { + log.Fatal(err) + } + + return db +} diff --git a/go/samples/http/pgdb/pg_driver.go b/go/samples/http/pgdb/pg_driver.go new file mode 100644 index 00000000..18c3972c --- /dev/null +++ b/go/samples/http/pgdb/pg_driver.go @@ -0,0 +1,23 @@ +package pgdb + +import ( + "log" + + "github.com/google/sqlcommenter/go/core" + gosql "github.com/google/sqlcommenter/go/database/sql" + _ "github.com/lib/pq" +) + +func ConnectPG(connection string) *gosql.DB { + db, err := gosql.Open("postgres", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) + if err != nil { + log.Fatal(err) + } + + err = db.Ping() + if err != nil { + log.Fatal(err) + } + + return db +} diff --git a/go/samples/http/tail_mysql_log.sh b/go/samples/http/tail_mysql_log.sh new file mode 100755 index 00000000..ec4346b9 --- /dev/null +++ b/go/samples/http/tail_mysql_log.sh @@ -0,0 +1 @@ +docker exec -it sqlcommenter_mysql_db tail -f /var/lib/mysql/mysql-log.log \ No newline at end of file From 69274a7c0c1a9f8c180ea9d99947a784bd7c0d3f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 00:41:38 +0530 Subject: [PATCH 052/108] wiring done --- go/samples/http/go.mod | 1 + go/samples/http/go.sum | 2 + go/samples/http/main.go | 98 ++++++++++++++++------------- go/samples/http/todos/controller.go | 33 ++++++++++ go/samples/http/todos/queries.go | 54 ++++++++++++++++ 5 files changed, 146 insertions(+), 42 deletions(-) create mode 100644 go/samples/http/todos/controller.go create mode 100644 go/samples/http/todos/queries.go diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index 8e8621b6..9bdc82eb 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -9,6 +9,7 @@ require ( ) require ( + github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/lib/pq v1.10.7 // indirect go.opentelemetry.io/otel v1.10.0 // indirect ) diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum index 8eb99546..35d728c6 100644 --- a/go/samples/http/go.sum +++ b/go/samples/http/go.sum @@ -14,6 +14,8 @@ github.com/google/sqlcommenter/go/database/sql v0.0.1-beta h1:N680pEYaRwmOSrQWUd github.com/google/sqlcommenter/go/database/sql v0.0.1-beta/go.mod h1:VdswmF4SM0cbjJdD+3GyM5QuXpHhH6F5nSzcbikzCGY= github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= +github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/go/samples/http/main.go b/go/samples/http/main.go index cd9aef55..2177dd63 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -9,82 +9,96 @@ import ( "github.com/google/sqlcommenter/go/core" gosql "github.com/google/sqlcommenter/go/database/sql" httpnet "github.com/google/sqlcommenter/go/net/http" + "github.com/julienschmidt/httprouter" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdktrace "go.opentelemetry.io/otel/sdk/trace" "sqlcommenter-http/mysqldb" "sqlcommenter-http/pgdb" + "sqlcommenter-http/todos" ) -var db *gosql.DB +func MakeIndexRoute(db *gosql.DB) func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { + exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) + bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithSpanProcessor(bsp), + ) -func Index(w http.ResponseWriter, r *http.Request) { - exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) - bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSpanProcessor(bsp), - ) + ctx, span := tp.Tracer("foo").Start(r.Context(), "parent-span-name") + defer span.End() - ctx, span := tp.Tracer("foo").Start(r.Context(), "parent-span-name") - defer span.End() + db.ExecContext(ctx, "Select 1") + db.Exec("Select 2") - db.ExecContext(ctx, "Select 1") - db.Exec("Select 2") + stmt1, err := db.Prepare("Select 3") + if err != nil { + log.Fatal(err) + } + stmt1.QueryRow() - stmt1, err := db.Prepare("Select 3") - if err != nil { - log.Fatal(err) + stmt2, err := db.PrepareContext(ctx, "Select 4") + if err != nil { + log.Fatal(err) + } + stmt2.QueryRow() + + db.QueryContext(ctx, "Select 5") + + fmt.Fprintf(w, "Hello World!\r\n") } - stmt1.QueryRow() +} - stmt2, err := db.PrepareContext(ctx, "Select 4") +// middleware is used to intercept incoming HTTP calls and apply general functions upon them. +func middleware(next httprouter.Handle) httprouter.Handle { + return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, next)) + log.Printf("HTTP request sent to %s from %v", r.URL.Path, next) + next(w, r.WithContext(ctx), p) + } +} + +func runApp(todosController *todos.TodosController) { + err := todosController.CreateTodosTableIfNotExists() if err != nil { log.Fatal(err) } - stmt2.QueryRow() - db.QueryContext(ctx, "Select 5") + router := httprouter.New() - fmt.Fprintf(w, "Hello World!\r\n") -} + index := MakeIndexRoute(todosController.DB) + router.GET("/", middleware(index)) -// middleware is used to intercept incoming HTTP calls and apply general functions upon them. -func middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, next)) - log.Printf("HTTP request sent to %s from %v", r.URL.Path, next) - next.ServeHTTP(w, r.WithContext(ctx)) - }) + router.GET("/todos", middleware(todosController.ActionList)) + router.POST("/todos", middleware(todosController.ActionInsert)) + router.PUT("/todos/:id", middleware(todosController.ActionUpdate)) + router.DELETE("/todos/:id", middleware(todosController.ActionDelete)) + + http.ListenAndServe(":8080", router) } func runForMysql() *gosql.DB { connection := "root:password@/sqlcommenter_db" - db = mysqldb.ConnectMySQL(connection) - - mux := http.NewServeMux() - finalHandler := http.HandlerFunc(Index) - mux.Handle("/", middleware((finalHandler))) - log.Fatal(http.ListenAndServe(":8080", mux)) - return db + db := mysqldb.ConnectMySQL(connection) + todosController := &todos.TodosController{DB: db, SQL: todos.MySQLQueries{}} + runApp(todosController) return db } func runForPg() *gosql.DB { connection := "postgres://dev:dev@localhost/sqlcommenter_db?sslmode=disable" - db = pgdb.ConnectPG(connection) - - mux := http.NewServeMux() - finalHandler := http.HandlerFunc(Index) - mux.Handle("/", middleware((finalHandler))) - log.Fatal(http.ListenAndServe(":8080", mux)) + db := pgdb.ConnectPG(connection) + todosController := &todos.TodosController{DB: db, SQL: todos.PGQueries{}} + runApp(todosController) return db } func main() { var engine string - flag.StringVar(&engine, "db_engine", "mysql", "db-engine to run the sample on") + flag.StringVar(&engine, "db_engine", "mysql", "db-engine to run the sample application on") flag.Parse() if engine != "mysql" && engine != "pg" { diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go new file mode 100644 index 00000000..4c1fb419 --- /dev/null +++ b/go/samples/http/todos/controller.go @@ -0,0 +1,33 @@ +package todos + +import ( + "net/http" + + gosql "github.com/google/sqlcommenter/go/database/sql" + "github.com/julienschmidt/httprouter" +) + +type TodosController struct { + DB *gosql.DB + SQL TodosQueries +} + +func (c *TodosController) CreateTodosTableIfNotExists() error { + return nil +} + +func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + +} + +func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + +} + +func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + +} + +func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + +} diff --git a/go/samples/http/todos/queries.go b/go/samples/http/todos/queries.go new file mode 100644 index 00000000..c5eccf6f --- /dev/null +++ b/go/samples/http/todos/queries.go @@ -0,0 +1,54 @@ +package todos + +type PGQueries struct{} +type MySQLQueries struct{} + +type TodosQueries interface { + CreateTodosTableIfNotExists() string + ListTodos(search string) string + InsertTodo(task string) string + UpdateTodo(id int, task string) string + DeleteTodo(id int) string +} + +// PGQueries impl +func (sql PGQueries) CreateTodosTableIfNotExists() string { + return "" +} + +func (sql PGQueries) ListTodos(search string) string { + return "" +} + +func (sql PGQueries) InsertTodo(task string) string { + return "" +} + +func (sql PGQueries) UpdateTodo(id int, task string) string { + return "" +} + +func (sql PGQueries) DeleteTodo(id int) string { + return "" +} + +// MySQLQueries impl +func (sql MySQLQueries) CreateTodosTableIfNotExists() string { + return "" +} + +func (sql MySQLQueries) ListTodos(search string) string { + return "" +} + +func (sql MySQLQueries) InsertTodo(task string) string { + return "" +} + +func (sql MySQLQueries) UpdateTodo(id int, task string) string { + return "" +} + +func (sql MySQLQueries) DeleteTodo(id int) string { + return "" +} From d89b78f855476e375e595bdce411af929a0bf556 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 01:57:29 +0530 Subject: [PATCH 053/108] todo CRUD done, testing left --- go/samples/http/main.go | 4 +- go/samples/http/todos/controller.go | 227 +++++++++++++++++++++++++++- go/samples/http/todos/queries.go | 63 +++++--- 3 files changed, 268 insertions(+), 26 deletions(-) diff --git a/go/samples/http/main.go b/go/samples/http/main.go index 2177dd63..767f3ce7 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -82,7 +82,7 @@ func runApp(todosController *todos.TodosController) { func runForMysql() *gosql.DB { connection := "root:password@/sqlcommenter_db" db := mysqldb.ConnectMySQL(connection) - todosController := &todos.TodosController{DB: db, SQL: todos.MySQLQueries{}} + todosController := &todos.TodosController{Engine: "mysql", DB: db, SQL: todos.MySQLQueries{}} runApp(todosController) return db } @@ -90,7 +90,7 @@ func runForMysql() *gosql.DB { func runForPg() *gosql.DB { connection := "postgres://dev:dev@localhost/sqlcommenter_db?sslmode=disable" db := pgdb.ConnectPG(connection) - todosController := &todos.TodosController{DB: db, SQL: todos.PGQueries{}} + todosController := &todos.TodosController{Engine: "pg", DB: db, SQL: todos.PGQueries{}} runApp(todosController) return db } diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index 4c1fb419..b43dd040 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -1,15 +1,28 @@ package todos import ( + "context" + "encoding/json" + "log" "net/http" gosql "github.com/google/sqlcommenter/go/database/sql" "github.com/julienschmidt/httprouter" ) +type Todo struct { + Id int `json:"id"` + Task string `json:"task"` +} + +type TodoDTO struct { + Task string `json:"task"` +} + type TodosController struct { - DB *gosql.DB - SQL TodosQueries + Engine string + DB *gosql.DB + SQL TodosQueries } func (c *TodosController) CreateTodosTableIfNotExists() error { @@ -17,17 +30,227 @@ func (c *TodosController) CreateTodosTableIfNotExists() error { } func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx := r.Context() + + query := r.URL.Query() + search := query.Get("search") + rows, err := c.DB.QueryContext(ctx, c.SQL.ListTodos(), search) + if err != nil { + writeServerErrorResponse(w, "query failed") + return + } + defer rows.Close() + + var todos []Todo + for rows.Next() { + var todo Todo + if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + writeServerErrorResponse(w, "scan row failed") + return + } + + todos = append(todos, todo) + } + + res := make(map[string]([]Todo)) + res["todos"] = todos + writeJsonResponse(w, res) } func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx := r.Context() + + var dto TodoDTO + err := json.NewDecoder(r.Body).Decode(&dto) + if err != nil { + writeServerErrorResponse(w, "parsing body failed") + return + } + + if c.Engine == "pg" { + c.insertTodoPG(ctx, w, dto) + } else if c.Engine == "mysql" { + c.insertTodoMySQL(ctx, w, dto) + } else { + log.Fatalf("Invalid controller.Engine %v", c.Engine) + } +} + +func (c *TodosController) insertTodoPG(ctx context.Context, w http.ResponseWriter, dto TodoDTO) { + rows, err := c.DB.QueryContext(ctx, c.SQL.InsertTodo(), dto.Task) + if err != nil { + writeServerErrorResponse(w, "insert failed") + return + } + + if rows.Next() { + var todo Todo + if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + writeServerErrorResponse(w, "scan row failed") + return + } + + res := make(map[string]Todo) + res["todo"] = todo + writeJsonResponse(w, res) + return + } else { + writeServerErrorResponse(w, "no record of inserted task") + return + } +} +func (c *TodosController) insertTodoMySQL(ctx context.Context, w http.ResponseWriter, dto TodoDTO) { + dbRes, err := c.DB.ExecContext(ctx, c.SQL.InsertTodo(), dto.Task) + if err != nil { + writeServerErrorResponse(w, "insert failed") + return + } + + lId, err := dbRes.LastInsertId() + if err != nil { + writeServerErrorResponse(w, "cannot get insert-id") + return + } + + rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), lId) + if err != nil { + writeServerErrorResponse(w, "error in query") + return + } + + if rows.Next() { + var todo Todo + if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + writeServerErrorResponse(w, "scan row failed") + return + } + + res := make(map[string]Todo) + res["todo"] = todo + writeJsonResponse(w, res) + return + } else { + writeServerErrorResponse(w, "no record of inserted task") + return + } } func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx := r.Context() + id := p.ByName("id") + + var dto TodoDTO + err := json.NewDecoder(r.Body).Decode(&dto) + if err != nil { + writeServerErrorResponse(w, "parsing body failed") + return + } + var todo Todo + rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), id) + if err != nil { + writeServerErrorResponse(w, "error in query") + return + } + + if rows.Next() { + if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + writeServerErrorResponse(w, "scan row failed") + return + } + } else { + writeNotFoundResponse(w) + return + } + + _, err = c.DB.ExecContext(ctx, c.SQL.UpdateTodo(), dto.Task, todo.Id) + if err != nil { + writeServerErrorResponse(w, "update todo query failed") + return + } + + todo.Task = dto.Task + res := make(map[string]Todo) + res["todo"] = todo + writeJsonResponse(w, res) } func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p httprouter.Params) { + ctx := r.Context() + id := p.ByName("id") + + var todo Todo + rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), id) + if err != nil { + writeServerErrorResponse(w, "error in query") + return + } + + if rows.Next() { + if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + writeServerErrorResponse(w, "scan row failed") + return + } + } else { + writeNotFoundResponse(w) + return + } + + _, err = c.DB.ExecContext(ctx, c.SQL.DeleteTodo(), todo.Id) + if err != nil { + writeServerErrorResponse(w, "update todo query failed") + return + } + + res := make(map[string]Todo) + res["todo"] = todo + writeJsonResponse(w, res) +} + +func writeJsonResponse(w http.ResponseWriter, res any) { + w.WriteHeader(http.StatusOK) + w.Header().Set("Content-Type", "application/json") + + resJson, err := json.Marshal(res) + if err != nil { + log.Fatalf("error: json marshall: %v", res) + } + + w.Write(resJson) + return +} + +func writeServerErrorResponse(w http.ResponseWriter, reason string) { + w.WriteHeader(http.StatusInternalServerError) + w.Header().Set("Content-Type", "application/json") + + res := make(map[string]string) + res["msg"] = "server error" + res["reason"] = reason + + resJson, err := json.Marshal(res) + if err != nil { + log.Fatalf("error: json marshall: %v", res) + } + + w.Write(resJson) + return +} + +func writeNotFoundResponse(w http.ResponseWriter) { + w.WriteHeader(http.StatusNotFound) + w.Header().Set("Content-Type", "application/json") + + res := make(map[string]string) + res["msg"] = "not found" + + resJson, err := json.Marshal(res) + if err != nil { + log.Fatalf("error: json marshall: %v", res) + } + w.Write(resJson) + return } diff --git a/go/samples/http/todos/queries.go b/go/samples/http/todos/queries.go index c5eccf6f..8ec7e680 100644 --- a/go/samples/http/todos/queries.go +++ b/go/samples/http/todos/queries.go @@ -5,50 +5,69 @@ type MySQLQueries struct{} type TodosQueries interface { CreateTodosTableIfNotExists() string - ListTodos(search string) string - InsertTodo(task string) string - UpdateTodo(id int, task string) string - DeleteTodo(id int) string + ListTodos() string + InsertTodo() string + UpdateTodo() string + DeleteTodo() string + TodoById() string } // PGQueries impl func (sql PGQueries) CreateTodosTableIfNotExists() string { - return "" + return `CREATE TABLE IF NOT EXISTS todos( + id SERIAL NOT NULL, + task VARCHAR(1000) NOT NULL, + + PRIMARY KEY(id) +)` +} + +func (sql PGQueries) ListTodos() string { + return "SELECT id, task FROM todos WHERE LOWER(task) LIKE $1 ORDER BY id DESC" } -func (sql PGQueries) ListTodos(search string) string { - return "" +func (sql PGQueries) InsertTodo() string { + return "INSERT INTO todos (task) VALUES ($1) RETURNING id, task" } -func (sql PGQueries) InsertTodo(task string) string { - return "" +func (sql PGQueries) UpdateTodo() string { + return "UPDATE todos SET task=$1 WHERE id=$2" } -func (sql PGQueries) UpdateTodo(id int, task string) string { - return "" +func (sql PGQueries) DeleteTodo() string { + return "DELETE FROM todos WHERE id=$1" } -func (sql PGQueries) DeleteTodo(id int) string { - return "" +func (sql PGQueries) TodoById() string { + return "SELECT id, task FROM todos WHERE id=$1" } // MySQLQueries impl func (sql MySQLQueries) CreateTodosTableIfNotExists() string { - return "" + return `CREATE TABLE IF NOT EXISTS todos( + id INT NOT NULL AUTO_INCREMENT, + task VARCHAR(1000) NOT NULL + + PRIMARY KEY(id) +)` +} + +func (sql MySQLQueries) ListTodos() string { + return "SELECT id, task FROM todos WHERE task LIKE ? ORDER BY id DESC" } -func (sql MySQLQueries) ListTodos(search string) string { - return "" +func (sql MySQLQueries) InsertTodo() string { + return "INSERT INTO todos (task) VALUES (?)" } -func (sql MySQLQueries) InsertTodo(task string) string { - return "" +func (sql MySQLQueries) UpdateTodo() string { + return "UPDATE todos SET task=? WHERE id=?" } -func (sql MySQLQueries) UpdateTodo(id int, task string) string { - return "" +func (sql MySQLQueries) DeleteTodo() string { + return "DELETE FROM todos WHERE id=?" } -func (sql MySQLQueries) DeleteTodo(id int) string { - return "" +func (sql MySQLQueries) TodoById() string { + return "SELECT id, task FROM todos WHERE id=?" } From 3bbf3d267e51a2cf33309136c5aa90ee2eee52c5 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 02:07:55 +0530 Subject: [PATCH 054/108] bad request response --- go/samples/http/todos/controller.go | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index b43dd040..ff927f41 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -64,7 +64,7 @@ func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p var dto TodoDTO err := json.NewDecoder(r.Body).Decode(&dto) if err != nil { - writeServerErrorResponse(w, "parsing body failed") + writeBadRequestResponse(w, "parsing body failed") return } @@ -144,7 +144,7 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p var dto TodoDTO err := json.NewDecoder(r.Body).Decode(&dto) if err != nil { - writeServerErrorResponse(w, "parsing body failed") + writeBadRequestResponse(w, "parsing body failed") return } @@ -254,3 +254,20 @@ func writeNotFoundResponse(w http.ResponseWriter) { w.Write(resJson) return } + +func writeBadRequestResponse(w http.ResponseWriter, reason string) { + w.WriteHeader(http.StatusBadRequest) + w.Header().Set("Content-Type", "application/json") + + res := make(map[string]string) + res["msg"] = "bad request" + res["reason"] = reason + + resJson, err := json.Marshal(res) + if err != nil { + log.Fatalf("error: json marshall: %v", res) + } + + w.Write(resJson) + return +} From 13034401a3fc9c330536e09cb3fb185bcbf6c60f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 02:28:20 +0530 Subject: [PATCH 055/108] curls working --- go/samples/http/curls/delete.sh | 4 ++++ go/samples/http/curls/index.sh | 2 ++ go/samples/http/curls/insert.sh | 5 +++++ go/samples/http/curls/list.sh | 2 ++ go/samples/http/curls/update.sh | 5 +++++ go/samples/http/go.mod | 4 ++-- go/samples/http/todos/controller.go | 27 ++++++++++++++++++++++++--- 7 files changed, 44 insertions(+), 5 deletions(-) create mode 100755 go/samples/http/curls/delete.sh create mode 100755 go/samples/http/curls/index.sh create mode 100755 go/samples/http/curls/insert.sh create mode 100755 go/samples/http/curls/list.sh create mode 100755 go/samples/http/curls/update.sh diff --git a/go/samples/http/curls/delete.sh b/go/samples/http/curls/delete.sh new file mode 100755 index 00000000..a0fe5573 --- /dev/null +++ b/go/samples/http/curls/delete.sh @@ -0,0 +1,4 @@ +curl --header "Content-Type: application/json" \ + --request DELETE \ + http://localhost:8080/todos/$1 +echo \ No newline at end of file diff --git a/go/samples/http/curls/index.sh b/go/samples/http/curls/index.sh new file mode 100755 index 00000000..1aaef3ef --- /dev/null +++ b/go/samples/http/curls/index.sh @@ -0,0 +1,2 @@ +curl http://localhost:8080 +echo \ No newline at end of file diff --git a/go/samples/http/curls/insert.sh b/go/samples/http/curls/insert.sh new file mode 100755 index 00000000..f9d96ac7 --- /dev/null +++ b/go/samples/http/curls/insert.sh @@ -0,0 +1,5 @@ +curl --header "Content-Type: application/json" \ + --request POST \ + --data '{"task":"'$1'"}' \ + http://localhost:8080/todos +echo \ No newline at end of file diff --git a/go/samples/http/curls/list.sh b/go/samples/http/curls/list.sh new file mode 100755 index 00000000..71739d53 --- /dev/null +++ b/go/samples/http/curls/list.sh @@ -0,0 +1,2 @@ +curl http://localhost:8080/todos?search=$1 +echo \ No newline at end of file diff --git a/go/samples/http/curls/update.sh b/go/samples/http/curls/update.sh new file mode 100755 index 00000000..a188ea6e --- /dev/null +++ b/go/samples/http/curls/update.sh @@ -0,0 +1,5 @@ +curl --header "Content-Type: application/json" \ + --request PUT \ + --data '{"task":"'$2'"}' \ + http://localhost:8080/todos/$1 +echo \ No newline at end of file diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index 9bdc82eb..62c7f725 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -9,8 +9,8 @@ require ( ) require ( - github.com/julienschmidt/httprouter v1.3.0 // indirect - github.com/lib/pq v1.10.7 // indirect + github.com/julienschmidt/httprouter v1.3.0 + github.com/lib/pq v1.10.7 go.opentelemetry.io/otel v1.10.0 // indirect ) diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index ff927f41..ef2aeb75 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -3,6 +3,7 @@ package todos import ( "context" "encoding/json" + "fmt" "log" "net/http" @@ -26,7 +27,8 @@ type TodosController struct { } func (c *TodosController) CreateTodosTableIfNotExists() error { - return nil + _, err := c.DB.Exec(c.SQL.CreateTodosTableIfNotExists()) + return err } func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { @@ -35,17 +37,19 @@ func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p h query := r.URL.Query() search := query.Get("search") - rows, err := c.DB.QueryContext(ctx, c.SQL.ListTodos(), search) + rows, err := c.DB.QueryContext(ctx, c.SQL.ListTodos(), "%"+search+"%") if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "query failed") return } defer rows.Close() - var todos []Todo + var todos []Todo = make([]Todo, 0) for rows.Next() { var todo Todo if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + fmt.Println(err) writeServerErrorResponse(w, "scan row failed") return } @@ -64,6 +68,7 @@ func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p var dto TodoDTO err := json.NewDecoder(r.Body).Decode(&dto) if err != nil { + fmt.Println(err) writeBadRequestResponse(w, "parsing body failed") return } @@ -80,6 +85,7 @@ func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p func (c *TodosController) insertTodoPG(ctx context.Context, w http.ResponseWriter, dto TodoDTO) { rows, err := c.DB.QueryContext(ctx, c.SQL.InsertTodo(), dto.Task) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "insert failed") return } @@ -87,6 +93,7 @@ func (c *TodosController) insertTodoPG(ctx context.Context, w http.ResponseWrite if rows.Next() { var todo Todo if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + fmt.Println(err) writeServerErrorResponse(w, "scan row failed") return } @@ -104,18 +111,21 @@ func (c *TodosController) insertTodoPG(ctx context.Context, w http.ResponseWrite func (c *TodosController) insertTodoMySQL(ctx context.Context, w http.ResponseWriter, dto TodoDTO) { dbRes, err := c.DB.ExecContext(ctx, c.SQL.InsertTodo(), dto.Task) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "insert failed") return } lId, err := dbRes.LastInsertId() if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "cannot get insert-id") return } rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), lId) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "error in query") return } @@ -144,6 +154,7 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p var dto TodoDTO err := json.NewDecoder(r.Body).Decode(&dto) if err != nil { + fmt.Println(err) writeBadRequestResponse(w, "parsing body failed") return } @@ -151,12 +162,14 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p var todo Todo rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), id) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "error in query") return } if rows.Next() { if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + fmt.Println(err) writeServerErrorResponse(w, "scan row failed") return } @@ -167,6 +180,7 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p _, err = c.DB.ExecContext(ctx, c.SQL.UpdateTodo(), dto.Task, todo.Id) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "update todo query failed") return } @@ -184,12 +198,14 @@ func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p var todo Todo rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), id) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "error in query") return } if rows.Next() { if err := rows.Scan(&todo.Id, &todo.Task); err != nil { + fmt.Println(err) writeServerErrorResponse(w, "scan row failed") return } @@ -200,6 +216,7 @@ func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p _, err = c.DB.ExecContext(ctx, c.SQL.DeleteTodo(), todo.Id) if err != nil { + fmt.Println(err) writeServerErrorResponse(w, "update todo query failed") return } @@ -215,6 +232,7 @@ func writeJsonResponse(w http.ResponseWriter, res any) { resJson, err := json.Marshal(res) if err != nil { + fmt.Println(err) log.Fatalf("error: json marshall: %v", res) } @@ -232,6 +250,7 @@ func writeServerErrorResponse(w http.ResponseWriter, reason string) { resJson, err := json.Marshal(res) if err != nil { + fmt.Println(err) log.Fatalf("error: json marshall: %v", res) } @@ -248,6 +267,7 @@ func writeNotFoundResponse(w http.ResponseWriter) { resJson, err := json.Marshal(res) if err != nil { + fmt.Println(err) log.Fatalf("error: json marshall: %v", res) } @@ -265,6 +285,7 @@ func writeBadRequestResponse(w http.ResponseWriter, reason string) { resJson, err := json.Marshal(res) if err != nil { + fmt.Println(err) log.Fatalf("error: json marshall: %v", res) } From fc321f1e739c18370150ed20d259162c4415cf0a Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 02:32:59 +0530 Subject: [PATCH 056/108] fix for mysql create table --- go/samples/http/todos/queries.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/go/samples/http/todos/queries.go b/go/samples/http/todos/queries.go index 8ec7e680..bbbeebdc 100644 --- a/go/samples/http/todos/queries.go +++ b/go/samples/http/todos/queries.go @@ -45,10 +45,8 @@ func (sql PGQueries) TodoById() string { // MySQLQueries impl func (sql MySQLQueries) CreateTodosTableIfNotExists() string { return `CREATE TABLE IF NOT EXISTS todos( - id INT NOT NULL AUTO_INCREMENT, + id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, task VARCHAR(1000) NOT NULL - - PRIMARY KEY(id) )` } From 5ad98cd762daa8a2fd1985e348b8fc5772c8b6d6 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 16 Nov 2022 02:35:46 +0530 Subject: [PATCH 057/108] doc comment for curls --- go/samples/http/curls/delete.sh | 2 ++ go/samples/http/curls/index.sh | 2 ++ go/samples/http/curls/insert.sh | 2 ++ go/samples/http/curls/list.sh | 2 ++ go/samples/http/curls/update.sh | 2 ++ 5 files changed, 10 insertions(+) diff --git a/go/samples/http/curls/delete.sh b/go/samples/http/curls/delete.sh index a0fe5573..f8dd8c0c 100755 --- a/go/samples/http/curls/delete.sh +++ b/go/samples/http/curls/delete.sh @@ -1,3 +1,5 @@ +# usage: delete.sh + curl --header "Content-Type: application/json" \ --request DELETE \ http://localhost:8080/todos/$1 diff --git a/go/samples/http/curls/index.sh b/go/samples/http/curls/index.sh index 1aaef3ef..c611abe3 100755 --- a/go/samples/http/curls/index.sh +++ b/go/samples/http/curls/index.sh @@ -1,2 +1,4 @@ +# usage: index.sh + curl http://localhost:8080 echo \ No newline at end of file diff --git a/go/samples/http/curls/insert.sh b/go/samples/http/curls/insert.sh index f9d96ac7..57be7805 100755 --- a/go/samples/http/curls/insert.sh +++ b/go/samples/http/curls/insert.sh @@ -1,3 +1,5 @@ +# usage: insert.sh + curl --header "Content-Type: application/json" \ --request POST \ --data '{"task":"'$1'"}' \ diff --git a/go/samples/http/curls/list.sh b/go/samples/http/curls/list.sh index 71739d53..ca8b9d69 100755 --- a/go/samples/http/curls/list.sh +++ b/go/samples/http/curls/list.sh @@ -1,2 +1,4 @@ +# usage: list.sh + curl http://localhost:8080/todos?search=$1 echo \ No newline at end of file diff --git a/go/samples/http/curls/update.sh b/go/samples/http/curls/update.sh index a188ea6e..43a62e03 100755 --- a/go/samples/http/curls/update.sh +++ b/go/samples/http/curls/update.sh @@ -1,3 +1,5 @@ +# usage: update.sh + curl --header "Content-Type: application/json" \ --request PUT \ --data '{"task":"'$2'"}' \ From 756ad5ec9d15eb4a8a1421e68724ec00d229b035 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Thu, 17 Nov 2022 12:15:10 +0530 Subject: [PATCH 058/108] Make the go sample application work with docker compose (#176) * Make the go application work with docker compose. * Updated README.md. * Formatted main.go using gofmt. * Add newlines to few files as recommended by Github. --- go/samples/http/.gitignore | 3 +- go/samples/http/Dockerfile | 28 ++++++++++++ go/samples/http/README.md | 37 +++++++++++----- go/samples/http/curls/delete.sh | 2 +- go/samples/http/curls/index.sh | 2 +- go/samples/http/curls/insert.sh | 2 +- go/samples/http/curls/list.sh | 2 +- go/samples/http/curls/update.sh | 2 +- go/samples/http/docker-compose.yml | 59 ++++++++++++++++++++----- go/samples/http/main.go | 8 ++-- go/samples/http/mysqldb/mysql_driver.go | 4 +- go/samples/http/pgdb/pg_driver.go | 4 +- go/samples/http/tail_mysql_log.sh | 2 +- 13 files changed, 117 insertions(+), 38 deletions(-) create mode 100644 go/samples/http/Dockerfile diff --git a/go/samples/http/.gitignore b/go/samples/http/.gitignore index 353eb76a..9c9ac574 100644 --- a/go/samples/http/.gitignore +++ b/go/samples/http/.gitignore @@ -1,2 +1 @@ -sqlcommenter-http -docker-data/ \ No newline at end of file +docker-data/ diff --git a/go/samples/http/Dockerfile b/go/samples/http/Dockerfile new file mode 100644 index 00000000..092a1a60 --- /dev/null +++ b/go/samples/http/Dockerfile @@ -0,0 +1,28 @@ +# Build Stage +# First pull Golang image +FROM golang:1.19-alpine as build-env + +ENV APP_NAME sqlcommenter-http +ENV CMD_PATH main.go + +# Copy application data into image +COPY . $GOPATH/src/$APP_NAME +WORKDIR $GOPATH/src/$APP_NAME + +# Budild application +RUN CGO_ENABLED=0 go build -v -o /$APP_NAME $GOPATH/src/$APP_NAME/$CMD_PATH + +# Run Stage +FROM alpine:3.16.3 + +# Set environment variable +ENV APP_NAME sqlcommenter-http + +# Copy only required data into this image +COPY --from=build-env /$APP_NAME . + +# Expose application port +EXPOSE 8081 + +# Start app +CMD ["./sqlcommenter-http", "--db_engine=mysql"] diff --git a/go/samples/http/README.md b/go/samples/http/README.md index 6520fd32..c53b814f 100644 --- a/go/samples/http/README.md +++ b/go/samples/http/README.md @@ -1,18 +1,33 @@ # sqlcommenter-http +This is a sample application used to test out `sqlcommenter-go-http` instrumentation libraries. ## Installation +We have containerized this application and its related dependencies (i.e. Postgres and MySQL servers) using `docker-compose`. -* Clone the source -* Update `connection` string in Index function -* Install dependencies - ``` - go build - ``` +To start the application: +```sh +docker compose build +docker compose up +``` -* Run the app - ``` - go run main.go - ```` -* Hit the url http://localhost:8080/ and observe the mysql logs to see comments appended +This will start the application server as well as MySQL and Postgres databases +(NOTE: At present both database will start even if one is used). + +By default the application server will connect with `Postgres` database. To change that, +update the `db_engine` parameter in the [`Dockerfile`](https://github.com/google/sqlcommenter/blob/master/go/samples/http/Dockerfile) to `mysql`. + +To view postgres logs, just use the `docker logs` command: + +```sh +docker logs --follow postgres +``` + +To view MySQL logs, use the provided script `./tail_mysql_log.sh`. + + +## Execution +Hit the url http://localhost:8081/ and observe the MySQL/Postgres logs to see comments appended. + +Alternatively, there are few scripts present in the `curls` folder to execute CRUD operations. diff --git a/go/samples/http/curls/delete.sh b/go/samples/http/curls/delete.sh index f8dd8c0c..d40bbbbe 100755 --- a/go/samples/http/curls/delete.sh +++ b/go/samples/http/curls/delete.sh @@ -2,5 +2,5 @@ curl --header "Content-Type: application/json" \ --request DELETE \ - http://localhost:8080/todos/$1 + http://localhost:8081/todos/$1 echo \ No newline at end of file diff --git a/go/samples/http/curls/index.sh b/go/samples/http/curls/index.sh index c611abe3..93960edf 100755 --- a/go/samples/http/curls/index.sh +++ b/go/samples/http/curls/index.sh @@ -1,4 +1,4 @@ # usage: index.sh -curl http://localhost:8080 +curl http://localhost:8081 echo \ No newline at end of file diff --git a/go/samples/http/curls/insert.sh b/go/samples/http/curls/insert.sh index 57be7805..1581848c 100755 --- a/go/samples/http/curls/insert.sh +++ b/go/samples/http/curls/insert.sh @@ -3,5 +3,5 @@ curl --header "Content-Type: application/json" \ --request POST \ --data '{"task":"'$1'"}' \ - http://localhost:8080/todos + http://localhost:8081/todos echo \ No newline at end of file diff --git a/go/samples/http/curls/list.sh b/go/samples/http/curls/list.sh index ca8b9d69..62164862 100755 --- a/go/samples/http/curls/list.sh +++ b/go/samples/http/curls/list.sh @@ -1,4 +1,4 @@ # usage: list.sh -curl http://localhost:8080/todos?search=$1 +curl http://localhost:8081/todos?search=$1 echo \ No newline at end of file diff --git a/go/samples/http/curls/update.sh b/go/samples/http/curls/update.sh index 43a62e03..ef0d07c3 100755 --- a/go/samples/http/curls/update.sh +++ b/go/samples/http/curls/update.sh @@ -3,5 +3,5 @@ curl --header "Content-Type: application/json" \ --request PUT \ --data '{"task":"'$2'"}' \ - http://localhost:8080/todos/$1 + http://localhost:8081/todos/$1 echo \ No newline at end of file diff --git a/go/samples/http/docker-compose.yml b/go/samples/http/docker-compose.yml index c2846ae0..89bff040 100644 --- a/go/samples/http/docker-compose.yml +++ b/go/samples/http/docker-compose.yml @@ -1,27 +1,62 @@ version: '3.8' +networks: + mynet: + driver: bridge + + services: - sqlcommenter_mysql_db: - container_name: sqlcommenter_mysql_db + mysql: + container_name: mysql image: mysql:8 command: --general-log=TRUE --general-log-file=/var/lib/mysql/mysql-log.log ports: - - '3306:3306' + - 3306:3306 environment: MYSQL_DATABASE: 'sqlcommenter_db' MYSQL_ROOT_PASSWORD: 'password' + healthcheck: + test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - mynet volumes: - - './docker-data/mysql:/var/lib/postgresql/data' - sqlcommenter_pg_db: - container_name: sqlcommenter_pg_db + - './docker-data/mysql:/var/lib/mysql' + postgres: image: postgres:14 + container_name: postgres + # restart: always + volumes: + - './docker-data/postgres:/var/lib/postgresql/data' command: postgres -c log_statement=all ports: - - '5432:5432' + - 5432:5432 environment: - POSTGRES_USER: dev - POSTGRES_PASSWORD: dev - POSTGRES_DB: sqlcommenter_db - volumes: - - './docker-data/pg:/var/lib/postgresql/data' \ No newline at end of file + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + healthcheck: + test: ["CMD-SHELL", "pg_isready -U postgres"] + interval: 10s + timeout: 5s + retries: 5 + networks: + - mynet + http-service: + container_name: http-service + build: + context: . + depends_on: + postgres: + condition: service_healthy + mysql: + condition: service_healthy + links: + - postgres + - mysql + ports: + - 8081:8081 + networks: + - mynet \ No newline at end of file diff --git a/go/samples/http/main.go b/go/samples/http/main.go index 767f3ce7..0032eba1 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -76,11 +76,13 @@ func runApp(todosController *todos.TodosController) { router.PUT("/todos/:id", middleware(todosController.ActionUpdate)) router.DELETE("/todos/:id", middleware(todosController.ActionDelete)) - http.ListenAndServe(":8080", router) + http.ListenAndServe(":8081", router) } +// host = “host.docker.internal” + func runForMysql() *gosql.DB { - connection := "root:password@/sqlcommenter_db" + connection := "root:password@tcp(mysql:3306)/sqlcommenter_db" db := mysqldb.ConnectMySQL(connection) todosController := &todos.TodosController{Engine: "mysql", DB: db, SQL: todos.MySQLQueries{}} runApp(todosController) @@ -88,7 +90,7 @@ func runForMysql() *gosql.DB { } func runForPg() *gosql.DB { - connection := "postgres://dev:dev@localhost/sqlcommenter_db?sslmode=disable" + connection := "host=postgres user=postgres password=postgres dbname=postgres port=5432 sslmode=disable" db := pgdb.ConnectPG(connection) todosController := &todos.TodosController{Engine: "pg", DB: db, SQL: todos.PGQueries{}} runApp(todosController) diff --git a/go/samples/http/mysqldb/mysql_driver.go b/go/samples/http/mysqldb/mysql_driver.go index 2b8da0e5..a5208346 100644 --- a/go/samples/http/mysqldb/mysql_driver.go +++ b/go/samples/http/mysqldb/mysql_driver.go @@ -11,12 +11,12 @@ import ( func ConnectMySQL(connection string) *gosql.DB { db, err := gosql.Open("mysql", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) if err != nil { - log.Fatal(err) + log.Fatalf("Failed to connect to MySQL(%q), error: %v", connection, err) } err = db.Ping() if err != nil { - log.Fatal(err) + log.Fatalf("Failed to ping the database, error: %v", err) } return db diff --git a/go/samples/http/pgdb/pg_driver.go b/go/samples/http/pgdb/pg_driver.go index 18c3972c..13fd6032 100644 --- a/go/samples/http/pgdb/pg_driver.go +++ b/go/samples/http/pgdb/pg_driver.go @@ -11,12 +11,12 @@ import ( func ConnectPG(connection string) *gosql.DB { db, err := gosql.Open("postgres", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) if err != nil { - log.Fatal(err) + log.Fatalf("Failed to connect to PG(%q), error: %v", connection, err) } err = db.Ping() if err != nil { - log.Fatal(err) + log.Fatalf("Failed to ping the database, error: %v", err) } return db diff --git a/go/samples/http/tail_mysql_log.sh b/go/samples/http/tail_mysql_log.sh index ec4346b9..27eb9bfa 100755 --- a/go/samples/http/tail_mysql_log.sh +++ b/go/samples/http/tail_mysql_log.sh @@ -1 +1 @@ -docker exec -it sqlcommenter_mysql_db tail -f /var/lib/mysql/mysql-log.log \ No newline at end of file +docker exec -it mysql tail -f /var/lib/mysql/mysql-log.log From b4a9768d5b272f50369377cd499d72da86c01200 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 18 Nov 2022 11:38:54 +0530 Subject: [PATCH 059/108] minor fix related to garbage collection --- go/samples/http/todos/controller.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index ef2aeb75..c770d298 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -89,6 +89,7 @@ func (c *TodosController) insertTodoPG(ctx context.Context, w http.ResponseWrite writeServerErrorResponse(w, "insert failed") return } + defer rows.Close() if rows.Next() { var todo Todo @@ -129,6 +130,7 @@ func (c *TodosController) insertTodoMySQL(ctx context.Context, w http.ResponseWr writeServerErrorResponse(w, "error in query") return } + defer rows.Close() if rows.Next() { var todo Todo @@ -166,6 +168,7 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p writeServerErrorResponse(w, "error in query") return } + defer rows.Close() if rows.Next() { if err := rows.Scan(&todo.Id, &todo.Task); err != nil { @@ -202,6 +205,7 @@ func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p writeServerErrorResponse(w, "error in query") return } + defer rows.Close() if rows.Next() { if err := rows.Scan(&todo.Id, &todo.Task); err != nil { From 5be250c139b8366c9f4eaabd5a98050612ec47ae Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 18 Nov 2022 11:44:49 +0530 Subject: [PATCH 060/108] added sqlcommenter-http to .gitignore --- go/samples/http/.gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/go/samples/http/.gitignore b/go/samples/http/.gitignore index 9c9ac574..57a5440d 100644 --- a/go/samples/http/.gitignore +++ b/go/samples/http/.gitignore @@ -1 +1,2 @@ docker-data/ +sqlcommenter-http From 75f6487097af4841636b7a338f2c798b8f38ecf8 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Fri, 18 Nov 2022 11:58:12 +0530 Subject: [PATCH 061/108] database type in driver tag --- go/database/sql/go-sql.go | 7 ++++--- go/database/sql/go-sql_test.go | 12 ++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/go/database/sql/go-sql.go b/go/database/sql/go-sql.go index 9742f24e..9c55912f 100644 --- a/go/database/sql/go-sql.go +++ b/go/database/sql/go-sql.go @@ -25,12 +25,13 @@ import ( type DB struct { *sql.DB - options core.CommenterOptions + driverName string + options core.CommenterOptions } func Open(driverName string, dataSourceName string, options core.CommenterOptions) (*DB, error) { db, err := sql.Open(driverName, dataSourceName) - return &DB{DB: db, options: options}, err + return &DB{DB: db, driverName: driverName, options: options}, err } // ***** Query Functions ***** @@ -79,7 +80,7 @@ func (db *DB) withComment(ctx context.Context, query string) string { // `driver` information should not be coming from framework. // So, explicitly adding that here. if db.options.EnableDBDriver { - commentsMap[core.Driver] = "database/sql" + commentsMap[core.Driver] = fmt.Sprintf("database/sql:%s", db.driverName) } if db.options.EnableFramework && (ctx.Value(core.Framework) != nil) { diff --git a/go/database/sql/go-sql_test.go b/go/database/sql/go-sql_test.go index 78c1d5bf..b805d9a9 100644 --- a/go/database/sql/go-sql_test.go +++ b/go/database/sql/go-sql_test.go @@ -32,7 +32,7 @@ func TestDisabled(t *testing.T) { if err != nil { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - db := DB{DB: mockDB, options: core.CommenterOptions{}} + db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{}} query := "SELECT 2" if got, want := db.withComment(context.Background(), query), query; got != want { t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) @@ -45,7 +45,7 @@ func TestHTTP_Net(t *testing.T) { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - db := DB{DB: mockDB, options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} + db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} r, err := http.NewRequest("GET", "hello/1", nil) if err != nil { t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) @@ -53,7 +53,7 @@ func TestHTTP_Net(t *testing.T) { ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) got := db.withComment(ctx, "Select 1") - want := "Select 1/*driver=database%2Fsql,framework=net%2Fhttp,route=hello%2F1*/" + want := "Select 1/*driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" if got != want { t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) } @@ -65,9 +65,9 @@ func TestQueryWithSemicolon(t *testing.T) { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - db := DB{DB: mockDB, options: core.CommenterOptions{EnableDBDriver: true}} + db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true}} got := db.withComment(context.Background(), "Select 1;") - want := "Select 1/*driver=database%2Fsql*/;" + want := "Select 1/*driver=database%2Fsql%3Amocksql*/;" if got != want { t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) } @@ -79,7 +79,7 @@ func TestOtelIntegration(t *testing.T) { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - db := DB{DB: mockDB, options: core.CommenterOptions{EnableTraceparent: true}} + db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableTraceparent: true}} exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod tp := sdktrace.NewTracerProvider( From 12bbed0b17f9a5e8031b4c38b14e22849776a5a6 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Sun, 20 Nov 2022 18:59:56 +0530 Subject: [PATCH 062/108] application working using gorrila/mux --- go/samples/http/go.mod | 16 +++++++++++----- go/samples/http/go.sum | 15 +++++++++++++++ go/samples/http/main.go | 29 ++++++++++++++--------------- go/samples/http/todos/controller.go | 16 +++++++++------- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index 62c7f725..665160e3 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -4,14 +4,20 @@ go 1.19 require ( github.com/go-sql-driver/mysql v1.6.0 - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 - go.opentelemetry.io/otel/sdk v1.10.0 + go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.1 + go.opentelemetry.io/otel/sdk v1.11.1 ) require ( - github.com/julienschmidt/httprouter v1.3.0 + github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/gorilla/mux v1.8.0 // indirect + go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4 // indirect +) + +require ( + github.com/julienschmidt/httprouter v1.3.0 github.com/lib/pq v1.10.7 - go.opentelemetry.io/otel v1.10.0 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect ) require ( @@ -20,6 +26,6 @@ require ( github.com/google/sqlcommenter/go/core v0.0.1-beta github.com/google/sqlcommenter/go/database/sql v0.0.1-beta github.com/google/sqlcommenter/go/net/http v0.0.1-beta - go.opentelemetry.io/otel/trace v1.10.0 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect ) diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum index 35d728c6..00b35900 100644 --- a/go/samples/http/go.sum +++ b/go/samples/http/go.sum @@ -1,5 +1,7 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= +github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -8,26 +10,39 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= github.com/google/sqlcommenter/go/database/sql v0.0.1-beta h1:N680pEYaRwmOSrQWUd4A4aD4kj4WYxcJTQB9WLe69vY= github.com/google/sqlcommenter/go/database/sql v0.0.1-beta/go.mod h1:VdswmF4SM0cbjJdD+3GyM5QuXpHhH6F5nSzcbikzCGY= github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4 h1:gn5Cf5XpnENThRBjAHq6vuENFo+l9qwnEMqwmanIYuY= +go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4/go.mod h1:f26RulijcxdgrGSYep0AykXM9ZkWoKVtInstDYUR8EU= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.1 h1:3Yvzs7lgOw8MmbxmLRsQGwYdCubFmUHSooKaEhQunFQ= +go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.1/go.mod h1:pyHDt0YlyuENkD2VwHsiRDf+5DfI3EH7pfhUYW6sQUE= go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= +go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= +go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/go/samples/http/main.go b/go/samples/http/main.go index 0032eba1..1a5d328a 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -9,7 +9,7 @@ import ( "github.com/google/sqlcommenter/go/core" gosql "github.com/google/sqlcommenter/go/database/sql" httpnet "github.com/google/sqlcommenter/go/net/http" - "github.com/julienschmidt/httprouter" + "github.com/gorilla/mux" "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" sdktrace "go.opentelemetry.io/otel/sdk/trace" @@ -18,8 +18,8 @@ import ( "sqlcommenter-http/todos" ) -func MakeIndexRoute(db *gosql.DB) func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { - return func(w http.ResponseWriter, r *http.Request, _ httprouter.Params) { +func MakeIndexRoute(db *gosql.DB) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod tp := sdktrace.NewTracerProvider( @@ -52,11 +52,11 @@ func MakeIndexRoute(db *gosql.DB) func(w http.ResponseWriter, r *http.Request, _ } // middleware is used to intercept incoming HTTP calls and apply general functions upon them. -func middleware(next httprouter.Handle) httprouter.Handle { - return func(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func middleware(next func(http.ResponseWriter, *http.Request)) func(w http.ResponseWriter, r *http.Request) { + return func(w http.ResponseWriter, r *http.Request) { ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, next)) - log.Printf("HTTP request sent to %s from %v", r.URL.Path, next) - next(w, r.WithContext(ctx), p) + log.Printf("HTTP request sent to %s", r.URL.Path) + next(w, r.WithContext(ctx)) } } @@ -66,17 +66,16 @@ func runApp(todosController *todos.TodosController) { log.Fatal(err) } - router := httprouter.New() + r := mux.NewRouter() index := MakeIndexRoute(todosController.DB) - router.GET("/", middleware(index)) + r.HandleFunc("/", middleware(index)).Methods("GET") + r.HandleFunc("/todos", middleware(todosController.ActionList)).Methods("GET") + r.HandleFunc("/todos", middleware(todosController.ActionInsert)).Methods("POST") + r.HandleFunc("/todos/{id}", middleware(todosController.ActionUpdate)).Methods("PUT") + r.HandleFunc("/todos/{id}", middleware(todosController.ActionDelete)).Methods("DELETE") - router.GET("/todos", middleware(todosController.ActionList)) - router.POST("/todos", middleware(todosController.ActionInsert)) - router.PUT("/todos/:id", middleware(todosController.ActionUpdate)) - router.DELETE("/todos/:id", middleware(todosController.ActionDelete)) - - http.ListenAndServe(":8081", router) + http.ListenAndServe(":8081", r) } // host = “host.docker.internal” diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index c770d298..0f1e832c 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -8,7 +8,7 @@ import ( "net/http" gosql "github.com/google/sqlcommenter/go/database/sql" - "github.com/julienschmidt/httprouter" + "github.com/gorilla/mux" ) type Todo struct { @@ -31,7 +31,7 @@ func (c *TodosController) CreateTodosTableIfNotExists() error { return err } -func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request) { ctx := r.Context() query := r.URL.Query() @@ -62,7 +62,7 @@ func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request, p h writeJsonResponse(w, res) } -func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func (c *TodosController) ActionInsert(w http.ResponseWriter, r *http.Request) { ctx := r.Context() var dto TodoDTO @@ -149,9 +149,10 @@ func (c *TodosController) insertTodoMySQL(ctx context.Context, w http.ResponseWr } } -func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - id := p.ByName("id") + vars := mux.Vars(r) + id := vars["id"] var dto TodoDTO err := json.NewDecoder(r.Body).Decode(&dto) @@ -194,9 +195,10 @@ func (c *TodosController) ActionUpdate(w http.ResponseWriter, r *http.Request, p writeJsonResponse(w, res) } -func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request, p httprouter.Params) { +func (c *TodosController) ActionDelete(w http.ResponseWriter, r *http.Request) { ctx := r.Context() - id := p.ByName("id") + vars := mux.Vars(r) + id := vars["id"] var todo Todo rows, err := c.DB.QueryContext(ctx, c.SQL.TodoById(), id) From 5359d8c899c68619cc88215359a5bc4d8b6c776c Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Sun, 20 Nov 2022 19:20:49 +0530 Subject: [PATCH 063/108] traceparent functionality working example --- .../http/curls/update_with_traceparent.sh | 8 ++ go/samples/http/go.mod | 6 +- go/samples/http/main.go | 87 +++++++++---------- 3 files changed, 51 insertions(+), 50 deletions(-) create mode 100755 go/samples/http/curls/update_with_traceparent.sh diff --git a/go/samples/http/curls/update_with_traceparent.sh b/go/samples/http/curls/update_with_traceparent.sh new file mode 100755 index 00000000..40b0d6bc --- /dev/null +++ b/go/samples/http/curls/update_with_traceparent.sh @@ -0,0 +1,8 @@ +# usage: update.sh + +curl --header "Content-Type: application/json" \ + --header "Traceparent: 00-a7586e0a5bc7934ce028e83bc1d247f2-6b94506168fc7803-01" \ + --request PUT \ + --data '{"task":"'$2'"}' \ + http://localhost:8081/todos/$1 +echo \ No newline at end of file diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index 665160e3..b7a47067 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -10,14 +10,14 @@ require ( require ( github.com/felixge/httpsnoop v1.0.3 // indirect - github.com/gorilla/mux v1.8.0 // indirect - go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4 // indirect + github.com/gorilla/mux v1.8.0 + go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4 ) require ( github.com/julienschmidt/httprouter v1.3.0 github.com/lib/pq v1.10.7 - go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel v1.11.1 ) require ( diff --git a/go/samples/http/main.go b/go/samples/http/main.go index 1a5d328a..b7d426eb 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -1,8 +1,8 @@ package main import ( + "context" "flag" - "fmt" "log" "net/http" @@ -10,7 +10,10 @@ import ( gosql "github.com/google/sqlcommenter/go/database/sql" httpnet "github.com/google/sqlcommenter/go/net/http" "github.com/gorilla/mux" - "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" + "go.opentelemetry.io/otel" + stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/otel/propagation" sdktrace "go.opentelemetry.io/otel/sdk/trace" "sqlcommenter-http/mysqldb" @@ -18,46 +21,13 @@ import ( "sqlcommenter-http/todos" ) -func MakeIndexRoute(db *gosql.DB) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) - bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSpanProcessor(bsp), - ) - - ctx, span := tp.Tracer("foo").Start(r.Context(), "parent-span-name") - defer span.End() - - db.ExecContext(ctx, "Select 1") - db.Exec("Select 2") - - stmt1, err := db.Prepare("Select 3") - if err != nil { - log.Fatal(err) - } - stmt1.QueryRow() - - stmt2, err := db.PrepareContext(ctx, "Select 4") - if err != nil { - log.Fatal(err) - } - stmt2.QueryRow() - - db.QueryContext(ctx, "Select 5") - - fmt.Fprintf(w, "Hello World!\r\n") - } -} - // middleware is used to intercept incoming HTTP calls and apply general functions upon them. -func middleware(next func(http.ResponseWriter, *http.Request)) func(w http.ResponseWriter, r *http.Request) { - return func(w http.ResponseWriter, r *http.Request) { - ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, next)) +func middleware(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, h)) log.Printf("HTTP request sent to %s", r.URL.Path) - next(w, r.WithContext(ctx)) - } + h.ServeHTTP(w, r.WithContext(ctx)) + }) } func runApp(todosController *todos.TodosController) { @@ -66,16 +36,25 @@ func runApp(todosController *todos.TodosController) { log.Fatal(err) } + tp, err := initTracer() + if err != nil { + log.Fatal(err) + } + defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) + } + }() + r := mux.NewRouter() + r.Use(otelmux.Middleware("sqlcommenter sample-server")) - index := MakeIndexRoute(todosController.DB) - r.HandleFunc("/", middleware(index)).Methods("GET") - r.HandleFunc("/todos", middleware(todosController.ActionList)).Methods("GET") - r.HandleFunc("/todos", middleware(todosController.ActionInsert)).Methods("POST") - r.HandleFunc("/todos/{id}", middleware(todosController.ActionUpdate)).Methods("PUT") - r.HandleFunc("/todos/{id}", middleware(todosController.ActionDelete)).Methods("DELETE") + r.HandleFunc("/todos", todosController.ActionList).Methods("GET") + r.HandleFunc("/todos", todosController.ActionInsert).Methods("POST") + r.HandleFunc("/todos/{id}", todosController.ActionUpdate).Methods("PUT") + r.HandleFunc("/todos/{id}", todosController.ActionDelete).Methods("DELETE") - http.ListenAndServe(":8081", r) + http.ListenAndServe(":8081", middleware(r)) } // host = “host.docker.internal” @@ -96,6 +75,20 @@ func runForPg() *gosql.DB { return db } +func initTracer() (*sdktrace.TracerProvider, error) { + exporter, err := stdout.New(stdout.WithPrettyPrint()) + if err != nil { + return nil, err + } + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithBatcher(exporter), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + return tp, nil +} + func main() { var engine string From b077be0028c36d8a49ed0ee9449a2f4189cc0c6c Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 12:17:35 +0530 Subject: [PATCH 064/108] changed docblock for update_with_traceparent.sh curl --- go/samples/http/curls/update_with_traceparent.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/samples/http/curls/update_with_traceparent.sh b/go/samples/http/curls/update_with_traceparent.sh index 40b0d6bc..e59c87a2 100755 --- a/go/samples/http/curls/update_with_traceparent.sh +++ b/go/samples/http/curls/update_with_traceparent.sh @@ -1,4 +1,4 @@ -# usage: update.sh +# usage: update_with_traceparent.sh curl --header "Content-Type: application/json" \ --header "Traceparent: 00-a7586e0a5bc7934ce028e83bc1d247f2-6b94506168fc7803-01" \ From 60c4ead36216388b94256e3f3b8d90275c029d33 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 18:53:43 +0530 Subject: [PATCH 065/108] db_driver tag fix and application tag related changes: --- go/core/core.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/go/core/core.go b/go/core/core.go index 65bf7194..9d1077ad 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -31,8 +31,9 @@ const ( Controller string = "controller" Action string = "action" Framework string = "framework" - Driver string = "driver" + Driver string = "db_driver" Traceparent string = "traceparent" + Application string = "application" ) type CommenterOptions struct { @@ -42,6 +43,8 @@ type CommenterOptions struct { EnableController bool EnableAction bool EnableTraceparent bool + EnableApplication bool + Application string } func encodeURL(k string) string { From 545986d328de10689968dd801326d9a0b42e7ca8 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:08:51 +0530 Subject: [PATCH 066/108] bumped go/net/http dep on go/core to v0.0.2-beta --- go/net/http/go.mod | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/net/http/go.mod b/go/net/http/go.mod index 42d8dd79..8d89e30f 100644 --- a/go/net/http/go.mod +++ b/go/net/http/go.mod @@ -2,7 +2,7 @@ module github.com/google/sqlcommenter/go/net/http go 1.19 -require github.com/google/sqlcommenter/go/core v0.0.1-beta +require github.com/google/sqlcommenter/go/core v0.0.2-beta require ( go.opentelemetry.io/otel v1.10.0 // indirect From 63b2899a14b9c76f50742842dd5e03ac6c762f50 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:19:30 +0530 Subject: [PATCH 067/108] update to go.mod & go.sum --- go/net/http/go.mod | 4 ++-- go/net/http/go.sum | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go/net/http/go.mod b/go/net/http/go.mod index 8d89e30f..c0997822 100644 --- a/go/net/http/go.mod +++ b/go/net/http/go.mod @@ -5,6 +5,6 @@ go 1.19 require github.com/google/sqlcommenter/go/core v0.0.2-beta require ( - go.opentelemetry.io/otel v1.10.0 // indirect - go.opentelemetry.io/otel/trace v1.10.0 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect ) diff --git a/go/net/http/go.sum b/go/net/http/go.sum index c0518c2b..33b96be6 100644 --- a/go/net/http/go.sum +++ b/go/net/http/go.sum @@ -4,10 +4,16 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= +github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From 7459a031be970ee67ee326e11f5e4bcbbe66fdad Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:18:15 +0530 Subject: [PATCH 068/108] wip --- go/database/sql/go-sql.go | 24 +++++++++++++++++++++--- go/database/sql/go-sql_test.go | 6 +++--- go/database/sql/go.mod | 4 ++-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/go/database/sql/go-sql.go b/go/database/sql/go-sql.go index 9c55912f..f0143789 100644 --- a/go/database/sql/go-sql.go +++ b/go/database/sql/go-sql.go @@ -18,20 +18,24 @@ import ( "context" "database/sql" "fmt" + "runtime/debug" "strings" "github.com/google/sqlcommenter/go/core" ) +var attemptedToAutosetApplication = false + type DB struct { *sql.DB - driverName string - options core.CommenterOptions + driverName string + options core.CommenterOptions + application string } func Open(driverName string, dataSourceName string, options core.CommenterOptions) (*DB, error) { db, err := sql.Open(driverName, dataSourceName) - return &DB{DB: db, driverName: driverName, options: options}, err + return &DB{DB: db, driverName: driverName, options: options, application: options.Application}, err } // ***** Query Functions ***** @@ -91,6 +95,20 @@ func (db *DB) withComment(ctx context.Context, query string) string { commentsMap[core.Route] = ctx.Value(core.Route).(string) } + if db.options.EnableApplication { + if !attemptedToAutosetApplication && db.application == "" { + attemptedToAutosetApplication = true + bi, ok := debug.ReadBuildInfo() + if ok { + db.application = bi.Path + } else { + db.application = "" + } + } + + commentsMap[core.Application] = db.application + } + if db.options.EnableTraceparent { carrier := core.ExtractTraceparent(ctx) if val, ok := carrier["traceparent"]; ok { diff --git a/go/database/sql/go-sql_test.go b/go/database/sql/go-sql_test.go index b805d9a9..7398a26d 100644 --- a/go/database/sql/go-sql_test.go +++ b/go/database/sql/go-sql_test.go @@ -45,7 +45,7 @@ func TestHTTP_Net(t *testing.T) { t.Fatalf("MockSQL failed with unexpected error: %s", err) } - db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true}} + db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true, EnableApplication: true, Application: "app"}, application: "app"} r, err := http.NewRequest("GET", "hello/1", nil) if err != nil { t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) @@ -53,7 +53,7 @@ func TestHTTP_Net(t *testing.T) { ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) got := db.withComment(ctx, "Select 1") - want := "Select 1/*driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" + want := "Select 1/*application=app,db_driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" if got != want { t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) } @@ -67,7 +67,7 @@ func TestQueryWithSemicolon(t *testing.T) { db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true}} got := db.withComment(context.Background(), "Select 1;") - want := "Select 1/*driver=database%2Fsql%3Amocksql*/;" + want := "Select 1/*db_driver=database%2Fsql%3Amocksql*/;" if got != want { t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) } diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index 681d531f..97d69b86 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -3,7 +3,7 @@ module github.com/google/sqlcommenter/go/database/sql go 1.19 require ( - github.com/google/sqlcommenter/go/core v0.0.1-beta + github.com/google/sqlcommenter/go/core v0.0.2-beta go.opentelemetry.io/otel/sdk v1.10.0 ) @@ -16,7 +16,7 @@ require ( require ( github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/google/sqlcommenter/go/net/http v0.0.1-beta + github.com/google/sqlcommenter/go/net/http v0.0.2-beta go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 go.opentelemetry.io/otel/trace v1.10.0 // indirect ) From 6c94180323d49975752d9b7101834f5a4aa1f9f1 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:30:31 +0530 Subject: [PATCH 069/108] db-driver tag change, application tag support with auto-initialization --- go/database/sql/go.mod | 4 ++-- go/database/sql/go.sum | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index 97d69b86..494e8554 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -10,7 +10,7 @@ require ( require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - go.opentelemetry.io/otel v1.10.0 // indirect + go.opentelemetry.io/otel v1.11.1 // indirect golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect ) @@ -18,5 +18,5 @@ require ( github.com/DATA-DOG/go-sqlmock v1.5.0 github.com/google/sqlcommenter/go/net/http v0.0.2-beta go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 - go.opentelemetry.io/otel/trace v1.10.0 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect ) diff --git a/go/database/sql/go.sum b/go/database/sql/go.sum index 8db643f7..4d587756 100644 --- a/go/database/sql/go.sum +++ b/go/database/sql/go.sum @@ -9,18 +9,26 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= +github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/google/sqlcommenter/go/net/http v0.0.2-beta h1:hL/nLxgWeM+2A7yKPoqhyJeaqQZI12kbruQ6/IEiErM= +github.com/google/sqlcommenter/go/net/http v0.0.2-beta/go.mod h1:1sd6t92iCHaNQc/v5qxTHp+td7KNoD8IIeG4BRetFZo= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From dcf70f444a4d6d4c55913a02382a426d38170968 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:34:33 +0530 Subject: [PATCH 070/108] updated readme --- go/database/sql/README.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/go/database/sql/README.md b/go/database/sql/README.md index f8aeb1e2..53ca1183 100644 --- a/go/database/sql/README.md +++ b/go/database/sql/README.md @@ -34,14 +34,18 @@ Users are given control over what tags they want to append by using `core.Commen ```go type CommenterOptions struct { EnableDBDriver bool - EnableTraceparent bool // OpenTelemetry trace information - EnableRoute bool // applicable for web frameworks - EnableFramework bool // applicable for web frameworks - EnableController bool // applicable for web frameworks - EnableAction bool // applicable for web frameworks + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + EnableApplication bool // applicable for web frameworks + Application string // user-provided application-name. not required } ``` +The driver will try to use the module-name from the project's `go.mod` as the application name if `EnableApplication` is `true` and no `Application` string is provided (works correctly for compiled go applications). + ### Framework Supported * [http/net](.../../../http-net/README.md) From 050d742680451cebec0ec3499a40f91a2b99dca5 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 21 Nov 2022 19:45:59 +0530 Subject: [PATCH 071/108] readme change and re-order of commentsMap buildiing in go-sql.go --- go/database/sql/README.md | 2 +- go/database/sql/go-sql.go | 16 +++++++--------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/go/database/sql/README.md b/go/database/sql/README.md index 53ca1183..1a3d71dc 100644 --- a/go/database/sql/README.md +++ b/go/database/sql/README.md @@ -40,7 +40,7 @@ type CommenterOptions struct { EnableController bool // applicable for web frameworks EnableAction bool // applicable for web frameworks EnableApplication bool // applicable for web frameworks - Application string // user-provided application-name. not required + Application string // user-provided application-name. optional } ``` diff --git a/go/database/sql/go-sql.go b/go/database/sql/go-sql.go index f0143789..5637b513 100644 --- a/go/database/sql/go-sql.go +++ b/go/database/sql/go-sql.go @@ -95,27 +95,25 @@ func (db *DB) withComment(ctx context.Context, query string) string { commentsMap[core.Route] = ctx.Value(core.Route).(string) } + if db.options.EnableTraceparent { + carrier := core.ExtractTraceparent(ctx) + if val, ok := carrier["traceparent"]; ok { + commentsMap[core.Traceparent] = val + } + } + if db.options.EnableApplication { if !attemptedToAutosetApplication && db.application == "" { attemptedToAutosetApplication = true bi, ok := debug.ReadBuildInfo() if ok { db.application = bi.Path - } else { - db.application = "" } } commentsMap[core.Application] = db.application } - if db.options.EnableTraceparent { - carrier := core.ExtractTraceparent(ctx) - if val, ok := carrier["traceparent"]; ok { - commentsMap[core.Traceparent] = val - } - } - var commentsString string = "" if len(commentsMap) > 0 { // Converts comments map to string and appends it to query commentsString = fmt.Sprintf("/*%s*/", core.ConvertMapToComment(commentsMap)) From 717fd59d6c03383901cf65d85d21831ea2c46c4f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Tue, 22 Nov 2022 21:59:37 +0530 Subject: [PATCH 072/108] RequestTags interface --- go/core/README.md | 14 ++++++++------ go/core/core.go | 4 ++-- go/core/go.mod | 4 ++-- go/core/go.sum | 4 ++++ 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/go/core/README.md b/go/core/README.md index 326bc3b7..5406a38b 100644 --- a/go/core/README.md +++ b/go/core/README.md @@ -17,12 +17,14 @@ Users are given control over what tags they want to append by using `core.Commen ```go type CommenterOptions struct { EnableDBDriver bool - EnableTraceparent bool // OpenTelemetry trace information - EnableRoute bool // applicable for web frameworks - EnableFramework bool // applicable for web frameworks - EnableController bool // applicable for web frameworks - EnableAction bool // applicable for web frameworks - } + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + EnableApplication bool + Application string // user-provided application-name. optional +} ``` diff --git a/go/core/core.go b/go/core/core.go index 9d1077ad..1d5ab920 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -88,13 +88,13 @@ func ExtractTraceparent(ctx context.Context) propagation.MapCarrier { return carrier } -type RequestExtractor interface { +type RequestTags interface { Route() string Action() string Framework() string } -func ContextInject(ctx context.Context, h RequestExtractor) context.Context { +func ContextInject(ctx context.Context, h RequestTags) context.Context { ctx = context.WithValue(ctx, Route, h.Route()) ctx = context.WithValue(ctx, Action, h.Action()) ctx = context.WithValue(ctx, Framework, h.Framework()) diff --git a/go/core/go.mod b/go/core/go.mod index 0cb7633c..65ff5bc4 100644 --- a/go/core/go.mod +++ b/go/core/go.mod @@ -2,6 +2,6 @@ module github.com/google/sqlcommenter/go/core go 1.19 -require go.opentelemetry.io/otel v1.10.0 +require go.opentelemetry.io/otel v1.11.1 -require go.opentelemetry.io/otel/trace v1.10.0 // indirect +require go.opentelemetry.io/otel/trace v1.11.1 // indirect diff --git a/go/core/go.sum b/go/core/go.sum index c9ab1f94..1dd73c61 100644 --- a/go/core/go.sum +++ b/go/core/go.sum @@ -6,6 +6,10 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= From 89145a83843bbdbd971dd5916e2b9e48f6dffa21 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Tue, 22 Nov 2022 23:35:22 +0530 Subject: [PATCH 073/108] RequestTags interface -> RequestTagsProvider interface --- go/core/core.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/go/core/core.go b/go/core/core.go index 1d5ab920..25ce2dd6 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -88,13 +88,13 @@ func ExtractTraceparent(ctx context.Context) propagation.MapCarrier { return carrier } -type RequestTags interface { +type RequestTagsProvider interface { Route() string Action() string Framework() string } -func ContextInject(ctx context.Context, h RequestTags) context.Context { +func ContextInject(ctx context.Context, h RequestTagsProvider) context.Context { ctx = context.WithValue(ctx, Route, h.Route()) ctx = context.WithValue(ctx, Action, h.Action()) ctx = context.WithValue(ctx, Framework, h.Framework()) From 7e7d04f802968688463fbbc7c392fdfe26baff50 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 11:11:10 +0530 Subject: [PATCH 074/108] added test, simpplified the impl to just a struct --- go/net/http/go.mod | 7 ------- go/net/http/go.sum | 19 ------------------- go/net/http/http.go | 29 ++++++++++++----------------- go/net/http/http_test.go | 19 +++++++++++++++++++ 4 files changed, 31 insertions(+), 43 deletions(-) create mode 100644 go/net/http/http_test.go diff --git a/go/net/http/go.mod b/go/net/http/go.mod index c0997822..23fe3fb7 100644 --- a/go/net/http/go.mod +++ b/go/net/http/go.mod @@ -1,10 +1,3 @@ module github.com/google/sqlcommenter/go/net/http go 1.19 - -require github.com/google/sqlcommenter/go/core v0.0.2-beta - -require ( - go.opentelemetry.io/otel v1.11.1 // indirect - go.opentelemetry.io/otel/trace v1.11.1 // indirect -) diff --git a/go/net/http/go.sum b/go/net/http/go.sum index 33b96be6..e69de29b 100644 --- a/go/net/http/go.sum +++ b/go/net/http/go.sum @@ -1,19 +0,0 @@ -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= -github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= -github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= -github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= -go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= -go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= -go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= -go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= diff --git a/go/net/http/http.go b/go/net/http/http.go index 5d762687..0644471e 100644 --- a/go/net/http/http.go +++ b/go/net/http/http.go @@ -14,29 +14,24 @@ package http -import ( - "net/http" - - "github.com/google/sqlcommenter/go/core" -) - -type HTTPRequestExtractor struct { - r *http.Request - next any +type HTTPRequestTags struct { + framework string + route string + action string } -func NewHTTPRequestExtractor(r *http.Request, next any) *HTTPRequestExtractor { - return &HTTPRequestExtractor{r, next} +func NewHTTPRequestTags(framework, route, action string) *HTTPRequestTags { + return &HTTPRequestTags{framework, route, action} } -func (h *HTTPRequestExtractor) Route() string { - return h.r.URL.Path +func (h *HTTPRequestTags) Route() string { + return h.route } -func (h *HTTPRequestExtractor) Action() string { - return core.GetFunctionName(h.next) +func (h *HTTPRequestTags) Action() string { + return h.action } -func (h *HTTPRequestExtractor) Framework() string { - return "net/http" +func (h *HTTPRequestTags) Framework() string { + return h.framework } diff --git a/go/net/http/http_test.go b/go/net/http/http_test.go new file mode 100644 index 00000000..003f5591 --- /dev/null +++ b/go/net/http/http_test.go @@ -0,0 +1,19 @@ +package http + +import "testing" + +func TestNewHTTPRequestTags(t *testing.T) { + rt := NewHTTPRequestTags("f", "r", "a") + + if rt.framework != "f" { + t.Errorf("rt.framework - got: %s, want: %s", rt.framework, "f") + } + + if rt.route != "r" { + t.Errorf("rt.route - got: %s, want: %s", rt.route, "r") + } + + if rt.action != "a" { + t.Errorf("rt.action - got: %s, want: %s", rt.action, "r") + } +} From eb0e19c08558c2ed75e8e29413a04470a7ba4bdd Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 11:30:26 +0530 Subject: [PATCH 075/108] Update the CommenterOptions struct (#190) --- go/core/core.go | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/go/core/core.go b/go/core/core.go index 25ce2dd6..1c36ea92 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -36,7 +36,17 @@ const ( Application string = "application" ) -type CommenterOptions struct { +const ( + Route string = "route" + Controller string = "controller" + Action string = "action" + Framework string = "framework" + Driver string = "db_driver" + Traceparent string = "traceparent" + Application string = "application" +) + +type CommenterConfig struct { EnableDBDriver bool EnableRoute bool EnableFramework bool @@ -44,7 +54,16 @@ type CommenterOptions struct { EnableAction bool EnableTraceparent bool EnableApplication bool - Application string +} + +type StaticTags struct { + Application string + DriverName string +} + +type CommenterOptions struct { + Config CommenterConfig + Tags StaticTags } func encodeURL(k string) string { From 743b18ce6d2779aae5a2ee211456a4b05cac771b Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 11:51:40 +0530 Subject: [PATCH 076/108] Commenter core (#191) * Update the CommenterOptions struct * Fix bad commit --- go/core/core.go | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/go/core/core.go b/go/core/core.go index 1c36ea92..6fca682a 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -36,16 +36,6 @@ const ( Application string = "application" ) -const ( - Route string = "route" - Controller string = "controller" - Action string = "action" - Framework string = "framework" - Driver string = "db_driver" - Traceparent string = "traceparent" - Application string = "application" -) - type CommenterConfig struct { EnableDBDriver bool EnableRoute bool From 443b1b32ed84f3571284e650314f258479fefd77 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 12:13:21 +0530 Subject: [PATCH 077/108] Update go sql to as a driver --- go/database/sql/connection.go | 126 ++++++++++++++++++++++++++++++++ go/database/sql/go-sql.go | 130 --------------------------------- go/database/sql/go-sql_test.go | 101 ------------------------- go/database/sql/go.mod | 4 +- go/database/sql/go.sum | 4 + go/database/sql/gosql.go | 120 ++++++++++++++++++++++++++++++ go/database/sql/gosql_test.go | 101 +++++++++++++++++++++++++ 7 files changed, 353 insertions(+), 233 deletions(-) create mode 100644 go/database/sql/connection.go delete mode 100644 go/database/sql/go-sql.go delete mode 100644 go/database/sql/go-sql_test.go create mode 100644 go/database/sql/gosql.go create mode 100644 go/database/sql/gosql_test.go diff --git a/go/database/sql/connection.go b/go/database/sql/connection.go new file mode 100644 index 00000000..7c9197e9 --- /dev/null +++ b/go/database/sql/connection.go @@ -0,0 +1,126 @@ +package sql + +import ( + "context" + "database/sql/driver" + "fmt" + "runtime/debug" + "strings" + + "github.com/google/sqlcommenter/go/core" +) + +var attemptedToAutosetApplication = false + +type sqlCommenterConn struct { + driver.Conn + options core.CommenterOptions +} + +func newSQLCommenterConn(conn driver.Conn, options core.CommenterOptions) *sqlCommenterConn { + return &sqlCommenterConn{ + Conn: conn, + options: options, + } +} + +func (s *sqlCommenterConn) Query(query string, args []driver.Value) (driver.Rows, error) { + queryer, ok := s.Conn.(driver.Queryer) + if !ok { + return nil, driver.ErrSkip + } + ctx := context.Background() + extendedQuery := s.withComment(ctx, query) + return queryer.Query(extendedQuery, args) +} + +func (s *sqlCommenterConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { + queryer, ok := s.Conn.(driver.QueryerContext) + if !ok { + return nil, driver.ErrSkip + } + extendedQuery := s.withComment(ctx, query) + return queryer.QueryContext(ctx, extendedQuery, args) +} + +func (s *sqlCommenterConn) Exec(query string, args []driver.Value) (driver.Result, error) { + execor, ok := s.Conn.(driver.Execer) + if !ok { + return nil, driver.ErrSkip + } + ctx := context.Background() + extendedQuery := s.withComment(ctx, query) + return execor.Exec(extendedQuery, args) +} + +func (s *sqlCommenterConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { + execor, ok := s.Conn.(driver.ExecerContext) + if !ok { + return nil, driver.ErrSkip + } + extendedQuery := s.withComment(ctx, query) + return execor.ExecContext(ctx, extendedQuery, args) +} + +func (s *sqlCommenterConn) Raw() driver.Conn { + return s.Conn +} + +// ***** Commenter Functions ***** + +func (conn *sqlCommenterConn) withComment(ctx context.Context, query string) string { + var commentsMap = map[string]string{} + query = strings.TrimSpace(query) + config := conn.options.Config + + // Sorted alphabetically + if config.EnableAction && (ctx.Value(core.Action) != nil) { + commentsMap[core.Action] = ctx.Value(core.Action).(string) + } + + // `driver` information should not be coming from framework. + // So, explicitly adding that here. + if config.EnableDBDriver { + commentsMap[core.Driver] = fmt.Sprintf("database/sql:%s", conn.options.Tags.DriverName) + } + + if config.EnableFramework && (ctx.Value(core.Framework) != nil) { + commentsMap[core.Framework] = ctx.Value(core.Framework).(string) + } + + if config.EnableRoute && (ctx.Value(core.Route) != nil) { + commentsMap[core.Route] = ctx.Value(core.Route).(string) + } + + if config.EnableTraceparent { + carrier := core.ExtractTraceparent(ctx) + if val, ok := carrier["traceparent"]; ok { + commentsMap[core.Traceparent] = val + } + } + + if config.EnableApplication { + if !attemptedToAutosetApplication && conn.options.Tags.Application == "" { + attemptedToAutosetApplication = true + bi, ok := debug.ReadBuildInfo() + if ok { + conn.options.Tags.Application = bi.Path + } + } + commentsMap[core.Application] = conn.options.Tags.Application + } + + var commentsString string = "" + if len(commentsMap) > 0 { // Converts comments map to string and appends it to query + commentsString = fmt.Sprintf("/*%s*/", core.ConvertMapToComment(commentsMap)) + } + + // A semicolon at the end of the SQL statement means the query ends there. + // We need to insert the comment before that to be considered as part of the SQL statemtent. + if query[len(query)-1:] == ";" { + return fmt.Sprintf("%s%s;", strings.TrimSuffix(query, ";"), commentsString) + } + return fmt.Sprintf("%s%s", query, commentsString) +} + +// ***** Commenter Functions ***** diff --git a/go/database/sql/go-sql.go b/go/database/sql/go-sql.go deleted file mode 100644 index 5637b513..00000000 --- a/go/database/sql/go-sql.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sql - -import ( - "context" - "database/sql" - "fmt" - "runtime/debug" - "strings" - - "github.com/google/sqlcommenter/go/core" -) - -var attemptedToAutosetApplication = false - -type DB struct { - *sql.DB - driverName string - options core.CommenterOptions - application string -} - -func Open(driverName string, dataSourceName string, options core.CommenterOptions) (*DB, error) { - db, err := sql.Open(driverName, dataSourceName) - return &DB{DB: db, driverName: driverName, options: options, application: options.Application}, err -} - -// ***** Query Functions ***** - -func (db *DB) Query(query string, args ...any) (*sql.Rows, error) { - return db.DB.Query(db.withComment(context.Background(), query), args...) -} - -func (db *DB) QueryRow(query string, args ...interface{}) *sql.Row { - return db.DB.QueryRow(db.withComment(context.Background(), query), args...) -} - -func (db *DB) QueryContext(ctx context.Context, query string, args ...any) (*sql.Rows, error) { - return db.DB.QueryContext(ctx, db.withComment(ctx, query), args...) -} - -func (db *DB) Exec(query string, args ...any) (sql.Result, error) { - return db.DB.Exec(db.withComment(context.Background(), query), args...) -} - -func (db *DB) ExecContext(ctx context.Context, query string, args ...any) (sql.Result, error) { - return db.DB.ExecContext(ctx, db.withComment(ctx, query), args...) -} - -func (db *DB) Prepare(query string) (*sql.Stmt, error) { - return db.DB.Prepare(db.withComment(context.Background(), query)) -} - -func (db *DB) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) { - return db.DB.PrepareContext(ctx, db.withComment(ctx, query)) -} - -// ***** Query Functions ***** - -// ***** Commenter Functions ***** - -func (db *DB) withComment(ctx context.Context, query string) string { - var commentsMap = map[string]string{} - query = strings.TrimSpace(query) - - // Sorted alphabetically - if db.options.EnableAction && (ctx.Value(core.Action) != nil) { - commentsMap[core.Action] = ctx.Value(core.Action).(string) - } - - // `driver` information should not be coming from framework. - // So, explicitly adding that here. - if db.options.EnableDBDriver { - commentsMap[core.Driver] = fmt.Sprintf("database/sql:%s", db.driverName) - } - - if db.options.EnableFramework && (ctx.Value(core.Framework) != nil) { - commentsMap[core.Framework] = ctx.Value(core.Framework).(string) - } - - if db.options.EnableRoute && (ctx.Value(core.Route) != nil) { - commentsMap[core.Route] = ctx.Value(core.Route).(string) - } - - if db.options.EnableTraceparent { - carrier := core.ExtractTraceparent(ctx) - if val, ok := carrier["traceparent"]; ok { - commentsMap[core.Traceparent] = val - } - } - - if db.options.EnableApplication { - if !attemptedToAutosetApplication && db.application == "" { - attemptedToAutosetApplication = true - bi, ok := debug.ReadBuildInfo() - if ok { - db.application = bi.Path - } - } - - commentsMap[core.Application] = db.application - } - - var commentsString string = "" - if len(commentsMap) > 0 { // Converts comments map to string and appends it to query - commentsString = fmt.Sprintf("/*%s*/", core.ConvertMapToComment(commentsMap)) - } - - // A semicolon at the end of the SQL statement means the query ends there. - // We need to insert the comment before that to be considered as part of the SQL statemtent. - if query[len(query)-1:] == ";" { - return fmt.Sprintf("%s%s;", strings.TrimSuffix(query, ";"), commentsString) - } - return fmt.Sprintf("%s%s", query, commentsString) -} - -// ***** Commenter Functions ***** diff --git a/go/database/sql/go-sql_test.go b/go/database/sql/go-sql_test.go deleted file mode 100644 index 7398a26d..00000000 --- a/go/database/sql/go-sql_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2022 Google LLC -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -package sql - -import ( - "context" - "net/http" - "regexp" - "testing" - - "github.com/DATA-DOG/go-sqlmock" - "github.com/google/sqlcommenter/go/core" - httpnet "github.com/google/sqlcommenter/go/net/http" - "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" - sdktrace "go.opentelemetry.io/otel/sdk/trace" -) - -func TestDisabled(t *testing.T) { - mockDB, _, err := sqlmock.New() - if err != nil { - t.Fatalf("MockSQL failed with unexpected error: %s", err) - } - db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{}} - query := "SELECT 2" - if got, want := db.withComment(context.Background(), query), query; got != want { - t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) - } -} - -func TestHTTP_Net(t *testing.T) { - mockDB, _, err := sqlmock.New() - if err != nil { - t.Fatalf("MockSQL failed with unexpected error: %s", err) - } - - db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true, EnableApplication: true, Application: "app"}, application: "app"} - r, err := http.NewRequest("GET", "hello/1", nil) - if err != nil { - t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) - } - - ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) - got := db.withComment(ctx, "Select 1") - want := "Select 1/*application=app,db_driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" - if got != want { - t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) - } -} - -func TestQueryWithSemicolon(t *testing.T) { - mockDB, _, err := sqlmock.New() - if err != nil { - t.Fatalf("MockSQL failed with unexpected error: %s", err) - } - - db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true}} - got := db.withComment(context.Background(), "Select 1;") - want := "Select 1/*db_driver=database%2Fsql%3Amocksql*/;" - if got != want { - t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) - } -} - -func TestOtelIntegration(t *testing.T) { - mockDB, _, err := sqlmock.New() - if err != nil { - t.Fatalf("MockSQL failed with unexpected error: %s", err) - } - - db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableTraceparent: true}} - exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) - bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithSpanProcessor(bsp), - ) - ctx, _ := tp.Tracer("").Start(context.Background(), "parent-span-name") - - got := db.withComment(ctx, "Select 1;") - wantRegex := "Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;" - r, err := regexp.Compile(wantRegex) - if err != nil { - t.Errorf("regex.Compile() failed with error: %v", err) - } - - if !r.MatchString(got) { - t.Errorf("%q does not match the given regex %q", got, wantRegex) - } -} diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index 494e8554..93bd486a 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -3,7 +3,7 @@ module github.com/google/sqlcommenter/go/database/sql go 1.19 require ( - github.com/google/sqlcommenter/go/core v0.0.2-beta + github.com/google/sqlcommenter/go/core v0.0.5-beta go.opentelemetry.io/otel/sdk v1.10.0 ) @@ -16,7 +16,7 @@ require ( require ( github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/google/sqlcommenter/go/net/http v0.0.2-beta + github.com/google/sqlcommenter/go/net/http v0.0.3-beta go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 go.opentelemetry.io/otel/trace v1.11.1 // indirect ) diff --git a/go/database/sql/go.sum b/go/database/sql/go.sum index 4d587756..8c1e11b9 100644 --- a/go/database/sql/go.sum +++ b/go/database/sql/go.sum @@ -11,10 +11,14 @@ github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57C github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= +github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= github.com/google/sqlcommenter/go/net/http v0.0.2-beta h1:hL/nLxgWeM+2A7yKPoqhyJeaqQZI12kbruQ6/IEiErM= github.com/google/sqlcommenter/go/net/http v0.0.2-beta/go.mod h1:1sd6t92iCHaNQc/v5qxTHp+td7KNoD8IIeG4BRetFZo= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= diff --git a/go/database/sql/gosql.go b/go/database/sql/gosql.go new file mode 100644 index 00000000..525ddd37 --- /dev/null +++ b/go/database/sql/gosql.go @@ -0,0 +1,120 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sql + +import ( + "context" + "database/sql" + "database/sql/driver" + + "github.com/google/sqlcommenter/go/core" +) + +var ( + _ driver.Driver = (*sqlCommenterDriver)(nil) + _ driver.DriverContext = (*sqlCommenterDriver)(nil) + _ driver.Connector = (*sqlCommenterConnector)(nil) +) + +// SQLCommenterDriver returns a driver object that contains SQLCommenter drivers. +type sqlCommenterDriver struct { + driver driver.Driver + options core.CommenterOptions +} + +func newSQLCommenterDriver(dri driver.Driver, options core.CommenterOptions) *sqlCommenterDriver { + return &sqlCommenterDriver{driver: dri, options: options} +} + +func (d *sqlCommenterDriver) Open(name string) (driver.Conn, error) { + rawConn, err := d.driver.Open(name) + if err != nil { + return nil, err + } + return newSQLCommenterConn(rawConn, d.options), nil +} + +func (d *sqlCommenterDriver) OpenConnector(name string) (driver.Connector, error) { + rawConnector, err := d.driver.(driver.DriverContext).OpenConnector(name) + if err != nil { + return nil, err + } + return newConnector(rawConnector, d, d.options), err +} + +type sqlCommenterConnector struct { + driver.Connector + driver *sqlCommenterDriver + options core.CommenterOptions +} + +func newConnector(connector driver.Connector, driver *sqlCommenterDriver, options core.CommenterOptions) *sqlCommenterConnector { + return &sqlCommenterConnector{ + Connector: connector, + driver: driver, + options: options, + } +} + +func (c *sqlCommenterConnector) Connect(ctx context.Context) (connection driver.Conn, err error) { + connection, err = c.Connector.Connect(ctx) + if err != nil { + return nil, err + } + return newSQLCommenterConn(connection, c.options), nil +} + +func (c *sqlCommenterConnector) Driver() driver.Driver { + return c.driver +} + +type dsnConnector struct { + dsn string + driver driver.Driver +} + +func (t dsnConnector) Connect(_ context.Context) (driver.Conn, error) { + return t.driver.Open(t.dsn) +} + +func (t dsnConnector) Driver() driver.Driver { + return t.driver +} + +// Open is a wrapper over sql.Open with OTel instrumentation. +func Open(driverName, dataSourceName string, options core.CommenterOptions) (*sql.DB, error) { + // Retrieve the driver implementation we need to wrap with instrumentation + db, err := sql.Open(driverName, "") + if err != nil { + return nil, err + } + d := db.Driver() + if err = db.Close(); err != nil { + return nil, err + } + + options.Tags.DriverName = driverName + sqlCommenterDriver := newSQLCommenterDriver(d, options) + + if _, ok := d.(driver.DriverContext); ok { + connector, err := sqlCommenterDriver.OpenConnector(dataSourceName) + if err != nil { + return nil, err + } + return sql.OpenDB(connector), nil + } + + return sql.OpenDB(dsnConnector{dsn: dataSourceName, driver: sqlCommenterDriver}), nil +} diff --git a/go/database/sql/gosql_test.go b/go/database/sql/gosql_test.go new file mode 100644 index 00000000..68d9b98a --- /dev/null +++ b/go/database/sql/gosql_test.go @@ -0,0 +1,101 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package sql + +// import ( +// "context" +// "net/http" +// "regexp" +// "testing" + +// "github.com/DATA-DOG/go-sqlmock" +// "github.com/google/sqlcommenter/go/core" +// httpnet "github.com/google/sqlcommenter/go/net/http" +// "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" +// sdktrace "go.opentelemetry.io/otel/sdk/trace" +// ) + +// func TestDisabled(t *testing.T) { +// mockDB, _, err := sqlmock.New() +// if err != nil { +// t.Fatalf("MockSQL failed with unexpected error: %s", err) +// } +// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{}} +// query := "SELECT 2" +// if got, want := db.withComment(context.Background(), query), query; got != want { +// t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) +// } +// } + +// func TestHTTP_Net(t *testing.T) { +// mockDB, _, err := sqlmock.New() +// if err != nil { +// t.Fatalf("MockSQL failed with unexpected error: %s", err) +// } + +// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true, EnableApplication: true, Application: "app"}, application: "app"} +// r, err := http.NewRequest("GET", "hello/1", nil) +// if err != nil { +// t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) +// } + +// ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) +// got := db.withComment(ctx, "Select 1") +// want := "Select 1/*application=app,db_driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" +// if got != want { +// t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) +// } +// } + +// func TestQueryWithSemicolon(t *testing.T) { +// mockDB, _, err := sqlmock.New() +// if err != nil { +// t.Fatalf("MockSQL failed with unexpected error: %s", err) +// } + +// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true}} +// got := db.withComment(context.Background(), "Select 1;") +// want := "Select 1/*db_driver=database%2Fsql%3Amocksql*/;" +// if got != want { +// t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) +// } +// } + +// func TestOtelIntegration(t *testing.T) { +// mockDB, _, err := sqlmock.New() +// if err != nil { +// t.Fatalf("MockSQL failed with unexpected error: %s", err) +// } + +// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableTraceparent: true}} +// exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) +// bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod +// tp := sdktrace.NewTracerProvider( +// sdktrace.WithSampler(sdktrace.AlwaysSample()), +// sdktrace.WithSpanProcessor(bsp), +// ) +// ctx, _ := tp.Tracer("").Start(context.Background(), "parent-span-name") + +// got := db.withComment(ctx, "Select 1;") +// wantRegex := "Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;" +// r, err := regexp.Compile(wantRegex) +// if err != nil { +// t.Errorf("regex.Compile() failed with error: %v", err) +// } + +// if !r.MatchString(got) { +// t.Errorf("%q does not match the given regex %q", got, wantRegex) +// } +// } From 5b87db594db1e283a2884300075c120da3b9e80e Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 12:29:43 +0530 Subject: [PATCH 078/108] Add PrepareContext methof --- go/database/sql/connection.go | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/go/database/sql/connection.go b/go/database/sql/connection.go index 7c9197e9..d03b3d89 100644 --- a/go/database/sql/connection.go +++ b/go/database/sql/connection.go @@ -30,8 +30,8 @@ func (s *sqlCommenterConn) Query(query string, args []driver.Value) (driver.Rows return nil, driver.ErrSkip } ctx := context.Background() - extendedQuery := s.withComment(ctx, query) - return queryer.Query(extendedQuery, args) + commentedQuery := s.withComment(ctx, query) + return queryer.Query(commentedQuery, args) } func (s *sqlCommenterConn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error) { @@ -39,8 +39,8 @@ func (s *sqlCommenterConn) QueryContext(ctx context.Context, query string, args if !ok { return nil, driver.ErrSkip } - extendedQuery := s.withComment(ctx, query) - return queryer.QueryContext(ctx, extendedQuery, args) + commentedQuery := s.withComment(ctx, query) + return queryer.QueryContext(ctx, commentedQuery, args) } func (s *sqlCommenterConn) Exec(query string, args []driver.Value) (driver.Result, error) { @@ -49,8 +49,8 @@ func (s *sqlCommenterConn) Exec(query string, args []driver.Value) (driver.Resul return nil, driver.ErrSkip } ctx := context.Background() - extendedQuery := s.withComment(ctx, query) - return execor.Exec(extendedQuery, args) + commentedQuery := s.withComment(ctx, query) + return execor.Exec(commentedQuery, args) } func (s *sqlCommenterConn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error) { @@ -58,8 +58,17 @@ func (s *sqlCommenterConn) ExecContext(ctx context.Context, query string, args [ if !ok { return nil, driver.ErrSkip } - extendedQuery := s.withComment(ctx, query) - return execor.ExecContext(ctx, extendedQuery, args) + commentedQuery := s.withComment(ctx, query) + return execor.ExecContext(ctx, commentedQuery, args) +} + +func (s *sqlCommenterConn) PrepareContext(ctx context.Context, query string) (stmt driver.Stmt, err error) { + preparer, ok := s.Conn.(driver.ConnPrepareContext) + if !ok { + return nil, driver.ErrSkip + } + commentedQuery := s.withComment(ctx, query) + return preparer.PrepareContext(ctx, commentedQuery) } func (s *sqlCommenterConn) Raw() driver.Conn { From 17cd0b13527d04c6f8913adc9f54518763583970 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 12:31:16 +0530 Subject: [PATCH 079/108] Add Copyright in connection.go --- go/database/sql/connection.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/go/database/sql/connection.go b/go/database/sql/connection.go index d03b3d89..40e67f6a 100644 --- a/go/database/sql/connection.go +++ b/go/database/sql/connection.go @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package sql import ( From c9f695f625469adf3671c5508a77ab53855b9e4a Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 12:35:50 +0530 Subject: [PATCH 080/108] gorrila/mux.SQLCommenterMiddleware test --- go/gorrila/mux/go.mod | 14 +++++++++++ go/gorrila/mux/go.sum | 15 ++++++++++++ go/gorrila/mux/mux.go | 22 +++++++++++++++++ go/gorrila/mux/mux_test.go | 48 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 go/gorrila/mux/go.mod create mode 100644 go/gorrila/mux/go.sum create mode 100644 go/gorrila/mux/mux.go create mode 100644 go/gorrila/mux/mux_test.go diff --git a/go/gorrila/mux/go.mod b/go/gorrila/mux/go.mod new file mode 100644 index 00000000..e85ebe62 --- /dev/null +++ b/go/gorrila/mux/go.mod @@ -0,0 +1,14 @@ +module github.com/google/sqlcommenter/go/gorrila/mux + +go 1.19 + +require ( + github.com/google/sqlcommenter/go/core v0.0.3-beta + github.com/google/sqlcommenter/go/net/http v0.0.3-beta + github.com/gorilla/mux v1.8.0 +) + +require ( + go.opentelemetry.io/otel v1.11.1 // indirect + go.opentelemetry.io/otel/trace v1.11.1 // indirect +) diff --git a/go/gorrila/mux/go.sum b/go/gorrila/mux/go.sum new file mode 100644 index 00000000..e15b61f7 --- /dev/null +++ b/go/gorrila/mux/go.sum @@ -0,0 +1,15 @@ +github.com/google/sqlcommenter/go/core v0.0.3-beta h1:gWUfq/UyMPEmHpAyhjcsGGAXRCV2fjB6e6F8CPedlnU= +github.com/google/sqlcommenter/go/core v0.0.3-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/net/http v0.0.2-beta/go.mod h1:1sd6t92iCHaNQc/v5qxTHp+td7KNoD8IIeG4BRetFZo= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= +github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= +github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= +go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= +go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= +go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= +go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= +go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= +go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= diff --git a/go/gorrila/mux/mux.go b/go/gorrila/mux/mux.go new file mode 100644 index 00000000..5fbbb6fb --- /dev/null +++ b/go/gorrila/mux/mux.go @@ -0,0 +1,22 @@ +package mux + +import ( + "net/http" + + "github.com/google/sqlcommenter/go/core" + httpnet "github.com/google/sqlcommenter/go/net/http" + "github.com/gorilla/mux" +) + +func SQLCommenterMiddleware(h http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + route := mux.CurrentRoute(r) + pathTemplate, err := route.GetPathTemplate() + if err != nil { + pathTemplate = "" + } + + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestTags("gorrila/mux", pathTemplate, core.GetFunctionName(route.GetHandler()))) + h.ServeHTTP(w, r.WithContext(ctx)) + }) +} diff --git a/go/gorrila/mux/mux_test.go b/go/gorrila/mux/mux_test.go new file mode 100644 index 00000000..9283603f --- /dev/null +++ b/go/gorrila/mux/mux_test.go @@ -0,0 +1,48 @@ +package mux + +import ( + "net/http" + "net/http/httptest" + "testing" + + "github.com/google/sqlcommenter/go/core" + "github.com/gorilla/mux" +) + +func TestSQLCommenterMiddleware(t *testing.T) { + framework := "gorrila/mux" + route := "/test/{id}" + action := "github.com/google/sqlcommenter/go/gorrila/mux.TestSQLCommenterMiddleware.func1" + + mockHandler := func(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + _framework := ctx.Value(core.Framework) + _route := ctx.Value(core.Route) + _action := ctx.Value(core.Action) + + if _framework != framework { + t.Errorf("mismatched framework - got: %s, want: %s", _framework, framework) + } + + if _route != route { + t.Errorf("mismatched route - got: %s, want: %s", _route, route) + } + + if _action != action { + t.Errorf("mismatched action - got: %s, want: %s", _action, action) + } + } + + router := mux.NewRouter() + router.Use(SQLCommenterMiddleware) + router.HandleFunc(route, mockHandler).Methods("GET") + + rr := httptest.NewRecorder() + req, err := http.NewRequest("GET", "/test/1", nil) + + if err != nil { + t.Errorf("error while building req: %v", err) + } + + router.ServeHTTP(rr, req) +} From a85954e61dc7907581ffc83b7e38a109b8a7511e Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 12:41:43 +0530 Subject: [PATCH 081/108] rebased master --- go/gorrila/mux/go.mod | 2 +- go/gorrila/mux/go.sum | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/go/gorrila/mux/go.mod b/go/gorrila/mux/go.mod index e85ebe62..b0129dcb 100644 --- a/go/gorrila/mux/go.mod +++ b/go/gorrila/mux/go.mod @@ -3,7 +3,7 @@ module github.com/google/sqlcommenter/go/gorrila/mux go 1.19 require ( - github.com/google/sqlcommenter/go/core v0.0.3-beta + github.com/google/sqlcommenter/go/core v0.0.5-beta github.com/google/sqlcommenter/go/net/http v0.0.3-beta github.com/gorilla/mux v1.8.0 ) diff --git a/go/gorrila/mux/go.sum b/go/gorrila/mux/go.sum index e15b61f7..c6f852c7 100644 --- a/go/gorrila/mux/go.sum +++ b/go/gorrila/mux/go.sum @@ -1,15 +1,17 @@ -github.com/google/sqlcommenter/go/core v0.0.3-beta h1:gWUfq/UyMPEmHpAyhjcsGGAXRCV2fjB6e6F8CPedlnU= -github.com/google/sqlcommenter/go/core v0.0.3-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= -github.com/google/sqlcommenter/go/net/http v0.0.2-beta/go.mod h1:1sd6t92iCHaNQc/v5qxTHp+td7KNoD8IIeG4BRetFZo= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= +github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= From f91b313e8c234c0d5b0a461db878536a79fbc924 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 13:34:26 +0530 Subject: [PATCH 082/108] Update unit tests in parity with the existing code --- go/database/sql/connection.go | 4 +- go/database/sql/connection_test.go | 152 +++++++++++++++++++++++++++++ go/database/sql/gosql_test.go | 127 ++++++++---------------- 3 files changed, 198 insertions(+), 85 deletions(-) create mode 100644 go/database/sql/connection_test.go diff --git a/go/database/sql/connection.go b/go/database/sql/connection.go index 40e67f6a..2dbb5f1d 100644 --- a/go/database/sql/connection.go +++ b/go/database/sql/connection.go @@ -130,7 +130,9 @@ func (conn *sqlCommenterConn) withComment(ctx context.Context, query string) str conn.options.Tags.Application = bi.Path } } - commentsMap[core.Application] = conn.options.Tags.Application + if conn.options.Tags.Application != "" { + commentsMap[core.Application] = conn.options.Tags.Application + } } var commentsString string = "" diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go new file mode 100644 index 00000000..1f91321a --- /dev/null +++ b/go/database/sql/connection_test.go @@ -0,0 +1,152 @@ +package sql + +import ( + "testing" + "context" + "github.com/google/sqlcommenter/go/core" +) + +func TestWithComment_NoContext(t *testing.T) { + testBasicConn := &mockConn{} + testCases := []struct { + desc string + commenterOptions core.CommenterOptions + query string + wantQuery string + } { + { + desc: "empty commenter options", + commenterOptions: core.CommenterOptions{}, + query: "SELECT 1;", + wantQuery: "SELECT 1;", + }, + { + desc: "only enable DBDriver", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true}, + }, + query: "SELECT 1;", + wantQuery: "SELECT 1/*db_driver=database%2Fsql%3A*/;", + }, + { + desc: "enable DBDriver and pass static tag driver name", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true}, + Tags: core.StaticTags{DriverName: "postgres"}, + }, + query: "SELECT 1;", + wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", + }, + { + desc: "enable DBDriver and pass all static tags", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true}, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + }, + query: "SELECT 1;", + wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", + }, + { + desc: "enable other tags and pass all static tags", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true, EnableApplication: true, EnableFramework: true}, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + }, + query: "SELECT 1;", + wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres*/;", + }, + } + for _, tc := range testCases { + testConn := newSQLCommenterConn(testBasicConn, tc.commenterOptions) + ctx := context.Background() + if got, want := testConn.withComment(ctx, tc.query), tc.wantQuery; got != want { + t.Errorf("testConn.withComment(ctx, %q) = %q, want = %q", tc.query, got, want) + } + } +} + +func TestWithComment_WithContext(t *testing.T) { + testBasicConn := &mockConn{} + testCases := []struct { + desc string + commenterOptions core.CommenterOptions + ctx context.Context + query string + wantQuery string + } { + { + desc: "empty commenter options", + commenterOptions: core.CommenterOptions{}, + ctx: getContextWithKeyValue( + map[string]string { + "route": "listData", + "framework": "custom-golang", + }, + ), + query: "SELECT 1;", + wantQuery: "SELECT 1;", + }, + { + desc: "only all options but context has few tags", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{ + EnableDBDriver: true, + EnableRoute: true, + EnableFramework: true, + EnableController: true, + EnableAction: true, + EnableTraceparent: true, + EnableApplication: true, + }, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + }, + ctx: getContextWithKeyValue( + map[string]string { + "route": "listData", + "framework": "custom-golang", + }, + ), + query: "SELECT 1;", + wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", + }, + { + desc: "only all options but context contains all tags", + commenterOptions: core.CommenterOptions{ + Config: core.CommenterConfig{ + EnableDBDriver: true, + EnableRoute: true, + EnableFramework: true, + EnableController: true, + EnableAction: true, + EnableTraceparent: true, + EnableApplication: true, + }, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + }, + ctx: getContextWithKeyValue( + map[string]string { + "route": "listData", + "framework": "custom-golang", + "controller": "custom-controller", + "action": "any action", + }, + ), + query: "SELECT 1;", + wantQuery: "SELECT 1/*action=any+action,application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", + }, + } + for _, tc := range testCases { + testConn := newSQLCommenterConn(testBasicConn, tc.commenterOptions) + if got, want := testConn.withComment(tc.ctx, tc.query), tc.wantQuery; got != want { + t.Errorf("testConn.withComment(ctx, %q) = %q, want = %q", tc.query, got, want) + } + } +} + +func getContextWithKeyValue(vals map[string]string) context.Context { + ctx := context.Background() + for k, v := range vals { + ctx = context.WithValue(ctx, k, v) + } + return ctx +} diff --git a/go/database/sql/gosql_test.go b/go/database/sql/gosql_test.go index 68d9b98a..2dcdec9b 100644 --- a/go/database/sql/gosql_test.go +++ b/go/database/sql/gosql_test.go @@ -14,88 +14,47 @@ package sql -// import ( -// "context" -// "net/http" -// "regexp" -// "testing" +import ( + "database/sql/driver" +) + +type mockConn struct { + prepareStmt driver.Stmt + prepareErr error + + closeErr error + + beginTx driver.Tx + beginErr error +} + +func (c *mockConn) Prepare(query string) (driver.Stmt, error) { + if c.prepareErr != nil { + return nil, c.prepareErr + } + return c.prepareStmt, nil +} + +func (c *mockConn) Close() error { + return c.closeErr +} + +func (c *mockConn) Begin() (driver.Tx, error) { + if c.beginErr != nil { + return nil, c.beginErr + } + return c.beginTx, nil +} + +type mockDriver struct { + conn driver.Conn + openError error +} + +func (d *mockDriver) Open(name string) (driver.Conn, error) { + if d.openError != nil { + return nil, d.openError + } + return d.conn, nil +} -// "github.com/DATA-DOG/go-sqlmock" -// "github.com/google/sqlcommenter/go/core" -// httpnet "github.com/google/sqlcommenter/go/net/http" -// "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" -// sdktrace "go.opentelemetry.io/otel/sdk/trace" -// ) - -// func TestDisabled(t *testing.T) { -// mockDB, _, err := sqlmock.New() -// if err != nil { -// t.Fatalf("MockSQL failed with unexpected error: %s", err) -// } -// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{}} -// query := "SELECT 2" -// if got, want := db.withComment(context.Background(), query), query; got != want { -// t.Errorf("db.withComment(context.Background(), %q) = %q, want = %q", query, got, want) -// } -// } - -// func TestHTTP_Net(t *testing.T) { -// mockDB, _, err := sqlmock.New() -// if err != nil { -// t.Fatalf("MockSQL failed with unexpected error: %s", err) -// } - -// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableFramework: true, EnableApplication: true, Application: "app"}, application: "app"} -// r, err := http.NewRequest("GET", "hello/1", nil) -// if err != nil { -// t.Errorf("http.NewRequest('GET', 'hello/1', nil) returned unexpected error: %v", err) -// } - -// ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, nil)) -// got := db.withComment(ctx, "Select 1") -// want := "Select 1/*application=app,db_driver=database%2Fsql%3Amocksql,framework=net%2Fhttp,route=hello%2F1*/" -// if got != want { -// t.Errorf("db.withComment(ctx, 'Select 1') got %q, wanted %q", got, want) -// } -// } - -// func TestQueryWithSemicolon(t *testing.T) { -// mockDB, _, err := sqlmock.New() -// if err != nil { -// t.Fatalf("MockSQL failed with unexpected error: %s", err) -// } - -// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableDBDriver: true}} -// got := db.withComment(context.Background(), "Select 1;") -// want := "Select 1/*db_driver=database%2Fsql%3Amocksql*/;" -// if got != want { -// t.Errorf("db.withComment(context.Background(), 'Select 1;') got %q, wanted %q", got, want) -// } -// } - -// func TestOtelIntegration(t *testing.T) { -// mockDB, _, err := sqlmock.New() -// if err != nil { -// t.Fatalf("MockSQL failed with unexpected error: %s", err) -// } - -// db := DB{DB: mockDB, driverName: "mocksql", options: core.CommenterOptions{EnableTraceparent: true}} -// exp, _ := stdouttrace.New(stdouttrace.WithPrettyPrint()) -// bsp := sdktrace.NewSimpleSpanProcessor(exp) // You should use batch span processor in prod -// tp := sdktrace.NewTracerProvider( -// sdktrace.WithSampler(sdktrace.AlwaysSample()), -// sdktrace.WithSpanProcessor(bsp), -// ) -// ctx, _ := tp.Tracer("").Start(context.Background(), "parent-span-name") - -// got := db.withComment(ctx, "Select 1;") -// wantRegex := "Select 1/\\*traceparent=\\d{1,2}-[a-zA-Z0-9_]{32}-[a-zA-Z0-9_]{16}-\\d{1,2}\\*/;" -// r, err := regexp.Compile(wantRegex) -// if err != nil { -// t.Errorf("regex.Compile() failed with error: %v", err) -// } - -// if !r.MatchString(got) { -// t.Errorf("%q does not match the given regex %q", got, wantRegex) -// } -// } From e221dbd54461ae2c8a84a0fffbd2e70103237406 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 13:36:00 +0530 Subject: [PATCH 083/108] Format fix with go-fmt --- go/database/sql/connection_test.go | 84 +++++++++++++++--------------- go/database/sql/gosql_test.go | 9 ++-- 2 files changed, 46 insertions(+), 47 deletions(-) diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go index 1f91321a..34d9f773 100644 --- a/go/database/sql/connection_test.go +++ b/go/database/sql/connection_test.go @@ -1,58 +1,58 @@ package sql import ( - "testing" "context" "github.com/google/sqlcommenter/go/core" + "testing" ) func TestWithComment_NoContext(t *testing.T) { testBasicConn := &mockConn{} testCases := []struct { - desc string + desc string commenterOptions core.CommenterOptions - query string - wantQuery string - } { + query string + wantQuery string + }{ { - desc: "empty commenter options", + desc: "empty commenter options", commenterOptions: core.CommenterOptions{}, - query: "SELECT 1;", - wantQuery: "SELECT 1;", + query: "SELECT 1;", + wantQuery: "SELECT 1;", }, { desc: "only enable DBDriver", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true}, }, - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*db_driver=database%2Fsql%3A*/;", }, { desc: "enable DBDriver and pass static tag driver name", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true}, - Tags: core.StaticTags{DriverName: "postgres"}, + Tags: core.StaticTags{DriverName: "postgres"}, }, - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", }, { desc: "enable DBDriver and pass all static tags", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true}, - Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", }, { desc: "enable other tags and pass all static tags", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true, EnableApplication: true, EnableFramework: true}, - Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, + Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres*/;", }, } @@ -68,70 +68,70 @@ func TestWithComment_NoContext(t *testing.T) { func TestWithComment_WithContext(t *testing.T) { testBasicConn := &mockConn{} testCases := []struct { - desc string + desc string commenterOptions core.CommenterOptions - ctx context.Context - query string - wantQuery string - } { + ctx context.Context + query string + wantQuery string + }{ { - desc: "empty commenter options", + desc: "empty commenter options", commenterOptions: core.CommenterOptions{}, ctx: getContextWithKeyValue( - map[string]string { - "route": "listData", + map[string]string{ + "route": "listData", "framework": "custom-golang", }, ), - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1;", }, { desc: "only all options but context has few tags", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{ - EnableDBDriver: true, - EnableRoute: true, - EnableFramework: true, - EnableController: true, - EnableAction: true, + EnableDBDriver: true, + EnableRoute: true, + EnableFramework: true, + EnableController: true, + EnableAction: true, EnableTraceparent: true, EnableApplication: true, }, Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, ctx: getContextWithKeyValue( - map[string]string { - "route": "listData", + map[string]string{ + "route": "listData", "framework": "custom-golang", }, ), - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", }, { desc: "only all options but context contains all tags", commenterOptions: core.CommenterOptions{ Config: core.CommenterConfig{ - EnableDBDriver: true, - EnableRoute: true, - EnableFramework: true, - EnableController: true, - EnableAction: true, + EnableDBDriver: true, + EnableRoute: true, + EnableFramework: true, + EnableController: true, + EnableAction: true, EnableTraceparent: true, EnableApplication: true, }, Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, ctx: getContextWithKeyValue( - map[string]string { - "route": "listData", - "framework": "custom-golang", + map[string]string{ + "route": "listData", + "framework": "custom-golang", "controller": "custom-controller", - "action": "any action", + "action": "any action", }, ), - query: "SELECT 1;", + query: "SELECT 1;", wantQuery: "SELECT 1/*action=any+action,application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", }, } diff --git a/go/database/sql/gosql_test.go b/go/database/sql/gosql_test.go index 2dcdec9b..511ab7fe 100644 --- a/go/database/sql/gosql_test.go +++ b/go/database/sql/gosql_test.go @@ -20,11 +20,11 @@ import ( type mockConn struct { prepareStmt driver.Stmt - prepareErr error + prepareErr error closeErr error - beginTx driver.Tx + beginTx driver.Tx beginErr error } @@ -43,11 +43,11 @@ func (c *mockConn) Begin() (driver.Tx, error) { if c.beginErr != nil { return nil, c.beginErr } - return c.beginTx, nil + return c.beginTx, nil } type mockDriver struct { - conn driver.Conn + conn driver.Conn openError error } @@ -57,4 +57,3 @@ func (d *mockDriver) Open(name string) (driver.Conn, error) { } return d.conn, nil } - From 8e975123f521c49fb304c6d3029a4f5005d89e84 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 13:37:45 +0530 Subject: [PATCH 084/108] Add copyright for connection_test.go --- go/database/sql/connection_test.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go index 34d9f773..d84d9e1a 100644 --- a/go/database/sql/connection_test.go +++ b/go/database/sql/connection_test.go @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + package sql import ( From de3c460dffa901be1fd64348916a30771482c052 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 23 Nov 2022 13:38:42 +0530 Subject: [PATCH 085/108] fix import orderinf --- go/database/sql/connection_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go index d84d9e1a..f5ed0f82 100644 --- a/go/database/sql/connection_test.go +++ b/go/database/sql/connection_test.go @@ -16,8 +16,9 @@ package sql import ( "context" - "github.com/google/sqlcommenter/go/core" "testing" + + "github.com/google/sqlcommenter/go/core" ) func TestWithComment_NoContext(t *testing.T) { From a4ebe16080c77cfd1e8bba5876e0db6c19b87a60 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 14:16:46 +0530 Subject: [PATCH 086/108] working sample application --- go/samples/http/Dockerfile | 2 +- go/samples/http/curls/index.sh | 4 --- go/samples/http/go.mod | 9 +++--- go/samples/http/go.sum | 37 ++++++++++++------------- go/samples/http/main.go | 28 ++++++------------- go/samples/http/mysqldb/mysql_driver.go | 8 ++++-- go/samples/http/pgdb/pg_driver.go | 8 ++++-- go/samples/http/todos/controller.go | 4 +-- 8 files changed, 45 insertions(+), 55 deletions(-) delete mode 100755 go/samples/http/curls/index.sh diff --git a/go/samples/http/Dockerfile b/go/samples/http/Dockerfile index 092a1a60..2759f15b 100644 --- a/go/samples/http/Dockerfile +++ b/go/samples/http/Dockerfile @@ -25,4 +25,4 @@ COPY --from=build-env /$APP_NAME . EXPOSE 8081 # Start app -CMD ["./sqlcommenter-http", "--db_engine=mysql"] +CMD ["./sqlcommenter-http", "--db_engine=pg"] diff --git a/go/samples/http/curls/index.sh b/go/samples/http/curls/index.sh deleted file mode 100755 index 93960edf..00000000 --- a/go/samples/http/curls/index.sh +++ /dev/null @@ -1,4 +0,0 @@ -# usage: index.sh - -curl http://localhost:8081 -echo \ No newline at end of file diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index b7a47067..87853586 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -15,17 +15,18 @@ require ( ) require ( - github.com/julienschmidt/httprouter v1.3.0 github.com/lib/pq v1.10.7 go.opentelemetry.io/otel v1.11.1 ) +require github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta // indirect + require ( github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/google/sqlcommenter/go/core v0.0.1-beta - github.com/google/sqlcommenter/go/database/sql v0.0.1-beta - github.com/google/sqlcommenter/go/net/http v0.0.1-beta + github.com/google/sqlcommenter/go/core v0.0.5-beta + github.com/google/sqlcommenter/go/database/sql v0.0.3-beta + github.com/google/sqlcommenter/go/net/http v0.0.3-beta // indirect go.opentelemetry.io/otel/trace v1.11.1 // indirect golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect ) diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum index 00b35900..7e782730 100644 --- a/go/samples/http/go.sum +++ b/go/samples/http/go.sum @@ -1,5 +1,5 @@ github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= @@ -9,40 +9,37 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE= github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= -github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= -github.com/google/sqlcommenter/go/database/sql v0.0.1-beta h1:N680pEYaRwmOSrQWUd4A4aD4kj4WYxcJTQB9WLe69vY= -github.com/google/sqlcommenter/go/database/sql v0.0.1-beta/go.mod h1:VdswmF4SM0cbjJdD+3GyM5QuXpHhH6F5nSzcbikzCGY= -github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= -github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= +github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= +github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/sqlcommenter/go/core v0.0.3-beta h1:gWUfq/UyMPEmHpAyhjcsGGAXRCV2fjB6e6F8CPedlnU= +github.com/google/sqlcommenter/go/core v0.0.3-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= +github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/database/sql v0.0.2-beta h1:0Caf+turrQA18W35lP3BwYpaV15vty+7eHAWtE73mQs= +github.com/google/sqlcommenter/go/database/sql v0.0.2-beta/go.mod h1:d4SXOYrVnfW0X38FR+MUa1pbYNgqHlPv2rgYK0xr+rg= +github.com/google/sqlcommenter/go/database/sql v0.0.3-beta h1:1f989k6obpu99gl/wX7cS6zHQwa77p5NrQABCg0X80Y= +github.com/google/sqlcommenter/go/database/sql v0.0.3-beta/go.mod h1:Bmr95q93SPegEZ04UpJTVSr+okVqZTR3tM4Tom4f0b4= +github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta h1:kCtKVtbDtv42Vh7jvwaHC7MCuVOFjKFUMcdjN2gvXjo= +github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta/go.mod h1:xhQX/UtJVH6+dzvU+ULSVyepXvnqMqBPZay4l8m1WfM= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= +github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= -github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4 h1:gn5Cf5XpnENThRBjAHq6vuENFo+l9qwnEMqwmanIYuY= go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux v0.36.4/go.mod h1:f26RulijcxdgrGSYep0AykXM9ZkWoKVtInstDYUR8EU= -go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.1 h1:3Yvzs7lgOw8MmbxmLRsQGwYdCubFmUHSooKaEhQunFQ= go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.11.1/go.mod h1:pyHDt0YlyuENkD2VwHsiRDf+5DfI3EH7pfhUYW6sQUE= -go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= -go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= go.opentelemetry.io/otel/sdk v1.11.1 h1:F7KmQgoHljhUuJyA+9BiU+EkJfyX5nVVF4wyzWZpKxs= go.opentelemetry.io/otel/sdk v1.11.1/go.mod h1:/l3FE4SupHJ12TduVjUkZtlfFqDCQJlOlithYrdktys= -go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go/samples/http/main.go b/go/samples/http/main.go index b7d426eb..4706e999 100644 --- a/go/samples/http/main.go +++ b/go/samples/http/main.go @@ -2,13 +2,12 @@ package main import ( "context" + "database/sql" "flag" "log" "net/http" - "github.com/google/sqlcommenter/go/core" - gosql "github.com/google/sqlcommenter/go/database/sql" - httpnet "github.com/google/sqlcommenter/go/net/http" + gosqlmux "github.com/google/sqlcommenter/go/gorrila/mux" "github.com/gorilla/mux" "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" "go.opentelemetry.io/otel" @@ -21,15 +20,6 @@ import ( "sqlcommenter-http/todos" ) -// middleware is used to intercept incoming HTTP calls and apply general functions upon them. -func middleware(h http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestExtractor(r, h)) - log.Printf("HTTP request sent to %s", r.URL.Path) - h.ServeHTTP(w, r.WithContext(ctx)) - }) -} - func runApp(todosController *todos.TodosController) { err := todosController.CreateTodosTableIfNotExists() if err != nil { @@ -47,19 +37,17 @@ func runApp(todosController *todos.TodosController) { }() r := mux.NewRouter() - r.Use(otelmux.Middleware("sqlcommenter sample-server")) + r.Use(otelmux.Middleware("sqlcommenter sample-server"), gosqlmux.SQLCommenterMiddleware) r.HandleFunc("/todos", todosController.ActionList).Methods("GET") r.HandleFunc("/todos", todosController.ActionInsert).Methods("POST") r.HandleFunc("/todos/{id}", todosController.ActionUpdate).Methods("PUT") r.HandleFunc("/todos/{id}", todosController.ActionDelete).Methods("DELETE") - http.ListenAndServe(":8081", middleware(r)) + http.ListenAndServe(":8081", r) } -// host = “host.docker.internal” - -func runForMysql() *gosql.DB { +func runForMysql() *sql.DB { connection := "root:password@tcp(mysql:3306)/sqlcommenter_db" db := mysqldb.ConnectMySQL(connection) todosController := &todos.TodosController{Engine: "mysql", DB: db, SQL: todos.MySQLQueries{}} @@ -67,7 +55,7 @@ func runForMysql() *gosql.DB { return db } -func runForPg() *gosql.DB { +func runForPg() *sql.DB { connection := "host=postgres user=postgres password=postgres dbname=postgres port=5432 sslmode=disable" db := pgdb.ConnectPG(connection) todosController := &todos.TodosController{Engine: "pg", DB: db, SQL: todos.PGQueries{}} @@ -92,14 +80,14 @@ func initTracer() (*sdktrace.TracerProvider, error) { func main() { var engine string - flag.StringVar(&engine, "db_engine", "mysql", "db-engine to run the sample application on") + flag.StringVar(&engine, "db_engine", "pg", "db-engine to run the sample application on") flag.Parse() if engine != "mysql" && engine != "pg" { log.Fatalf("invalid engine: %s", engine) } - var db *gosql.DB + var db *sql.DB switch engine { case "mysql": diff --git a/go/samples/http/mysqldb/mysql_driver.go b/go/samples/http/mysqldb/mysql_driver.go index a5208346..36160801 100644 --- a/go/samples/http/mysqldb/mysql_driver.go +++ b/go/samples/http/mysqldb/mysql_driver.go @@ -1,6 +1,7 @@ package mysqldb import ( + "database/sql" "log" _ "github.com/go-sql-driver/mysql" @@ -8,8 +9,11 @@ import ( gosql "github.com/google/sqlcommenter/go/database/sql" ) -func ConnectMySQL(connection string) *gosql.DB { - db, err := gosql.Open("mysql", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) +func ConnectMySQL(connection string) *sql.DB { + db, err := gosql.Open("mysql", connection, core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true, EnableApplication: true}, + Tags: core.StaticTags{}, + }) if err != nil { log.Fatalf("Failed to connect to MySQL(%q), error: %v", connection, err) } diff --git a/go/samples/http/pgdb/pg_driver.go b/go/samples/http/pgdb/pg_driver.go index 13fd6032..68538324 100644 --- a/go/samples/http/pgdb/pg_driver.go +++ b/go/samples/http/pgdb/pg_driver.go @@ -1,6 +1,7 @@ package pgdb import ( + "database/sql" "log" "github.com/google/sqlcommenter/go/core" @@ -8,8 +9,11 @@ import ( _ "github.com/lib/pq" ) -func ConnectPG(connection string) *gosql.DB { - db, err := gosql.Open("postgres", connection, core.CommenterOptions{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true}) +func ConnectPG(connection string) *sql.DB { + db, err := gosql.Open("postgres", connection, core.CommenterOptions{ + Config: core.CommenterConfig{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true, EnableApplication: true}, + Tags: core.StaticTags{}, + }) if err != nil { log.Fatalf("Failed to connect to PG(%q), error: %v", connection, err) } diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index 0f1e832c..70c85a0e 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -2,12 +2,12 @@ package todos import ( "context" + "database/sql" "encoding/json" "fmt" "log" "net/http" - gosql "github.com/google/sqlcommenter/go/database/sql" "github.com/gorilla/mux" ) @@ -22,7 +22,7 @@ type TodoDTO struct { type TodosController struct { Engine string - DB *gosql.DB + DB *sql.DB SQL TodosQueries } From fc843bc0dd64653b64d3b03fd31e8143dafda359 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 14:36:21 +0530 Subject: [PATCH 087/108] dockerfile changes --- go/samples/http/Dockerfile | 23 +++++++---------------- 1 file changed, 7 insertions(+), 16 deletions(-) diff --git a/go/samples/http/Dockerfile b/go/samples/http/Dockerfile index 2759f15b..af993c85 100644 --- a/go/samples/http/Dockerfile +++ b/go/samples/http/Dockerfile @@ -1,25 +1,16 @@ -# Build Stage # First pull Golang image -FROM golang:1.19-alpine as build-env +FROM golang:1.19-alpine ENV APP_NAME sqlcommenter-http -ENV CMD_PATH main.go - -# Copy application data into image -COPY . $GOPATH/src/$APP_NAME + +# Set workdir WORKDIR $GOPATH/src/$APP_NAME + +# Copy application data into image +COPY . . # Budild application -RUN CGO_ENABLED=0 go build -v -o /$APP_NAME $GOPATH/src/$APP_NAME/$CMD_PATH - -# Run Stage -FROM alpine:3.16.3 - -# Set environment variable -ENV APP_NAME sqlcommenter-http - -# Copy only required data into this image -COPY --from=build-env /$APP_NAME . +RUN CGO_ENABLED=0 go build -v # Expose application port EXPOSE 8081 From 9a440a1d5c3ff00e302759a02c9a57b2a46ebb99 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 14:46:28 +0530 Subject: [PATCH 088/108] updated db initialization --- go/samples/http/mysqldb/mysql_driver.go | 1 - go/samples/http/pgdb/pg_driver.go | 1 - 2 files changed, 2 deletions(-) diff --git a/go/samples/http/mysqldb/mysql_driver.go b/go/samples/http/mysqldb/mysql_driver.go index 36160801..4b2d5ad1 100644 --- a/go/samples/http/mysqldb/mysql_driver.go +++ b/go/samples/http/mysqldb/mysql_driver.go @@ -12,7 +12,6 @@ import ( func ConnectMySQL(connection string) *sql.DB { db, err := gosql.Open("mysql", connection, core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true, EnableApplication: true}, - Tags: core.StaticTags{}, }) if err != nil { log.Fatalf("Failed to connect to MySQL(%q), error: %v", connection, err) diff --git a/go/samples/http/pgdb/pg_driver.go b/go/samples/http/pgdb/pg_driver.go index 68538324..52a7c49b 100644 --- a/go/samples/http/pgdb/pg_driver.go +++ b/go/samples/http/pgdb/pg_driver.go @@ -12,7 +12,6 @@ import ( func ConnectPG(connection string) *sql.DB { db, err := gosql.Open("postgres", connection, core.CommenterOptions{ Config: core.CommenterConfig{EnableDBDriver: true, EnableRoute: true, EnableAction: true, EnableFramework: true, EnableTraceparent: true, EnableApplication: true}, - Tags: core.StaticTags{}, }) if err != nil { log.Fatalf("Failed to connect to PG(%q), error: %v", connection, err) From 08771c5267542b3bff17b06f750050076f53917b Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 14:51:21 +0530 Subject: [PATCH 089/108] added method to route --- go/gorrila/mux/mux.go | 10 ++++++---- go/gorrila/mux/mux_test.go | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/go/gorrila/mux/mux.go b/go/gorrila/mux/mux.go index 5fbbb6fb..646fb942 100644 --- a/go/gorrila/mux/mux.go +++ b/go/gorrila/mux/mux.go @@ -1,6 +1,7 @@ package mux import ( + "fmt" "net/http" "github.com/google/sqlcommenter/go/core" @@ -10,13 +11,14 @@ import ( func SQLCommenterMiddleware(h http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - route := mux.CurrentRoute(r) - pathTemplate, err := route.GetPathTemplate() + muxRoute := mux.CurrentRoute(r) + path, err := muxRoute.GetPathTemplate() if err != nil { - pathTemplate = "" + path = "" } - ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestTags("gorrila/mux", pathTemplate, core.GetFunctionName(route.GetHandler()))) + route := fmt.Sprintf("%s--%s", r.Method, path) + ctx := core.ContextInject(r.Context(), httpnet.NewHTTPRequestTags("gorrila/mux", route, core.GetFunctionName(muxRoute.GetHandler()))) h.ServeHTTP(w, r.WithContext(ctx)) }) } diff --git a/go/gorrila/mux/mux_test.go b/go/gorrila/mux/mux_test.go index 9283603f..c17d2985 100644 --- a/go/gorrila/mux/mux_test.go +++ b/go/gorrila/mux/mux_test.go @@ -11,7 +11,7 @@ import ( func TestSQLCommenterMiddleware(t *testing.T) { framework := "gorrila/mux" - route := "/test/{id}" + route := "GET--/test/{id}" action := "github.com/google/sqlcommenter/go/gorrila/mux.TestSQLCommenterMiddleware.func1" mockHandler := func(w http.ResponseWriter, r *http.Request) { From 4e05c75c53a9998bc9b1cad45d1a55089b3f11d1 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 15:40:48 +0530 Subject: [PATCH 090/108] sample application prepare-statement, go mod tidy on database/sql --- go/database/sql/go.mod | 19 +++-------------- go/database/sql/go.sum | 33 ++++------------------------- go/samples/http/go.mod | 2 +- go/samples/http/go.sum | 2 ++ go/samples/http/todos/controller.go | 10 ++++++++- 5 files changed, 19 insertions(+), 47 deletions(-) diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index 93bd486a..b0edf01e 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -2,21 +2,8 @@ module github.com/google/sqlcommenter/go/database/sql go 1.19 -require ( - github.com/google/sqlcommenter/go/core v0.0.5-beta - go.opentelemetry.io/otel/sdk v1.10.0 -) +require github.com/google/sqlcommenter/go/core v0.0.5-beta -require ( - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - go.opentelemetry.io/otel v1.11.1 // indirect - golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 // indirect -) +require go.opentelemetry.io/otel v1.11.1 // indirect -require ( - github.com/DATA-DOG/go-sqlmock v1.5.0 - github.com/google/sqlcommenter/go/net/http v0.0.3-beta - go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 - go.opentelemetry.io/otel/trace v1.11.1 // indirect -) +require go.opentelemetry.io/otel/trace v1.11.1 // indirect diff --git a/go/database/sql/go.sum b/go/database/sql/go.sum index 8c1e11b9..2342027e 100644 --- a/go/database/sql/go.sum +++ b/go/database/sql/go.sum @@ -1,38 +1,13 @@ -github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60= -github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM= -github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= -github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/sqlcommenter/go/core v0.0.1-beta h1:IVszEHanWVeS7UcmP8C3SHa57CmfeqMBj0QUcJ8VZ9Q= -github.com/google/sqlcommenter/go/core v0.0.1-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= -github.com/google/sqlcommenter/go/core v0.0.2-beta h1:VnX58Jvf1mkI5KveBddZhCm4YtzG9IQErCNdmfXBU1I= -github.com/google/sqlcommenter/go/core v0.0.2-beta/go.mod h1:CZfcqmbIxngExnZ7Se6AsKNVubZhKyi54aeDJZiqTMQ= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= -github.com/google/sqlcommenter/go/net/http v0.0.1-beta h1:7XQ6poZv+ZJwwHWQHlesq9IMsRus3G6Z9n10qAkrGqE= -github.com/google/sqlcommenter/go/net/http v0.0.1-beta/go.mod h1:tVUqM1YZ/K3eRTdGzeav1GSbw+BXNdTGzSAbLW9CxAc= -github.com/google/sqlcommenter/go/net/http v0.0.2-beta h1:hL/nLxgWeM+2A7yKPoqhyJeaqQZI12kbruQ6/IEiErM= -github.com/google/sqlcommenter/go/net/http v0.0.2-beta/go.mod h1:1sd6t92iCHaNQc/v5qxTHp+td7KNoD8IIeG4BRetFZo= -github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= -github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= -go.opentelemetry.io/otel v1.10.0 h1:Y7DTJMR6zs1xkS/upamJYk0SxxN4C9AqRd77jmZnyY4= -go.opentelemetry.io/otel v1.10.0/go.mod h1:NbvWjCthWHKBEUMpf0/v8ZRZlni86PpGFEMA9pnQSnQ= +github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= go.opentelemetry.io/otel v1.11.1/go.mod h1:1nNhXBbWSD0nsL38H6btgnFN2k4i0sNLHNNMZMSbUGE= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0 h1:c9UtMu/qnbLlVwTwt+ABrURrioEruapIslTDYZHJe2w= -go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.10.0/go.mod h1:h3Lrh9t3Dnqp3NPwAZx7i37UFX7xrfnO1D+fuClREOA= -go.opentelemetry.io/otel/sdk v1.10.0 h1:jZ6K7sVn04kk/3DNUdJ4mqRlGDiXAVuIG+MMENpTNdY= -go.opentelemetry.io/otel/sdk v1.10.0/go.mod h1:vO06iKzD5baltJz1zarxMCNHFpUlUiOy4s65ECtn6kE= -go.opentelemetry.io/otel/trace v1.10.0 h1:npQMbR8o7mum8uF95yFbOEJffhs1sbCOfDh8zAJiH5E= -go.opentelemetry.io/otel/trace v1.10.0/go.mod h1:Sij3YYczqAdz+EhmGhE6TpTxUO5/F/AzrK+kxfGqySM= go.opentelemetry.io/otel/trace v1.11.1 h1:ofxdnzsNrGBYXbP7t7zpUK281+go5rF7dvdIZXF8gdQ= go.opentelemetry.io/otel/trace v1.11.1/go.mod h1:f/Q9G7vzk5u91PhbmKbg1Qn0rzH1LJ4vbPHFGkTPtOk= -golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6 h1:cy1ko5847T/lJ45eyg/7uLprIE/amW5IXxGtEnQdYMI= -golang.org/x/sys v0.0.0-20220927170352-d9d178bc13c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/go/samples/http/go.mod b/go/samples/http/go.mod index 87853586..5e1b691f 100644 --- a/go/samples/http/go.mod +++ b/go/samples/http/go.mod @@ -19,7 +19,7 @@ require ( go.opentelemetry.io/otel v1.11.1 ) -require github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta // indirect +require github.com/google/sqlcommenter/go/gorrila/mux v0.0.2-beta // indirect require ( github.com/go-logr/logr v1.2.3 // indirect diff --git a/go/samples/http/go.sum b/go/samples/http/go.sum index 7e782730..e5e21e2d 100644 --- a/go/samples/http/go.sum +++ b/go/samples/http/go.sum @@ -22,6 +22,8 @@ github.com/google/sqlcommenter/go/database/sql v0.0.3-beta h1:1f989k6obpu99gl/wX github.com/google/sqlcommenter/go/database/sql v0.0.3-beta/go.mod h1:Bmr95q93SPegEZ04UpJTVSr+okVqZTR3tM4Tom4f0b4= github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta h1:kCtKVtbDtv42Vh7jvwaHC7MCuVOFjKFUMcdjN2gvXjo= github.com/google/sqlcommenter/go/gorrila/mux v0.0.1-beta/go.mod h1:xhQX/UtJVH6+dzvU+ULSVyepXvnqMqBPZay4l8m1WfM= +github.com/google/sqlcommenter/go/gorrila/mux v0.0.2-beta h1:wJV2txZXFLPDLCgM1isWT47SA54bTZpT/hmzCeO4FxI= +github.com/google/sqlcommenter/go/gorrila/mux v0.0.2-beta/go.mod h1:xhQX/UtJVH6+dzvU+ULSVyepXvnqMqBPZay4l8m1WfM= github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= diff --git a/go/samples/http/todos/controller.go b/go/samples/http/todos/controller.go index 70c85a0e..39ed104a 100644 --- a/go/samples/http/todos/controller.go +++ b/go/samples/http/todos/controller.go @@ -37,7 +37,15 @@ func (c *TodosController) ActionList(w http.ResponseWriter, r *http.Request) { query := r.URL.Query() search := query.Get("search") - rows, err := c.DB.QueryContext(ctx, c.SQL.ListTodos(), "%"+search+"%") + stmt, err := c.DB.PrepareContext(ctx, c.SQL.ListTodos()) + if err != nil { + fmt.Println(err) + writeServerErrorResponse(w, "error in prepare statement") + return + } + defer stmt.Close() + + rows, err := stmt.QueryContext(ctx, "%"+search+"%") if err != nil { fmt.Println(err) writeServerErrorResponse(w, "query failed") From c8c0733f30f691a4a673df1229ccfe2ef523e441 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 17:34:30 +0530 Subject: [PATCH 091/108] updated docs --- go/core/README.md | 31 +++++++++---- go/database/sql/README.md | 40 +++++++++------- go/gorrila/mux/README.md | 96 +++++++++++++++++++++++++++++++++++++++ go/net/http/README.md | 68 +++++---------------------- 4 files changed, 154 insertions(+), 81 deletions(-) create mode 100644 go/gorrila/mux/README.md diff --git a/go/core/README.md b/go/core/README.md index 5406a38b..eaec9bad 100644 --- a/go/core/README.md +++ b/go/core/README.md @@ -12,19 +12,34 @@ This is a support package and will be installed indirectly by other go sqlcommen ### Configuration -Users are given control over what tags they want to append by using `core.CommenterOptions` struct. +Users are given control over what tags they want to append by using `core.CommenterConfig` struct. ```go -type CommenterOptions struct { +type CommenterConfig struct { EnableDBDriver bool - EnableTraceparent bool // OpenTelemetry trace information - EnableRoute bool // applicable for web frameworks - EnableFramework bool // applicable for web frameworks - EnableController bool // applicable for web frameworks - EnableAction bool // applicable for web frameworks + EnableRoute bool + EnableFramework bool + EnableController bool + EnableAction bool + EnableTraceparent bool EnableApplication bool - Application string // user-provided application-name. optional } ``` +Users can also set the values for some static tags by using `core.StaticTags` struct. + +```go +type StaticTags struct { + Application string + DriverName string +} +``` +These two structs together form the `core.CommenterOptions` struct, which is used by [sqlcommenter/go/database/sql](../database/sql/README.md). + +```go +type CommenterOptions struct { + Config CommenterConfig + Tags StaticTags +} +``` \ No newline at end of file diff --git a/go/database/sql/README.md b/go/database/sql/README.md index 1a3d71dc..9459083d 100644 --- a/go/database/sql/README.md +++ b/go/database/sql/README.md @@ -1,22 +1,12 @@ -# go-sql-driver [In development] +# go-sql-driver SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. ## Installation -### Install from source - -* Clone the source -* In terminal go inside the client folder location where we need to import sqlcommenter go-sql module and enter the below commands - ```shell -go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/go-sql - -go mod tiny - -go get google.com/sqlcommenter/gosql +go get -u github.com/google/sqlcommenter/go/database/sql ``` -### Install from github [To be added] ## Usage @@ -24,7 +14,16 @@ Please use the sqlcommenter's default go-sql database driver to execute statemen Due to inherent nature of Go, the safer way to pass information from framework to database driver is via `context`. So, it is recommended to use the context based methods of `DB` interface like `QueryContext`, `ExecContext` and `PrepareContext`. ```go -db, err := gosql.Open("", "", sqlcommenter.CommenterOptions{:}) +import ( + gosql "github.com/google/sqlcommenter/go/database/sql" + sqlcommentercore "github.com/google/sqlcommenter/go/core" + _ "github.com/lib/pq" // or any other database driver +) + +db, err := gosql.Open("", "", sqlcommentercore.CommenterOptions{ + Config: sqlcommentercore.CommenterConfig{:bool} + Tags : sqlcommentercore.StaticTags{: string} // optional +}) ``` ### Configuration @@ -40,15 +39,24 @@ type CommenterOptions struct { EnableController bool // applicable for web frameworks EnableAction bool // applicable for web frameworks EnableApplication bool // applicable for web frameworks - Application string // user-provided application-name. optional - } +} +``` + +Users can also provide static tags they want to use by using `core.StaticTags` struct. These tags are optional + +```go +type StaticTags struct { + Application string + DriverName string +} ``` The driver will try to use the module-name from the project's `go.mod` as the application name if `EnableApplication` is `true` and no `Application` string is provided (works correctly for compiled go applications). ### Framework Supported -* [http/net](.../../../http-net/README.md) +* [http/net](../../net/http/README.md) - basic support +* [gorrila/mux](../../gorrila//mux/README.md) - proper support ## Options diff --git a/go/gorrila/mux/README.md b/go/gorrila/mux/README.md new file mode 100644 index 00000000..afd09ac0 --- /dev/null +++ b/go/gorrila/mux/README.md @@ -0,0 +1,96 @@ +# go-sql-driver + +SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. + +## Installation + +```shell +go get -u github.com/google/sqlcommenter/go/gorrila/mux +``` + +## Usage + +This library provides a middleware that extracts SQLCommenter HTTP request tags from a request being handled by `gorrila/mux` and attaches them to the request's context. This same context, when used to run queries using [sqlcommenter/go/database/sql](../../database/sql/README.md), allows request tags and traceparent (if using the [otelmux](https://github.com/open-telemetry/opentelemetry-go-contrib/tree/main/instrumentation/github.com/gorilla/mux/otelmux)) to be passed into SQL comments. + + +## Example + +```go +import ( + "net/http" + + sqlcommentermux "github.com/google/sqlcommenter/go/gorrila/mux" + "github.com/gorilla/mux" +) + +func runApp() { + r := mux.NewRouter() + r.Use(sqlcommentermux.SQLCommenterMiddleware) + + r.HandleFunc("/", ActionHome).Methods("GET") + + http.ListenAndServe(":8081", r) +} +``` + +## Example (with otelmux) + +```go +import ( + "context" + "log" + "net/http" + + sqlcommentermux "github.com/google/sqlcommenter/go/gorrila/mux" + "github.com/gorilla/mux" + "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" + "go.opentelemetry.io/otel" + stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/otel/propagation" + sdktrace "go.opentelemetry.io/otel/sdk/trace" +) + +func main() { + tp, err := initTracer() + if err != nil { + log.Fatal(err) + } + defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) + } + }() + + r := mux.NewRouter() + r.Use(otelmux.Middleware("sqlcommenter sample-server"), sqlcommentermux.SQLCommenterMiddleware) + + r.HandleFunc("/", ActionHome).Methods("GET") + + http.ListenAndServe(":8081", r) +} + +func initTracer() (*sdktrace.TracerProvider, error) { + exporter, err := stdout.New(stdout.WithPrettyPrint()) + if err != nil { + return nil, err + } + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithBatcher(exporter), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + return tp, nil +} +``` + +## Options + +With Go SqlCommenter, we have configuration to choose which tags to be appended to the comment. + +| Options | Included by default? | gorrila/mux | +| --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `Action` | | name of the handler function | +| `Route` | | [routing path](https://pkg.go.dev/github.com/gorilla/mux#Route.GetPathTemplate) | +| `Framework` | | gorrila/mux | +| `Opentelemetry` | | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | diff --git a/go/net/http/README.md b/go/net/http/README.md index 6c148954..612fa89f 100644 --- a/go/net/http/README.md +++ b/go/net/http/README.md @@ -1,71 +1,25 @@ -# http-net [In development] +# SQLCommenter http-net [In development] SQLcommenter is a plugin/middleware/wrapper to augment application related information/tags with SQL Statements that can be used later to correlate user code with SQL statements. ## Installation -### Install from source - -* Clone the source -* In terminal go inside the client folder location where we need to import sqlcommenter http/net module and enter the below commands - -```shell -go mod edit -replace google.com/sqlcommenter=path/to/google/sqlcommenter/http-net - -go mod tiny - -go get google.com/sqlcommenter/http-net +```bash +go get -u github.com/google/sqlcommenter/go/net/http ``` -### Install from github [To be added] ## Usage -Please use the sqlcommenter's default go-sql database driver to execute statements. \ -Due to inherent nature of Go, the safer way to pass information from framework to database driver is via `context`. So, it is recommended to use the context based methods of `DB` interface like `QueryContext`, `ExecContext` and `PrepareContext`. - -```go -db, err := gosql.Open("", "", sqlcommenter.CommenterOptions{:}) -``` - -### Configuration - -Users are given control over what tags they want to append by using `core.CommenterOptions` struct. +This is a low-level package that can be used to prepare SQLCommeneterTags out of an http request. The core package can then be used to inject these tags into a context ```go -type CommenterOptions struct { - EnableDBDriver bool - EnableTraceparent bool // OpenTelemetry trace information - EnableRoute bool // applicable for web frameworks - EnableFramework bool // applicable for web frameworks - EnableController bool // applicable for web frameworks - EnableAction bool // applicable for web frameworks - } -``` - +import ( + sqlcommenterhttp "github.com/google/sqlcommenter/go/net/http" +) -#### Note -* We only support the `database/sql` driver and have provided an implementation for that. -* ORM related tags are added to the driver only when the tags are enabled in the commenter's driver's config and also the request context should passed to the querying functions -* The middleware implementing this sqlcommenter http-net module should be added at the last - -#### Example -```go -// middleware is used to intercept incoming HTTP calls and populate request context with commenter tags. -func middleware(next http.Handler) http.Handler { - return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - ctx := httpnet.NewHttpNet(r, next).AddTags(r.Context()) - next.ServeHTTP(w, r.WithContext(ctx)) - }) -} +requestTags := sqlcommenterhttp.NewHTTPRequestTags(framework string, route string, action string) +ctx := core.ContextInject(request.Context(), requestTags) +requestWithTags := request.WithContext(ctx) ``` -## Options - -With Go SqlCommenter, we have configuration to choose which tags to be appended to the comment. - -| Options | Included by default? | net/http | -| --------------- | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `Action` | | [net/http handle](https://pkg.go.dev/net/http#Handle) | -| `Route` | | [net/http routing path](https://pkg.go.dev/github.com/gorilla/mux#Route.URLPath) | -| `Framework` | | [net/http](https://pkg.go.dev/net/http) | -| `Opentelemetry` | | [W3C TraceContext.Traceparent](https://www.w3.org/TR/trace-context/#traceparent-field), [W3C TraceContext.Tracestate](https://www.w3.org/TR/trace-context/#tracestate-field) | +This package can be used to instrument SQLCommenter for various frameworks. \ No newline at end of file From 41431ddfb00b273356be7ba221dcbb8fea47af08 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Wed, 23 Nov 2022 17:45:02 +0530 Subject: [PATCH 092/108] docs fixes --- go/core/README.md | 22 ++++++------- go/database/sql/README.md | 30 ++++++++--------- go/gorrila/mux/README.md | 68 +++++++++++++++++++-------------------- go/net/http/README.md | 2 +- 4 files changed, 61 insertions(+), 61 deletions(-) diff --git a/go/core/README.md b/go/core/README.md index eaec9bad..98ddf424 100644 --- a/go/core/README.md +++ b/go/core/README.md @@ -16,13 +16,13 @@ Users are given control over what tags they want to append by using `core.Commen ```go type CommenterConfig struct { - EnableDBDriver bool - EnableRoute bool - EnableFramework bool - EnableController bool - EnableAction bool - EnableTraceparent bool - EnableApplication bool + EnableDBDriver bool + EnableRoute bool + EnableFramework bool + EnableController bool + EnableAction bool + EnableTraceparent bool + EnableApplication bool } ``` @@ -30,8 +30,8 @@ Users can also set the values for some static tags by using `core.StaticTags` st ```go type StaticTags struct { - Application string - DriverName string + Application string + DriverName string } ``` @@ -39,7 +39,7 @@ These two structs together form the `core.CommenterOptions` struct, which is use ```go type CommenterOptions struct { - Config CommenterConfig - Tags StaticTags + Config CommenterConfig + Tags StaticTags } ``` \ No newline at end of file diff --git a/go/database/sql/README.md b/go/database/sql/README.md index 9459083d..459fdf41 100644 --- a/go/database/sql/README.md +++ b/go/database/sql/README.md @@ -15,14 +15,14 @@ Due to inherent nature of Go, the safer way to pass information from framework t ```go import ( - gosql "github.com/google/sqlcommenter/go/database/sql" - sqlcommentercore "github.com/google/sqlcommenter/go/core" - _ "github.com/lib/pq" // or any other database driver + gosql "github.com/google/sqlcommenter/go/database/sql" + sqlcommentercore "github.com/google/sqlcommenter/go/core" + _ "github.com/lib/pq" // or any other database driver ) db, err := gosql.Open("", "", sqlcommentercore.CommenterOptions{ - Config: sqlcommentercore.CommenterConfig{:bool} - Tags : sqlcommentercore.StaticTags{: string} // optional + Config: sqlcommentercore.CommenterConfig{:bool} + Tags : sqlcommentercore.StaticTags{: string} // optional }) ``` @@ -32,22 +32,22 @@ Users are given control over what tags they want to append by using `core.Commen ```go type CommenterOptions struct { - EnableDBDriver bool - EnableTraceparent bool // OpenTelemetry trace information - EnableRoute bool // applicable for web frameworks - EnableFramework bool // applicable for web frameworks - EnableController bool // applicable for web frameworks - EnableAction bool // applicable for web frameworks - EnableApplication bool // applicable for web frameworks + EnableDBDriver bool + EnableTraceparent bool // OpenTelemetry trace information + EnableRoute bool // applicable for web frameworks + EnableFramework bool // applicable for web frameworks + EnableController bool // applicable for web frameworks + EnableAction bool // applicable for web frameworks + EnableApplication bool // applicable for web frameworks } ``` -Users can also provide static tags they want to use by using `core.StaticTags` struct. These tags are optional +Users can also provide static tags they want to use by using `core.StaticTags` struct. These tags are optional. If not provided, the `Application` tag will get auto-populated from the user-project's module-name in `go.mod`. `DriverName` is set to the driver-name provided in `gosql.Open(driverName, ...)` call. ```go type StaticTags struct { - Application string - DriverName string + Application string + DriverName string } ``` diff --git a/go/gorrila/mux/README.md b/go/gorrila/mux/README.md index afd09ac0..0e533a9e 100644 --- a/go/gorrila/mux/README.md +++ b/go/gorrila/mux/README.md @@ -20,14 +20,14 @@ import ( "net/http" sqlcommentermux "github.com/google/sqlcommenter/go/gorrila/mux" - "github.com/gorilla/mux" + "github.com/gorilla/mux" ) func runApp() { - r := mux.NewRouter() - r.Use(sqlcommentermux.SQLCommenterMiddleware) + r := mux.NewRouter() + r.Use(sqlcommentermux.SQLCommenterMiddleware) - r.HandleFunc("/", ActionHome).Methods("GET") + r.HandleFunc("/", ActionHome).Methods("GET") http.ListenAndServe(":8081", r) } @@ -38,49 +38,49 @@ func runApp() { ```go import ( "context" - "log" - "net/http" + "log" + "net/http" sqlcommentermux "github.com/google/sqlcommenter/go/gorrila/mux" - "github.com/gorilla/mux" - "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" - "go.opentelemetry.io/otel" - stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" - "go.opentelemetry.io/otel/propagation" - sdktrace "go.opentelemetry.io/otel/sdk/trace" + "github.com/gorilla/mux" + "go.opentelemetry.io/contrib/instrumentation/github.com/gorilla/mux/otelmux" + "go.opentelemetry.io/otel" + stdout "go.opentelemetry.io/otel/exporters/stdout/stdouttrace" + "go.opentelemetry.io/otel/propagation" + sdktrace "go.opentelemetry.io/otel/sdk/trace" ) func main() { tp, err := initTracer() - if err != nil { - log.Fatal(err) - } - defer func() { - if err := tp.Shutdown(context.Background()); err != nil { - log.Printf("Error shutting down tracer provider: %v", err) - } - }() + if err != nil { + log.Fatal(err) + } + defer func() { + if err := tp.Shutdown(context.Background()); err != nil { + log.Printf("Error shutting down tracer provider: %v", err) + } + }() - r := mux.NewRouter() - r.Use(otelmux.Middleware("sqlcommenter sample-server"), sqlcommentermux.SQLCommenterMiddleware) + r := mux.NewRouter() + r.Use(otelmux.Middleware("sqlcommenter sample-server"), sqlcommentermux.SQLCommenterMiddleware) - r.HandleFunc("/", ActionHome).Methods("GET") + r.HandleFunc("/", ActionHome).Methods("GET") http.ListenAndServe(":8081", r) } func initTracer() (*sdktrace.TracerProvider, error) { - exporter, err := stdout.New(stdout.WithPrettyPrint()) - if err != nil { - return nil, err - } - tp := sdktrace.NewTracerProvider( - sdktrace.WithSampler(sdktrace.AlwaysSample()), - sdktrace.WithBatcher(exporter), - ) - otel.SetTracerProvider(tp) - otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) - return tp, nil + exporter, err := stdout.New(stdout.WithPrettyPrint()) + if err != nil { + return nil, err + } + tp := sdktrace.NewTracerProvider( + sdktrace.WithSampler(sdktrace.AlwaysSample()), + sdktrace.WithBatcher(exporter), + ) + otel.SetTracerProvider(tp) + otel.SetTextMapPropagator(propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{})) + return tp, nil } ``` diff --git a/go/net/http/README.md b/go/net/http/README.md index 612fa89f..2268dfd9 100644 --- a/go/net/http/README.md +++ b/go/net/http/README.md @@ -14,7 +14,7 @@ This is a low-level package that can be used to prepare SQLCommeneterTags out of ```go import ( - sqlcommenterhttp "github.com/google/sqlcommenter/go/net/http" + sqlcommenterhttp "github.com/google/sqlcommenter/go/net/http" ) requestTags := sqlcommenterhttp.NewHTTPRequestTags(framework string, route string, action string) From ad52f05b91a4514913d0d01e0ee761dd11d66e94 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 12:53:40 +0530 Subject: [PATCH 093/108] gh-pages workflow --- .github/workflows/gh-pages.yaml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 .github/workflows/gh-pages.yaml diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml new file mode 100644 index 00000000..056caec2 --- /dev/null +++ b/.github/workflows/gh-pages.yaml @@ -0,0 +1,32 @@ +name: github pages + +on: + push: + branches: + - gh-pages # Set a branch that will trigger a deployment + pull_request: + +jobs: + deploy: + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v3 + with: + submodules: true # Fetch Hugo themes (true OR recursive) + fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod + + - name: Setup Hugo + uses: peaceiris/actions-hugo@v2 + with: + hugo-version: '0.79' + # extended: true + + - name: Build + run: hugo --minify + + - name: Deploy + uses: peaceiris/actions-gh-pages@v3 + if: github.ref == 'refs/heads/gh-pages' + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./public \ No newline at end of file From 293b864723d374135264dcd53a144414ced54c6f Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 12:57:23 +0530 Subject: [PATCH 094/108] hugo-version latest --- .github/workflows/gh-pages.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 056caec2..238dcded 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -5,6 +5,8 @@ on: branches: - gh-pages # Set a branch that will trigger a deployment pull_request: + branches: + - gh-pages jobs: deploy: @@ -18,7 +20,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - hugo-version: '0.79' + hugo-version: 'latest' # extended: true - name: Build From 22b9c08a8e95bf9c4ecc78b7049e3a7accf7a157 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:00:34 +0530 Subject: [PATCH 095/108] hugo-version 0.79.1 --- .github/workflows/gh-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 238dcded..65ee121f 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -20,7 +20,7 @@ jobs: - name: Setup Hugo uses: peaceiris/actions-hugo@v2 with: - hugo-version: 'latest' + hugo-version: '0.79.1' # extended: true - name: Build From 7ec529efced1ed427ad2fabb63907a8ce7fb0aad Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:07:54 +0530 Subject: [PATCH 096/108] workflow_dispatch --- .github/workflows/gh-pages.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 65ee121f..635fdfb8 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -7,6 +7,7 @@ on: pull_request: branches: - gh-pages + workflow_dispatch jobs: deploy: From 8dfcbcd7721553a0147a8e70259b6d0d89a0b17d Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:17:52 +0530 Subject: [PATCH 097/108] workflow_dispatch: --- .github/workflows/gh-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 635fdfb8..bce04186 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -7,7 +7,7 @@ on: pull_request: branches: - gh-pages - workflow_dispatch + workflow_dispatch: jobs: deploy: From e6bd9fb774d48afa1540e262dd3e9915fa457815 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:28:34 +0530 Subject: [PATCH 098/108] github pages workflow fix --- .github/workflows/gh-pages.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index bce04186..0489984c 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -15,6 +15,7 @@ jobs: steps: - uses: actions/checkout@v3 with: + ref: gh-pages submodules: true # Fetch Hugo themes (true OR recursive) fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod From 68a0e73a3f2405f1166a3c39715c0a15582f6ebb Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:31:15 +0530 Subject: [PATCH 099/108] github pages workflow fix --- .github/workflows/gh-pages.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 0489984c..7a9f7c58 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -26,7 +26,7 @@ jobs: # extended: true - name: Build - run: hugo --minify + run: cd src && hugo --minify - name: Deploy uses: peaceiris/actions-gh-pages@v3 From 114328861d322a5eee2e1beecd26078cef306200 Mon Sep 17 00:00:00 2001 From: Kapil Verma Date: Mon, 5 Dec 2022 13:35:22 +0530 Subject: [PATCH 100/108] github pages workflow fix --- .github/workflows/gh-pages.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/gh-pages.yaml b/.github/workflows/gh-pages.yaml index 7a9f7c58..6865261b 100644 --- a/.github/workflows/gh-pages.yaml +++ b/.github/workflows/gh-pages.yaml @@ -26,11 +26,11 @@ jobs: # extended: true - name: Build - run: cd src && hugo --minify + run: cd src && hugo --minify && cd .. - name: Deploy uses: peaceiris/actions-gh-pages@v3 if: github.ref == 'refs/heads/gh-pages' with: github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./public \ No newline at end of file + publish_dir: . \ No newline at end of file From 36ce7d3bcd80b0700907fa7eb93a108df7a598c6 Mon Sep 17 00:00:00 2001 From: Lucas Swart Date: Thu, 8 Dec 2022 04:19:21 -0800 Subject: [PATCH 101/108] Ruby on Rails documentation updates (#169) --- ruby/sqlcommenter-ruby/README.md | 20 ++++++++++++++++++- .../sqlcommenter_rails/README.md | 3 +++ .../sqlcommenter_rails_demo/README.md | 3 +++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/ruby/sqlcommenter-ruby/README.md b/ruby/sqlcommenter-ruby/README.md index 26380a40..2ca1b82f 100644 --- a/ruby/sqlcommenter-ruby/README.md +++ b/ruby/sqlcommenter-ruby/README.md @@ -1 +1,19 @@ -# sqlcommenter-ruby \ No newline at end of file +# SQLCommenter in Ruby + +## SQLCommenter support in Rails + + +Support for [SQLCommenter](https://google.github.io/sqlcommenter/) in [Ruby on Rails](https://rubyonrails.org/) varies, depending on your versions of Rails. + +If you are on Rails version: + + - **7.1 and above:** SQLCommenter is supported by default. Enable [query_log_tags](https://guides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-enabled), and SQLCommenter formatting will be [enabled by default](https://edgeguides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-format). + - **7.0:** Enable [query_log_tags](https://guides.rubyonrails.org/configuring.html#config-active-record-query-log-tags-enabled) and install the [PlanetScale SQLCommenter gem](https://github.com/planetscale/activerecord-sql_commenter#installation) for SQLCommenter support. + - **Below 7.0:** Refer to the [sqlcommenter_rails gem](https://github.com/google/sqlcommenter/tree/master/ruby/sqlcommenter-ruby/sqlcommenter_rails) in this directory for adding SQLCommenter support. Note that this requires additional work because you will have to install a fork of the [marginalia](https://github.com/basecamp/marginalia/) gem, which has since been consolidated into Rails 7.0 and up. + +## Tracing support in Rails + +Tracing support has been implemented in the [marginalia-opencensus gem]: https://github.com/google/sqlcommenter/tree/master/ruby/sqlcommenter-ruby/marginalia-opencensus. Note that this only works for Rails versions below 7.0, before the [marginalia](https://github.com/basecamp/marginalia/) gem was consolidated into Rails. + +Re-purposing that gem for Rails versions >=7.0 should only require minor modifications (contributions are welcome!). + diff --git a/ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md b/ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md index dc30dd3d..f8f57ef8 100644 --- a/ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md +++ b/ruby/sqlcommenter-ruby/sqlcommenter_rails/README.md @@ -1,5 +1,7 @@ # sqlcommenter_rails +**If you are on Rails version 7.0 and up, refer to the [sqlcommenter-ruby README] instead** + [sqlcommenter] for [Ruby on Rails]. Powered by [marginalia] and [marginalia-opencensus]. @@ -8,6 +10,7 @@ Powered by [marginalia] and [marginalia-opencensus]. [Ruby on Rails]: https://rubyonrails.org/ [marginalia]: https://github.com/basecamp/marginalia/ [marginalia-opencensus]: https://github.com/google/sqlcommenter/tree/master/ruby/sqlcommenter-ruby/marginalia-opencensus +[sqlcommenter-ruby README]: https://github.com/google/sqlcommenter/tree/master/ruby/sqlcommenter-ruby ## Installation diff --git a/ruby/sqlcommenter-ruby/sqlcommenter_rails_demo/README.md b/ruby/sqlcommenter-ruby/sqlcommenter_rails_demo/README.md index cdb5e2aa..9c7491ec 100644 --- a/ruby/sqlcommenter-ruby/sqlcommenter_rails_demo/README.md +++ b/ruby/sqlcommenter-ruby/sqlcommenter_rails_demo/README.md @@ -1,9 +1,12 @@ # sqlcommenter_rails demo +**If you are on Rails version 7.0 and up, refer to the [sqlcommenter-ruby README] instead** + This is a demo [Rails API] application to demonstrate [sqlcommenter_rails] integration. [Rails API]: https://guides.rubyonrails.org/api_app.html [sqlcommenter_rails]: https://github.com/google/sqlcommenter/ruby/sqlcommenter-ruby/sqlcommenter_rails +[sqlcommenter-ruby README]: https://github.com/google/sqlcommenter/tree/master/ruby/sqlcommenter-ruby ## Setup From 0579a4ad9652d34001c19895a387a397958780dd Mon Sep 17 00:00:00 2001 From: Kostya Ostrovsky Date: Thu, 15 Dec 2022 17:35:25 +0200 Subject: [PATCH 102/108] Always escape values in comments as per specification (#217) * Always escape values in comments as per specification * escape --- go/core/core.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/go/core/core.go b/go/core/core.go index 6fca682a..c2d30696 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -57,7 +57,7 @@ type CommenterOptions struct { } func encodeURL(k string) string { - return url.QueryEscape(string(k)) + return url.QueryEscape(k) } func GetFunctionName(i interface{}) string { @@ -71,7 +71,7 @@ func ConvertMapToComment(tags map[string]string) string { var sb strings.Builder i, sz := 0, len(tags) - //sort by keys + // sort by keys sortedKeys := make([]string, 0, len(tags)) for k := range tags { sortedKeys = append(sortedKeys, k) @@ -80,9 +80,9 @@ func ConvertMapToComment(tags map[string]string) string { for _, key := range sortedKeys { if i == sz-1 { - sb.WriteString(fmt.Sprintf("%s=%v", encodeURL(key), encodeURL(tags[key]))) + sb.WriteString(fmt.Sprintf("%s='%s'", encodeURL(key), encodeURL(tags[key]))) } else { - sb.WriteString(fmt.Sprintf("%s=%v,", encodeURL(key), encodeURL(tags[key]))) + sb.WriteString(fmt.Sprintf("%s='%s',", encodeURL(key), encodeURL(tags[key]))) } i++ } From b8c31ec9ab4197e4be741fdeb0c2a079963786df Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Tue, 20 Dec 2022 11:43:55 +0530 Subject: [PATCH 103/108] Add comments and unittests to go-sqlcommenter-core (#218) --- go/core/core.go | 35 +++++++++++---- go/core/core_test.go | 101 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 127 insertions(+), 9 deletions(-) create mode 100644 go/core/core_test.go diff --git a/go/core/core.go b/go/core/core.go index c2d30696..5a35e61a 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -22,20 +22,23 @@ import ( "runtime" "sort" "strings" - - "go.opentelemetry.io/otel/propagation" ) +// Constants used as key string for tags. +// It is not necessary that all SQLCommenter frameworks/ORMs will contain all these keys i.e. +// it is on best-effort basis. const ( Route string = "route" - Controller string = "controller" - Action string = "action" - Framework string = "framework" - Driver string = "db_driver" - Traceparent string = "traceparent" - Application string = "application" + Controller = "controller" + Action = "action" + Framework = "framework" + Driver = "db_driver" + Traceparent = "traceparent" + Application = "application" ) +// CommenterConfig contains configurations for SQLCommenter library. +// We can enable and disable certain tags by enabling these configurations. type CommenterConfig struct { EnableDBDriver bool EnableRoute bool @@ -46,11 +49,15 @@ type CommenterConfig struct { EnableApplication bool } +// StaticTags are few tags that can be set by the application and will be constant +// for every API call. type StaticTags struct { Application string DriverName string } +// CommenterOptions contains all options regarding SQLCommenter library. +// This includes the configurations as well as any static tags. type CommenterOptions struct { Config CommenterConfig Tags StaticTags @@ -60,13 +67,19 @@ func encodeURL(k string) string { return url.QueryEscape(k) } -func GetFunctionName(i interface{}) string { +// GetFunctionName returns the name of the function passed. +func GetFunctionName(i any) string { if i == nil { return "" } return runtime.FuncForPC(reflect.ValueOf(i).Pointer()).Name() } +// ConvertMapToComment returns a comment string given a map of key-value pairs of tags. +// There are few steps involved here: +// - Sorting the tags by key string +// - url encoding the key value pairs +// - Formatting the key value pairs as "key1=value1,key2=value2" format. func ConvertMapToComment(tags map[string]string) string { var sb strings.Builder i, sz := 0, len(tags) @@ -89,6 +102,7 @@ func ConvertMapToComment(tags map[string]string) string { return sb.String() } +// ExtractTraceparent extracts the traceparent field using OpenTelemetry library. func ExtractTraceparent(ctx context.Context) propagation.MapCarrier { // Serialize the context into carrier textMapPropogator := propagation.NewCompositeTextMapPropagator(propagation.TraceContext{}, propagation.Baggage{}) @@ -97,12 +111,15 @@ func ExtractTraceparent(ctx context.Context) propagation.MapCarrier { return carrier } +// RequestTagsProvider adds a basic interface for other libraries like gorilla/mux to implement. type RequestTagsProvider interface { Route() string Action() string Framework() string } +// ContextInject injects the tags key-value pairs into context, +// which can be later passed into drivers/ORMs to finally inject them into SQL queries. func ContextInject(ctx context.Context, h RequestTagsProvider) context.Context { ctx = context.WithValue(ctx, Route, h.Route()) ctx = context.WithValue(ctx, Action, h.Action()) diff --git a/go/core/core_test.go b/go/core/core_test.go new file mode 100644 index 00000000..fb33c515 --- /dev/null +++ b/go/core/core_test.go @@ -0,0 +1,101 @@ +package core + +import ( + "context" + "testing" +) + +func TestConvertMapToComment(t *testing.T) { + for _, tc := range []struct { + desc string + tagMap map[string]string + want string + }{ + { + desc: "nil tagMap", + want: "", + }, + { + desc: "no tags", + tagMap: map[string]string{}, + want: "", + }, + { + desc: "only one tag", + tagMap: map[string]string{ + Route: "test-route", + }, + want: "route='test-route'", + }, + { + desc: "only one tag with url encoding", + tagMap: map[string]string{ + Route: "test/route", + }, + want: "route='test%2Froute'", + }, + { + desc: "multiple tags", + tagMap: map[string]string{ + Route: "test/route", + Action: "test-action", + Driver: "sql-pg", + }, + want: "action='test-action',db_driver='sql-pg',route='test%2Froute'", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + if got, want := ConvertMapToComment(tc.tagMap), tc.want; got != want { + t.Errorf("ConvertMapToComment(%+v) = %q, want = %q", tc.tagMap, got, want) + } + }) + } +} + +type testRequestProvider struct { + withRoute string + withAction string + withFramework string +} + +func (p *testRequestProvider) Route() string { return p.withRoute } +func (p *testRequestProvider) Action() string { return p.withAction } +func (p *testRequestProvider) Framework() string { return p.withFramework } + +func TestContextInject(t *testing.T) { + tagsProvider := &testRequestProvider{ + withRoute: "test-route", + withAction: "test-action", + withFramework: "test-framework", + } + ctx := context.Background() + gotCtx := ContextInject(ctx, tagsProvider) + + for _, tc := range []struct { + desc string + key string + want string + }{ + { + desc: "fetch action", + key: Action, + want: "test-action", + }, + { + desc: "fetch route", + key: Route, + want: "test-route", + }, + { + desc: "fetch framework", + key: Framework, + want: "test-framework", + }, + } { + t.Run(tc.desc, func(t *testing.T) { + if got, want := gotCtx.Value(tc.key), tc.want; got != want { + t.Errorf("ContextInject(ctx, tagsProvider) context.Value(%q) = %q, want = %q", tc.key, got, tc.want) + } + }) + } +} From 2e81d3076846342ebacb985cb9fc2e609993bd55 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 21 Dec 2022 21:57:15 +0530 Subject: [PATCH 104/108] Update go test pipeline to build and test all libraries (#220) There were few libraries CI missing. So, added them. --- .github/workflows/go-sql-tests.yaml | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/.github/workflows/go-sql-tests.yaml b/.github/workflows/go-sql-tests.yaml index 5f081e3a..d1b4c9cf 100644 --- a/.github/workflows/go-sql-tests.yaml +++ b/.github/workflows/go-sql-tests.yaml @@ -21,11 +21,35 @@ jobs: with: go-version: 1.19 - - name: Build + - name: Build core + run: go build -v ./... + working-directory: ./go/core + + - name: Test core + run: go test -v ./... + working-directory: ./go/core + + - name: Build net/http + run: go build -v ./... + working-directory: ./go/net/http + + - name: Test net/http + run: go test -v ./... + working-directory: ./go/net/http + + - name: Build gorilla/mux + run: go build -v ./... + working-directory: ./go/gorrila/mux + + - name: Test gorilla/mux + run: go test -v ./... + working-directory: ./go/gorrila/mux + + - name: Build database/sql run: go build -v ./... working-directory: ./go/database/sql - - name: Test go-sql + - name: Test database/sql run: go test -v ./... working-directory: ./go/database/sql @@ -42,4 +66,3 @@ jobs: # Verify go fmt standards are used - name: Format run: if [ "$(gofmt -s -l . | wc -l)" -gt 0 ]; then exit 1; fi - From 619477b16652b74cc5d3ace76b8f42f7d2863c68 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Wed, 21 Dec 2022 21:58:31 +0530 Subject: [PATCH 105/108] Fix sqlcommenter go imports (#219) * Fix a missing import * Update sql to use the new core * updated more libraries --- go/core/core.go | 2 ++ go/database/sql/go.mod | 2 +- go/database/sql/go.sum | 2 ++ go/gorrila/mux/go.mod | 2 +- go/gorrila/mux/go.sum | 2 ++ 5 files changed, 8 insertions(+), 2 deletions(-) diff --git a/go/core/core.go b/go/core/core.go index 5a35e61a..beb7207f 100644 --- a/go/core/core.go +++ b/go/core/core.go @@ -22,6 +22,8 @@ import ( "runtime" "sort" "strings" + + "go.opentelemetry.io/otel/propagation" ) // Constants used as key string for tags. diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index b0edf01e..6386f6f0 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -2,7 +2,7 @@ module github.com/google/sqlcommenter/go/database/sql go 1.19 -require github.com/google/sqlcommenter/go/core v0.0.5-beta +require github.com/google/sqlcommenter/go/core v0.1.0 require go.opentelemetry.io/otel v1.11.1 // indirect diff --git a/go/database/sql/go.sum b/go/database/sql/go.sum index 2342027e..73a6f921 100644 --- a/go/database/sql/go.sum +++ b/go/database/sql/go.sum @@ -4,6 +4,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/core v0.1.0 h1:g5jL8HUk2Ko9mMPoCI4jP47dyJhpNyu6E8WmiEhh8OU= +github.com/google/sqlcommenter/go/core v0.1.0/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= diff --git a/go/gorrila/mux/go.mod b/go/gorrila/mux/go.mod index b0129dcb..354f7dce 100644 --- a/go/gorrila/mux/go.mod +++ b/go/gorrila/mux/go.mod @@ -3,7 +3,7 @@ module github.com/google/sqlcommenter/go/gorrila/mux go 1.19 require ( - github.com/google/sqlcommenter/go/core v0.0.5-beta + github.com/google/sqlcommenter/go/core v0.1.0 github.com/google/sqlcommenter/go/net/http v0.0.3-beta github.com/gorilla/mux v1.8.0 ) diff --git a/go/gorrila/mux/go.sum b/go/gorrila/mux/go.sum index c6f852c7..93704cb1 100644 --- a/go/gorrila/mux/go.sum +++ b/go/gorrila/mux/go.sum @@ -4,6 +4,8 @@ github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/core v0.1.0 h1:g5jL8HUk2Ko9mMPoCI4jP47dyJhpNyu6E8WmiEhh8OU= +github.com/google/sqlcommenter/go/core v0.1.0/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= github.com/google/sqlcommenter/go/net/http v0.0.3-beta h1:IE/vO3xKddn/2Bq3k+hSy4CxcEuvE1lUiIDYTXjApzA= github.com/google/sqlcommenter/go/net/http v0.0.3-beta/go.mod h1:duXQQvXZYCX8eQ+XOrlojWF512ltEp1eSKXc/KiS9lg= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= From 3018fe71b8ab356b530391b17efea61047198399 Mon Sep 17 00:00:00 2001 From: Subhrajyoti Date: Thu, 22 Dec 2022 21:30:09 +0530 Subject: [PATCH 106/108] Fix SQLCommenter database/sql test (#221) * Updated database/sql to use core-0.1.2 * Fix SQLCommenter database/sql test * Ran go mod tidy --- go/database/sql/connection_test.go | 12 ++++++------ go/database/sql/go.mod | 2 +- go/database/sql/go.sum | 6 ++---- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go index f5ed0f82..1fcdc9f5 100644 --- a/go/database/sql/connection_test.go +++ b/go/database/sql/connection_test.go @@ -41,7 +41,7 @@ func TestWithComment_NoContext(t *testing.T) { Config: core.CommenterConfig{EnableDBDriver: true}, }, query: "SELECT 1;", - wantQuery: "SELECT 1/*db_driver=database%2Fsql%3A*/;", + wantQuery: "SELECT 1/*db_driver='database%2Fsql%3A'*/;", }, { desc: "enable DBDriver and pass static tag driver name", @@ -50,7 +50,7 @@ func TestWithComment_NoContext(t *testing.T) { Tags: core.StaticTags{DriverName: "postgres"}, }, query: "SELECT 1;", - wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", + wantQuery: "SELECT 1/*db_driver='database%2Fsql%3Apostgres'*/;", }, { desc: "enable DBDriver and pass all static tags", @@ -59,7 +59,7 @@ func TestWithComment_NoContext(t *testing.T) { Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, query: "SELECT 1;", - wantQuery: "SELECT 1/*db_driver=database%2Fsql%3Apostgres*/;", + wantQuery: "SELECT 1/*db_driver='database%2Fsql%3Apostgres'*/;", }, { desc: "enable other tags and pass all static tags", @@ -68,7 +68,7 @@ func TestWithComment_NoContext(t *testing.T) { Tags: core.StaticTags{DriverName: "postgres", Application: "app-1"}, }, query: "SELECT 1;", - wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres*/;", + wantQuery: "SELECT 1/*application='app-1',db_driver='database%2Fsql%3Apostgres'*/;", }, } for _, tc := range testCases { @@ -122,7 +122,7 @@ func TestWithComment_WithContext(t *testing.T) { }, ), query: "SELECT 1;", - wantQuery: "SELECT 1/*application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", + wantQuery: "SELECT 1/*application='app-1',db_driver='database%2Fsql%3Apostgres',framework='custom-golang',route='listData'*/;", }, { desc: "only all options but context contains all tags", @@ -147,7 +147,7 @@ func TestWithComment_WithContext(t *testing.T) { }, ), query: "SELECT 1;", - wantQuery: "SELECT 1/*action=any+action,application=app-1,db_driver=database%2Fsql%3Apostgres,framework=custom-golang,route=listData*/;", + wantQuery: "SELECT 1/*action='any+action',application='app-1',db_driver='database%2Fsql%3Apostgres',framework='custom-golang',route='listData'*/;", }, } for _, tc := range testCases { diff --git a/go/database/sql/go.mod b/go/database/sql/go.mod index 6386f6f0..59afde4e 100644 --- a/go/database/sql/go.mod +++ b/go/database/sql/go.mod @@ -2,7 +2,7 @@ module github.com/google/sqlcommenter/go/database/sql go 1.19 -require github.com/google/sqlcommenter/go/core v0.1.0 +require github.com/google/sqlcommenter/go/core v0.1.2 require go.opentelemetry.io/otel v1.11.1 // indirect diff --git a/go/database/sql/go.sum b/go/database/sql/go.sum index 73a6f921..b2f0d072 100644 --- a/go/database/sql/go.sum +++ b/go/database/sql/go.sum @@ -2,10 +2,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= -github.com/google/sqlcommenter/go/core v0.0.5-beta h1:axqYR1zQCCdRBLnwr/j+ckllBSBJ7uaVdsnANuGzCUI= -github.com/google/sqlcommenter/go/core v0.0.5-beta/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= -github.com/google/sqlcommenter/go/core v0.1.0 h1:g5jL8HUk2Ko9mMPoCI4jP47dyJhpNyu6E8WmiEhh8OU= -github.com/google/sqlcommenter/go/core v0.1.0/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= +github.com/google/sqlcommenter/go/core v0.1.2 h1:UM3jS7JROrPTsJxbLq68PRB34Iq8H3AZQDQUSV7sQWU= +github.com/google/sqlcommenter/go/core v0.1.2/go.mod h1:GORu2htXRC4xtejBzOa4ct1L20pohP81DFNYKdCJI70= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= go.opentelemetry.io/otel v1.11.1 h1:4WLLAmcfkmDk2ukNXJyq3/kiz/3UzCaYq6PskJsaou4= From c447d218a1b8ff628571b22cf4e74f2a6fe2e38a Mon Sep 17 00:00:00 2001 From: Shubham Jain Date: Wed, 22 Mar 2023 01:46:02 +0000 Subject: [PATCH 107/108] #224 Add Docs for spring application properties (#225) --- java/sqlcommenter-java/README.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/java/sqlcommenter-java/README.md b/java/sqlcommenter-java/README.md index d8a4fdd7..7139a6d0 100644 --- a/java/sqlcommenter-java/README.md +++ b/java/sqlcommenter-java/README.md @@ -110,12 +110,35 @@ or alternatively just for a specific method #### Hibernate +##### Hibernate via JPA + If you're using Hibernate via JPA, then you can simply set the `hibernate.session_factory.statement_inspector` configuration property in the `persistence.xml` configuration file: ```xml ``` +##### Hibernate via Spring Application Properties +If you're using Hibernate via Spring application properties(i.e. you have `application.yml` or `application.properties` in your resources folder) +- `application.properties` + +```properties +spring.jpa.properties.hibernate.session_factory.statement_inspector=com.google.cloud.sqlcommenter.schibernate.SCHibernate +``` + +- `application.yml` + +```yml +spring: + jpa: + properties: + hibernate: + session_factory: + statement_inspector: com.google.cloud.sqlcommenter.schibernate.SCHibernate +``` + +##### Hibernate via Spring + If you're using Hibernate via Spring, then you might not use a `persistence.xml` configuration file, in which case, you can set up the `hibernate.session_factory.statement_inspector` configuration property as follows: From 871c1c81e014830c3f5f402a9c63d83823132542 Mon Sep 17 00:00:00 2001 From: duffn <3457341+duffn@users.noreply.github.com> Date: Mon, 22 Jul 2024 09:32:37 -0600 Subject: [PATCH 108/108] fix: Add Go controller comment (#280) --- go/database/sql/connection.go | 4 ++++ go/database/sql/connection_test.go | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/go/database/sql/connection.go b/go/database/sql/connection.go index 2dbb5f1d..d01d09cb 100644 --- a/go/database/sql/connection.go +++ b/go/database/sql/connection.go @@ -101,6 +101,10 @@ func (conn *sqlCommenterConn) withComment(ctx context.Context, query string) str commentsMap[core.Action] = ctx.Value(core.Action).(string) } + if config.EnableController && (ctx.Value(core.Controller) != nil) { + commentsMap[core.Controller] = ctx.Value(core.Controller).(string) + } + // `driver` information should not be coming from framework. // So, explicitly adding that here. if config.EnableDBDriver { diff --git a/go/database/sql/connection_test.go b/go/database/sql/connection_test.go index 1fcdc9f5..d977c829 100644 --- a/go/database/sql/connection_test.go +++ b/go/database/sql/connection_test.go @@ -147,7 +147,7 @@ func TestWithComment_WithContext(t *testing.T) { }, ), query: "SELECT 1;", - wantQuery: "SELECT 1/*action='any+action',application='app-1',db_driver='database%2Fsql%3Apostgres',framework='custom-golang',route='listData'*/;", + wantQuery: "SELECT 1/*action='any+action',application='app-1',controller='custom-controller',db_driver='database%2Fsql%3Apostgres',framework='custom-golang',route='listData'*/;", }, } for _, tc := range testCases {