From 3f9969856f8bc3ce2687d63623e704bf2698240f Mon Sep 17 00:00:00 2001 From: pmcb55 Date: Thu, 19 Oct 2023 16:33:25 +0100 Subject: [PATCH 1/3] just minor wording or phrasing tweaks --- README.md | 227 ++++++++++++++++++++++++++++-------------------------- 1 file changed, 118 insertions(+), 109 deletions(-) diff --git a/README.md b/README.md index 4da4284..972c372 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ This repository contains code demonstrating how to Extract, Transform, and Load (ETL) into user Pods from various data sources, including publicly -accessible 3rd-party data sources, local files, etc. +accessible 3rd-party data sources, local files, JSON Objects, etc. Developed by [Inrupt, inc](https://www.inrupt.com). @@ -16,32 +16,33 @@ Pods. ## Background To aid in the understanding of Linked Data, which is the foundation for -everything in Solid, we first recommend reading the +everything in Solid, we first recommend reading this [High-level overview of how Solid stores data](docs/LinkedDataOverview/LinkedData-HighLevel.md). ## Quick-start Worksheet -If you want a complete, start-to-finish run through of the entire process of -installing, configuring, testing, and running the ETL Tutorial, then you can -follow our detailed Worksheet instructions [here](docs/Worksheet/Worksheet.md). +If you want a complete but quick, start-to-finish run-through of the entire +process of installing, configuring, testing, and running the ETL Tutorial, then +you can follow our detailed Worksheet instructions +[here](docs/Worksheet/Worksheet.md). The following instructions provide more background, and go into greater detail. ## Install and Run -Since we may not yet wish to publicly publish any of the vocabularies we -develop for this tutorial (namely the vocabularies we create on behalf of +Since you may not yet wish to publicly publish any of the vocabularies we +develop during this tutorial (namely the vocabularies you create on behalf of 3rd-party data sources that don't yet provide RDF vocabularies themselves), we -first need to generate a local `npm` package that bundles together JavaScript -classes representing all the terms from all those vocabularies. +recommend first generating a local `npm` package that bundles together all the +JavaScript classes representing all the terms from all those vocabularies. To do this, we run Inrupt's open-source [Artifact Generator](https://github.com/inrupt/artifact-generator), pointing it at our local configuration YAML file that references all the local vocabularies we wish to use terms from, and that bundles together the generated JavaScript classes that contain constants for all the terms from -each of those vocabularies (which are all located in the +all of those vocabularies (which are all located in the [./resources/Vocab](./resources/Vocab) directory): ```script @@ -55,15 +56,16 @@ faster execution), then you can run it directly: node ../SDK/artifact-generator/src/index.js generate --vocabListFile "resources/Vocab/vocab-etl-tutorial-bundle-all.yml" --outputDirectory "./src/InruptTooling/Vocab/EtlTutorial" --noPrompt --force --publish npmInstallAndBuild ``` -**Note**: during any ETL development, it's generally very common to continue -to re-run the Artifact Generator regularly, for example after any local -vocabulary changes or updates (we can also run it in 'file watcher' mode so -that it runs automatically on any local vocab file changes, which is really -convenient). So since it's a such a regular thing to run, it's generally a -good idea to clone and run the Artifact Generator locally (as that's much -faster than using `npx`). +**Note**: During ETL development generally it's common to re-run the Artifact +Generator regularly, for example after any local vocabulary changes or updates. +We can also keep it running constantly in 'file watcher' mode so that it re-runs +automatically on any local vocab file changes, which can be really convenient. -Now install our ETL Tutorial as normal: +So since it can be run so regularly, it can generally be a good idea to clone +and run the open-source Artifact Generator locally (as that's much faster than +using `npx`). + +Now install our ETL Tutorial: ```script npm install @@ -71,11 +73,11 @@ npm install Finally, execute the units tests to ensure everything is configured correctly: -Note: You can expect to see error output in the console, as we have **_100% +**Note**: You can expect to see error output in the console, as we have **_100% branch code coverage_**, meaning our tests deliberately force lots of error -situations so that we can test that our code correctly handles all these error -situations. What we expect to see is a completely green final Jest report, -with 100% coverage across the board. +situations so that we can test that our code handles all those situations +correctly. What we expect to see is a completely green final Jest report, with +100% coverage across the board. ```script npm test @@ -83,10 +85,10 @@ npm test ## End-2-End tests -We provide multiple forms of End-2-End tests to allow us demonstrate and test -different aspects of the overall ETL process in isolation. This clear -separation also allows us to understand the various different credentials we -generally need for an overall ETL process flow. +We provide multiple forms of End-2-End tests to demonstrate and test different +aspects of the overall ETL process in isolation. This clear separation also +allows you to understand the various different credentials we generally need for +an overall ETL process flow. For all these tests, and indeed when running the actual ETL process 'for real', we only need to create and edit a single local environment file to provide the @@ -94,9 +96,11 @@ various credentials needed. Note however, that all these End-2-End tests, and the ETL process itself, will also all 'pass' without any such environment file at all, as the ETL code -treats loading into Pods or a triplestore as completely optional. So if no -credentials are provided at all, everything will still pass, but you'll see -lots of console output saying Extraction and Loading are being ignored! +actually treats the loading of data into Pods or a triplestore as completely +optional (to allow easy testing of just the Extract phase, or just the +Transformation phase). So even if no credentials are provided at all, everything +will still pass, but you'll see lots of console output saying the Extraction +and/or the Loading phases are being ignored! ### Overview of our End-2-End test suites @@ -111,16 +115,17 @@ being 'ignored': ``` (Without any credentials, we'll see this test successfully Extract data from local copies of 3rd-party data, successfully transform that data into - RDF, and then display that data to the console, but we'll see it ignore - Extraction from 3rd-parties for which we **require** credentials.) -2. Load locally, Transform, and Load to Pods (and/or triplestore): + Linked Data, and then display that data to the console, but we'll see it + ignore Extraction from any 3rd-parties that **require** credentials.) +2. Load locally, Transform, and Load to Pods (and/or a triplestore, if + configured): ```script npm run e2e-test-node-localExtract-TransformLoad ``` (Without any credentials, we'll see this test successfully Extract data from local copies of 3rd-party data, successfully transform that data into - RDF, but then ignore all attempts to Load those resources into any Pod or - triplestore.) + Linked Data, but then ignore all attempts to Load those resources into any + Pod or triplestore.) ### Overview of test suites @@ -129,21 +134,21 @@ Here we describe our test suites in a bit more detail... #### 1. Extract, Transform, and display to console. Tests that connect to each of our 3rd-party data sources to Extract data, -Transform that extracted data into RDF, and then just outputs some of that -data to the console (rather than Loading it anywhere!). This is to demonstrate -and test **_only_** the Extract and Transform stages of the ETL process, and -so for these tests we don't need to configure or setup anything to do with -Solid Pods or triplestores (since we deliberately don't attempt to 'Load' this -Extracted and Transformed data anywhere). +Transform that extracted data into Linked Data, and then just outputs some of +that data to the console (rather than Loading it anywhere!). This is to +demonstrate and test **_only_** the Extract and Transform stages of the ETL +process, and so for these tests we don't need to configure or setup anything to +do with Solid Pods or triplestores (since we deliberately don't attempt to +'Load' this Extracted and Transformed data anywhere yet). #### 2. Load locally, Transform, and Load to Pods (and/or triplestore). Tests that read local copies of 3rd-party data (so in this case, we are deliberately avoiding the need for any credentials to connect to any of our -3rd-party data sources). These tests Transform that local data into RDF, and -attempt to Load that data into a Solid Pod (and optionally a triplestore). In +3rd-party data sources). These tests Transform that local data into Linked Data, +and attempt to Load it into a Solid Pod (and optionally, a triplestore). In other words, this is for demonstrating and testing **_only_** the -Transformation and Loading stages of the ETL process. +Transformation and Loading phases of the ETL process. ### Create a local-only environment file @@ -151,7 +156,7 @@ To run our ETL Tutorial or execute our End-2-End tests for 'real' (i.e., where we attempt to Extract real data from actual 3rd-parties, and/or Load data into real Solid Pods or a triplestore), we need to provide real, valid credentials, i.e., to allow our application to authenticate with the real APIs of our -3rd-party data sources, and/or to allow our application to write RDF data to +3rd-party data sources, and/or to allow our application to write Linked Data to real user's Solid Pods (and/or, optionally, to a triplestore). To allow us do all of this, we simply need to create and configure a single @@ -164,13 +169,14 @@ local environment file, as follows: End-2-End tests, and/or the full ETL process itself). We can now configure this local environment file in various ways, and re-run -our End-2-End test suites to understand all the variations of ETL possible. +our End-2-End test suites to understand all the possible mix-and-match +variations of ETL. ### Loading into a triplestore If you are already familiar with triplestores, then perhaps the easiest option initially is to simply create a new repository in your favorite triplestore -and provide that repository's SPARQL update endpoint to our local environment +and provide that repository's SPARQL update endpoint in your local environment file. If you are not already familiar with triplestores, you can safely ignore this @@ -213,8 +219,8 @@ default inferred triples in all search results)). **Note**: At this stage (i.e., by only configuring our triplestore via the ETL environment file), all triples will be added directly to the `default` Named -Graph. For more information on how to populate Named Graphs-per-user Pod, see -later in this documentation. +Graph. For more information on how to populate separate Named Graphs per user, +see later in this documentation. If your triplestore supports visualizing triples (such as GraphDB), then our data can already be intuitively inspected and navigated by starting at the @@ -228,13 +234,12 @@ any Linked Data Platform (LDP) containment triples (e.g., no `ldp:contains` or Loaded data into a raw triplestore, which has no inherent notion of LDP containment. We'll see later that Loading the same resources into a Solid Pod does result in these containment triples, since they'll have been created by -virtue of Solid servers also being LDP servers (as currently defined in the -Solid specification). +virtue of Solid servers (currently) also being LDP servers. ### Running just Extract and Transform The test suite `e2e/node/ExtractTransform-display.test.ts` tests the -Extraction of data from each of our 3rd-party data sources; Transforms that +Extraction of data from each of our 3rd-party data sources, Transforms that Extracted data into Linked Data, and then displays it to the console for manual, visual verification (i.e., it deliberately does **_not_** attempt to Load this Transformed data anywhere, such as a Solid Pod or a triplestore). @@ -248,12 +253,13 @@ npm run e2e-test-node-ExtractTransform-display **Note**: We can still run these tests without any environment file at all, but the code simply won't attempt any Extraction or Loading. -If the supplied credentials are all valid, you should see data displayed -on-screen, with colorful console output via the [debug](https://www.npmjs.com/package/debug) -library, from all data sources that have configured credentials. Data sources -without credentials are simply ignored, so these tests are convenient for -testing individual data sources in isolation (i.e., simply comment out the -credentials for the other data sources), or collectively. +If the credentials you supplied were all valid, you should see data displayed +on-screen, with colorful console output (via the +[debug](https://www.npmjs.com/package/debug) library) from all data sources that +have configured credentials. Data sources without credentials are simply +ignored, so these tests are convenient for testing individual data sources in +isolation (i.e., simply comment out the credentials for the other data sources), +or collectively. ### Running the ETL process 'for real' @@ -273,42 +279,43 @@ and also the ETL process registration credentials (see **_Note:_** We can also provide within these user-specific credential resources a SPARQL Update endpoint URL for a triplestore, and also a Named -Graph IRI to use as that user's Pod in that triplestore. This allows us to -populate multiple user's data in a single triplestore instance, with each -user's Pod isolated by having its data in its own Named Graph. If no Named -Graph value is provided, then that user's data will be loaded into the -'default' graph of the triplestore, which would only be useful if running the -ETL for a single user (as loading multiple users would just result in each -user overwriting the data of the previously ETL'ed user). +Graph IRI to represent that user's separate 'Pod' within that triplestore +repository. This allows us to populate multiple user's data in a single +triplestore instance, with each user's Pod isolated by having its data in its +own Named Graph. If no Named Graph value is provided, then that user's data will +be loaded into the 'default' graph of the triplestore, which is really only +useful if running the ETL for a single user (as loading multiple users would +just result in each user's data overwriting the data of the previously ETL'ed +user). ## ETL Process -Our ETL process runs as an automated process - one that individual end users -need to specifically grant access to, to allow that process Load data into -their Pods for them. (Note: if an Enterprise provides their end users with +Our ETL process runs as an automated application - one that individual end users +need to specifically grant access to, to allow that application Load data into +their Pods on their behalf. (Note: if an Enterprise provides their users with Pods, then that Pod provisioning phase can automate the granting of that -permission, so the actual end users may never need to take any specific action -here at all). +permission, so the actual end users themselves may never need to take any +specific action here at all). To allow the ETL process to be granted access to any Pod, it needs to have an identifier (i.e., it needs a WebID). The easiest way to do this is simply to create a new Pod for **_your_** ETL Tutorial process. -Note: [YopMail](https://yopmail.com/en/) is a very convenient, easy-to-use +**Note**: [YopMail](https://yopmail.com/en/) is a very convenient, easy-to-use tool that can be used to create 'burner' email addresses for creating development or test accounts. -Note: [Secure Password Generator](https://passwordsgenerator.net/) is a very +**Note**: [Secure Password Generator](https://passwordsgenerator.net/) is a very convenient, easy-to-use tool that can be used to create secure 'burner' passwords for creating development or test accounts. -### Registering the ETL process for each user +### Registering our ETL application for each user -In order for the ETL process to populate any user's Pod, the ETL process must -first be registered. This simple registration process will generate standard -OAuth Client ID and Client Secret values that our ETL tool will use to -authenticate itself to allow it access individual user Pod's to Load their -respective data. +In order for our ETL application to populate any user's Pod, the application +itself must first be registered. This simple registration process will generate +standard OAuth `Client ID` and `Client Secret` values that our application will +use to authenticate itself to allow it access individual user Pod's to Load +their respective data. 1. Go to the `registration` endpoint of the user's Identity Provider. For example, for Pods registered with Inrupt's PodSpaces, that would be: @@ -317,26 +324,27 @@ respective data. https://login.inrupt.com/registration.html ``` -2. Login as the ETL tool user. +2. Login as the ETL user. 3. After successful login, the "Inrupt Application Registration" is redisplayed. -4. In the "Register an app" field, enter a descriptive name for our ETL - application, and click "Register". -5. After registration, store the displayed `Client ID` and `Client Secret` +4. In the "Register an App" field, enter a descriptive name for our ETL + application, and click the "REGISTER" button. +5. After registration, record the displayed `Client ID` and `Client Secret` values, which we'll need in the next step. ### Providing a Turtle credential file for the ETL application -Our ETL process needs credentials with which it can connect to user Pods, so -that (once authorized by each user) it can then load user-specific data into +Our ETL application needs credentials with which it can connect to user Pods, so +that (once authorized by each user) it can then Load user-specific data into those Pods. The easiest way to provide these credentials is to use a local Turtle file. An example Turtle file is provided here: ` resources/CredentialResource/RegisteredApp/example-registered-app-credential.ttl`. -For more detailed instructions, see the [README.md](resources/CredentialResource/RegisteredApp/README.md) -file in that directory. +For more detailed instructions, see the +[README.md](resources/CredentialResource/RegisteredApp/README.md) file in that +directory. ### Providing a Turtle credential file per user @@ -348,15 +356,15 @@ Pod!). 1. Make a copy of the example user credentials Turtle file `resources/CredentialResource/User/example-user-credential.ttl` in the same directory. -2. Rename the copied file using a simple naming convention such as +2. Name the copied file using a simple naming convention such as `user-credential-.ttl`. 3. Repeat this process, once for each user, filling in that user's 3rd-party API and Solid Pod credentials as appropriate for each user (if a user doesn't have credentials for a particular data source simply leave out - those credentials, or provide empty string values - the ETL tool will skip - that data source for that user). + those credentials, or provide empty string values - our ETL application will + skip that data source for that user). -### Executing the ETL process +### Executing the ETL application Make sure the project is successfully compiled to JavaScript: @@ -373,12 +381,12 @@ node dist/index.js runEtl --etlCredentialResource Date: Thu, 19 Oct 2023 16:47:51 +0100 Subject: [PATCH 2/3] use application instead of process, where appropriate --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index 972c372..5c200e2 100644 --- a/README.md +++ b/README.md @@ -203,7 +203,7 @@ never attempts to Load any data anywhere anyway)... npm run e2e-test-node-localExtract-TransformLoad ``` -...you should see console output informing you that our ETL process +...you should see console output informing you that our ETL application successfully Loaded resources into your triplestore repository. If your triplestore is not running, or you provided an incorrect SPARQL Update endpoint, then this test suite should fail (for example, with @@ -261,7 +261,7 @@ ignored, so these tests are convenient for testing individual data sources in isolation (i.e., simply comment out the credentials for the other data sources), or collectively. -### Running the ETL process 'for real' +### Running the ETL application 'for real' To execute the entire ETL process 'for real' (i.e., hitting the 3rd-party APIs and populating real Solid Pods (and optionally also a triplestore)), we run @@ -274,8 +274,8 @@ one per user, configured with that user's API credentials for each of the 3rd-party data sources that that user has access to (each individual user may have credentials for none, some, or all, of the data sources), and also providing their Solid Pod credentials (such as their WebID and storage root, -and also the ETL process registration credentials (see -[below](#registering_the_etl_process_for_each_user))). +and also the ETL application registration credentials (see +[below](#registering_the_etl_application_for_each_user))). **_Note:_** We can also provide within these user-specific credential resources a SPARQL Update endpoint URL for a triplestore, and also a Named @@ -288,7 +288,7 @@ useful if running the ETL for a single user (as loading multiple users would just result in each user's data overwriting the data of the previously ETL'ed user). -## ETL Process +## ETL Application Our ETL process runs as an automated application - one that individual end users need to specifically grant access to, to allow that application Load data into @@ -297,9 +297,9 @@ Pods, then that Pod provisioning phase can automate the granting of that permission, so the actual end users themselves may never need to take any specific action here at all). -To allow the ETL process to be granted access to any Pod, it needs to have an -identifier (i.e., it needs a WebID). The easiest way to do this is simply to -create a new Pod for **_your_** ETL Tutorial process. +To allow the ETL application to be granted access to any Pod, it needs to have +an identifier (i.e., it needs a WebID). The easiest way to do this is simply to +create a new Pod for **_your_** ETL Tutorial application. **Note**: [YopMail](https://yopmail.com/en/) is a very convenient, easy-to-use tool that can be used to create 'burner' email addresses for creating @@ -348,7 +348,7 @@ directory. ### Providing a Turtle credential file per user -We can drive our ETL process using a credential resource per user, and the +We can drive our ETL application using a credential resource per user, and the easiest way to provide these resources is to use local Turtle files - one per user (these could also be stored as resources within each user's individual Pod!). @@ -383,7 +383,7 @@ naming convention you used to name your user credential files in double quote characters, so that any wildcard characters (like asterisks or question marks) will be correctly interpreted. -### Using `ts-node` to speed up running the ETL process repeatedly +### Using `ts-node` to speed up running the ETL application repeatedly Since this project is TypeScript, it can be very convenient to use `ts-node` so that we don't have to repeatedly re-run the TypeScript compilation step. We @@ -666,7 +666,7 @@ from 3rd-parties, see yet defined in the Pod, the user could stipulate they wish to create these Pod-wide preferences based on current preferences they may have set. -- Drive ETL process based on direct user input via the WebApp, to do things +- Drive the ETL process based on direct user input via a WebApp, to do things like: - Manually enter credentials for pre-defined data sources. - Detect discrepancies in preferences between data sources (e.g., user has From dcc5b1c0609d50dc1aadc04c317447acffe3eba6 Mon Sep 17 00:00:00 2001 From: pmcb55 Date: Thu, 19 Oct 2023 21:17:03 +0100 Subject: [PATCH 3/3] further tweaks to docs, ran npm audit, updated test WebID --- docs/Worksheet/Worksheet-Advanced.md | 2 +- docs/Worksheet/Worksheet.md | 166 ++--- package-lock.json | 648 ++++++++++++------ .../dummy-user-credential-user-with-pod.ttl | 2 +- src/applicationSetup.ts | 2 +- 5 files changed, 542 insertions(+), 278 deletions(-) diff --git a/docs/Worksheet/Worksheet-Advanced.md b/docs/Worksheet/Worksheet-Advanced.md index db74861..09de7ec 100644 --- a/docs/Worksheet/Worksheet-Advanced.md +++ b/docs/Worksheet/Worksheet-Advanced.md @@ -109,7 +109,7 @@ npm run e2e-test-node-localExtract-TransformLoad whichever repository you configured your `.env.test.local` to Load data into). - Simply visualize this node: - `https://test.example.com/test-user/profile/card#me` + `https://test.example.com/test-user/webid` - You should be able to intuitively navigate through the ETL-ed data. Make a change to the local Passport data (e.g., in the JSON in diff --git a/docs/Worksheet/Worksheet.md b/docs/Worksheet/Worksheet.md index e3a8927..9c4b32d 100644 --- a/docs/Worksheet/Worksheet.md +++ b/docs/Worksheet/Worksheet.md @@ -1,11 +1,10 @@ # Worksheet for installing, configuring, debugging, and successfully running the ETL Tutorial -This worksheet attempts you walk you through the entire process of installing, -configuring, debugging, and successfully running the ETL Tutorial, from start to -finish. +This worksheet walks you through the entire process of installing, configuring, +debugging, and successfully running the ETL Tutorial, from start to finish. You'll know you've successfully completed this entire process if you can -determine which famous comedian appears in our test user's sample passport +identify the famous comedian that appears as our test user's sample passport photo! ### References @@ -25,21 +24,21 @@ way through this worksheet: ## Pre-requisites 1. Before we run through this process, first ensure you're on at least Node.js - version 14.18: + version 18: ``` $ node --version - v14.18.2 + v18.16.1 $ npm --version - 6.14.15 + 9.5.1 ``` 2. Create a Pod to represent your particular instance of this ETL Tutorial application. We really only need a WebID, but the easiest way to get a WebID is simply to create a Pod. 3. Create a Pod for our test user. This will be the Pod into which we want our - ETL tool to Load data Extracted from multiple 3rd-parties. + ETL application to Load data Extracted from multiple 3rd-parties. --- @@ -80,10 +79,10 @@ git clone git@github.com:inrupt/etl-tutorial.git Run the code generation phase for our local vocabularies (this will generate local TypeScript source code providing convenient constants for all the terms -defined in the local vocabularies that we created to represent concepts from the -sample 3rd-party data sources we Extract from (e.g., for concepts like a +defined in all the local vocabularies that we created to represent concepts from +the sample 3rd-party data sources we Extract from (e.g., for concepts like a Passport, or a passport number, as might be defined by a government Passport -Office; or the concepts related to a person's hobbies): +Office, or the concepts related to a person's hobbies): ``` npx @inrupt/artifact-generator generate --vocabListFile "resources/Vocab/vocab-etl-tutorial-bundle-all.yml" --outputDirectory "./src/InruptTooling/Vocab/EtlTutorial" --noPrompt --force --publish npmInstallAndBuild @@ -124,16 +123,16 @@ we have. **_Note_**: We recommend using `ts-node` to run the remaining commands, as its faster and more convenient. We generally don't recommend installing modules -globally as you'll have problems if multiple applications require modules, like -`ts-node`, to be globally installed, but with different versions, etc. +globally as you'll have problems if multiple applications require modules to be +globally installed, but with different versions, etc. So instead we've provided `ts-node` as a dev dependency of this project, meaning -you can run it conveniently using `npx`, or less convenient by explicitly using -`./node_modules/.bin/ts-node`. All our examples below use `npx`. +you can run it conveniently using `npx` (or less convenient by explicitly using +`./node_modules/.bin/ts-node`). All our examples below use `npx`. Remember that using `ts-node` is completely optional, and if it doesn't install -or run correctly for you, simply replace all references below of `npx ts-node` -with the standard `node` instead. +or run correctly for you, simply replace all the references below to +`npx ts-node` with the standard `node` instead. --- @@ -149,24 +148,24 @@ Now run with the 'runEtl' command, but no arguments yet... npx ts-node src/index.ts runEtl ``` -...and we see that there are two **_required_** arguments needed to run any ETL -job: +...and you'll see that there are two **_required_** arguments needed to run any +ETL job: -- etlCredentialResource - the filename of a local Linked Data resource (e.g., - a Turtle file) containing the required credentials we need for our ETL tool - itself. - This is required since our tool needs to have a valid Access Token that - effectively identifies itself, so that it can then attempt to write data into - the Pods of end users on their behalf (if those users explicitly granted it - permission to do so, of course!). -- localUserCredentialResourceGlob - this is a file pattern that can contain - wildcards (including for subdirectories) that tells our ETL tool what +- `--etlCredentialResource` - the filename of a local Linked Data resource + (e.g., a Turtle file) containing the required credentials we need for our ETL + application itself. + This is required since our application needs to have a valid Access Token that + effectively identifies it so that it can then attempt to write data into + the Pods of end users on their behalf (assuming those users explicitly granted + it permission to do so, of course!). +- `--localUserCredentialResourceGlob` - this is a file pattern that can contain + wildcards (including for subdirectories) that tells our ETL application what local filenames it should search for, expecting matching files to be user credential resources (e.g., Turtle files). - These user credential resources are needed by our tool so that it can log into - potentially multiple 3d-party data sources on behalf of that user to Extract - relevant data that we then Transform into Linked Data, and Load into that - user's Pod. + These user credential resources are needed by our application so that it can + log into potentially multiple 3d-party data sources on behalf of that user to + Extract relevant data that we then Transform into Linked Data, and finally + Load into that user's Pod. Run with our example Turtle configurations (note the use of a wildcard (e.g., an asterisk `*`) in the file pattern for user credentials): @@ -213,23 +212,23 @@ This is totally fine, as, for example, we may only wish our ETL process to populate a Linked Data database (called a triplestore), and not attempt to write to any user Pods at all. -Next our tool searches for local resources matching the file pattern we provided -for user credential resources via the `--localUserCredentialResourceGlob` -command-line argument, and it should find, and successfully parse, two such -local resources. +Next our application searches for local resources matching the file pattern we +provided for user credential resources via the +`--localUserCredentialResourceGlob` command-line argument. It should find, and +successfully parse, two such local resources. For each of the two user credential resources it finds it then: - Attempts to clear out existing user data from the triplestore (but we - haven't configured one yet, so this is ignored). + haven't configured one yet, so this does nothing). - Attempts to clear out existing user data from the current user's Pod (but we - haven't configured them yet, so this is ignored). + haven't configured them yet, so this does nothing). - Creates a dummy ProfileDocument for this user. Even though we didn't attempt - to get an Access Token (via the ETL tool logging into it's IdP), the code - assumes that we **_may_** want to write a triplestore, and so it creates this - dummy resource just in case. + to get an Access Token (via the ETL application logging into it's IdP), the + code assumes that we **_may_** want to write a triplestore, and so it creates + this dummy resource just in case. - Creates a number of ETL Tutorial-specific resources, such as containers - intended to contain all the data we expect we Load into a user's Pod. + intended to contain all the data we expect to Load into a user's Pod. The ETL process then attempts to connect to each of the multiple potential data sources of user data, and for each one attempts to Extract relevant data for the @@ -237,8 +236,8 @@ current user. Data sources that Extract from local files, or from sample in-memory objects, will work fine without any further configuration, but data sources that require -credentials to access real 3rd-party APIs will fail (since we haven't configured -their required credentials yet), and will therefore be ignored. +credentials to access real 3rd-party APIs would fail (since we haven't +configured their required credentials yet), and so are therefore skipped. In each case, writing any successfully Extracted and Transformed resources will not be written to user Pods or a triplestore at this stage, since we haven't @@ -248,7 +247,7 @@ configured those yet! It can be **_extremely_** helpful to visualize the data we are Loading, especially when developing data models for new data sources, which may go -through multiple phases of iteration. +through multiple phases of modelling iteration. Perhaps the most convenient way to do this is using a triplestore (see [here](../VisualizePodData/VisualizeExamplePodData.png) for a screenshot of a @@ -257,24 +256,25 @@ sample Pod with lots of highly inter-related personal data). If you don't already have a triplestore, you can follow the very simple instructions [here](../VisualizePodData/VisualizePodData.md) to install, configure, load, and visualize sample Pod data yourself using a free triplestore -locally in **_less than 10 minutes_**. +in **_less than 10 minutes_**. Once you have a triplestore running (locally or remotely), you can populate -that right away using our ETL tool by simply editing just a single line of a -user's credential resource (or by editing your new local `.env` file - but see -the [Advanced Worksheet](./Worksheet-Advanced.md) for details on that approach). +that right away using our ETL application by simply editing just a single line +of a user's credential resource (or by editing your new local `.env` file - but +see the [Advanced Worksheet](./Worksheet-Advanced.md) for details on that +approach). So assuming that you do have GraphDB installed and running locally, and it's listening on its default port of `7200`, **_and_** that you've already created a -new repository named `inrupt-etl-tutorial`: +new GraphDB repository named `inrupt-etl-tutorial`: ``` # Use gedit, vim, VSCode, or any text editor to edit our sample user resource: gedit ./resources/CredentialResource/User/example-user-credential-1.ttl ``` -...and just uncommenting this line (editing it accordingly to match the port and -repository name in your trplestore): +...and just uncomment this line (editing it accordingly to match the port and +repository name in your triplestore): ``` INRUPT_TRIPLESTORE_ENDPOINT_UPDATE="http://localhost:7200/repositories/inrupt-etl-tutorial/statements" @@ -290,30 +290,31 @@ npx ts-node src/index.ts runEtl --etlCredentialResource "resources/CredentialRes Linked Data as before. - **_But now_** we should also see that data Loaded as Resources from the Passport Office data source and the Hobby data source into the triplestore - (our Companies House data source is still being ignored, as we haven't yet + (our Companies House data source is still being skipped, as we haven't yet configured the necessary API credentials). - To see this data in the triplestore, open GraphDB: - Make sure you select the `inrupt-etl-tutorial` repository (i.e., or whatever repository name you created and configured). - Simply visualize this node: - `https://test.example.com/test-user/profile/card#me` - - You should be able to intuitively navigate through the ETL-ed data. + `https://test.example.com/test-user/webid` + - You should be able to intuitively navigate through all the ETL-ed data. -Make a change, such as extending the passport expiry date, to the local Passport -data (e.g., in the JSON in `src/dataSource/clientPassportInMemory.ts`), and -re-run: +To demonstrate the re-run-ability of the ETL process, now make a simple change, +such as extending the passport expiry date in the local Passport data (e.g., in +the JSON in `src/dataSource/clientPassportInMemory.ts`), and re-run the ETL: ``` npx ts-node src/index.ts runEtl --etlCredentialResource "resources/CredentialResource/RegisteredApp/example-registered-app-credential.ttl" --localUserCredentialResourceGlob "resources/CredentialResource/User/example-user-credential-1.ttl" ``` -...and you should see your change reflected in the data now in the triplestore -when you refresh the visualization. +You should now see your change reflected in the data in the triplestore when you +simply refresh the visualization. ## PHASE 3 - (Optionally) configure Companies House API Our ETL Tutorial also demonstrates accessing a real public 3rd-party API, in -this case the Company Search API from the Companies House in the UK. +this case the Company Search API from the Companies House in the UK, which is +the freely available national registry of every company incorporated in the UK. To use this API, a developer needs to register to get an API Auth Token that allows them to make API requests - see @@ -321,7 +322,7 @@ allows them to make API requests - see for instructions on how to register. For now, and for ease of demonstration, we're going to simply reuse a test Auth -Token provided by your instructor. +Token provided by Inrupt. Edit our single user credentials resource again: @@ -337,19 +338,19 @@ line of the file): inrupt_3rd_party_companies_house_uk:authenticationHttpBasicToken "" . ``` -Now re-run your ETL process: +Now re-run the ETL process: ``` npx ts-node src/index.ts runEtl --etlCredentialResource "resources/CredentialResource/RegisteredApp/example-registered-app-credential.ttl" --localUserCredentialResourceGlob "resources/CredentialResource/User/example-user-credential-1.ttl" ``` -- Now our console output should show local data being Extracted and Transformed - to Linked Data as before. +- Your console output should show local data being Extracted and Transformed to + Linked Data as before. - **_But now_** we should also see data Loaded as Resources from the Companies House data source too. - If we configured a triplestore, we'll also see a new data source container containing multiple resources - one for the company search result, and a - connected resource for that company's registered address (can you + connected resource for that company's registered address. (Can you see which company was searched for, and where it's registered in the UK?) ## PHASE 4 - Registering our ETL Tutorial application @@ -357,8 +358,8 @@ npx ts-node src/index.ts runEtl --etlCredentialResource "resources/CredentialRes Now we'll Register your ETL Tutorial application with the Identity Provider (IdP) you used to create its Pod. This registration process will provide us with standard OAuth `ClientID` and `ClientSecret` values, which we can then use to -configure your ETL process to allow it to login automatically (i.e., without any -human intervention whatsoever). +configure your ETL application to allow it to log into it's IDP automatically +(i.e., without any human intervention whatsoever). **_Note_**: This is just the standard OAuth Client Credentials flow. @@ -376,9 +377,9 @@ Record the resulting `ClientID` and `ClientSecret` values (using a password manager, or our simple credentials template from the pre-requisites section above). -## PHASE 5 - Configure our ETL's `ClientId` and `ClientSecret` values +## PHASE 5 - Configure your ETL's `ClientId` and `ClientSecret` values -Now we simply edit our ETL Credentials resource to add the `ClientId` and +Now you need to edit your ETL Credentials resource to add the `ClientId` and `ClientSecret` values. ``` @@ -406,10 +407,12 @@ Solid Pod. The login will result in our application's WebID being displayed in the console output. But later in the process, we should see that we fail to find a valid Storage -Root configuration for our test user. This is simply because we still haven't -configured our test users credentials - so let's do that now... +Root configuration for our test user - but this is simply because we still +haven't configured our test users credentials. -## PHASE 6 - Configure our test users WebID and StorageRoot +So let's go do that now... + +## PHASE 6 - Configure our test user's WebID and StorageRoot Edit our user credentials resource again: @@ -437,15 +440,17 @@ This time we should see a different failure. This time it's a `403 Forbidden` error, **_which is exactly what we should expect!_** This test user has not yet granted permission for our ETL Tutorial application -to write to their Pod! So let's go do that now... +to write to their Pod! + +So let's go do that now... ## PHASE 7 - Test user granting permission to our ETL Tutorial application For this operation, we're going to use Inrupt's open-source PodBrowser tool. -In a **_new Incognito window_** (make sure you don't have any other Incognito +Open a **_new Incognito window_** (make sure you don't have any other Incognito windows open, as session state is shared even for Incognito tabs, across browser -instances!), go to: `https://podbrowser.inrupt.com/`. +instances!), and go to: `https://podbrowser.inrupt.com/`. --- @@ -479,7 +484,8 @@ Click the `ADD` button, then the `SAVE EDITORS` button, confirm the action, and we should see the ETL Tutorial application's WebID appear as an Editor of this `private` container resource in our test user's Pod. -Finally, re-run your ETL process again. This time we should have no failures! +Finally, re-run your ETL process again, and this time we should have no +failures! ``` npx ts-node src/index.ts runEtl --etlCredentialResource "resources/CredentialResource/RegisteredApp/example-registered-app-credential.ttl" --localUserCredentialResourceGlob "resources/CredentialResource/User/example-user-credential-1.ttl" @@ -505,8 +511,8 @@ open-source project for browsing the data in Pods, especially for developers as it very nicely displays the contents of all Linked Data resources as Turtle. Log into your test user's Pod using PodPro by clicking on the Login icon in the -bottom-left-hand-side of the page, and you'll need to paste in, or select, the -PodSpaces broker (i.e., `https://login.inrupt.com/`). +bottom-left-hand-side of the page, and select the PodSpaces broker (i.e., +`https://login.inrupt.com/`). By navigating the resources and viewing the Linked Data triples, can you find where our test user skydives as a hobby in Ireland? @@ -516,7 +522,7 @@ where our test user skydives as a hobby in Ireland? If you made it all the way through this worksheet, then congratulations! You've certainly covered a lot of ground, and managed to install, run, -configure, debug, and successfully execute a sophisticated full End-to-End ETL +configure, debug, and successfully execute a sophisticated fully End-to-End ETL process resulting in the population of a user Pod from multiple 3rd-party data sources. diff --git a/package-lock.json b/package-lock.json index 4f1c439..409d514 100644 --- a/package-lock.json +++ b/package-lock.json @@ -142,13 +142,14 @@ } }, "node_modules/@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "dependencies": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "engines": { @@ -156,12 +157,12 @@ } }, "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "dependencies": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" }, @@ -197,34 +198,34 @@ } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "dependencies": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" @@ -283,21 +284,30 @@ } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "dependencies": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true, "engines": { "node": ">=6.9.0" @@ -327,13 +337,13 @@ } }, "node_modules/@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "engines": { @@ -412,9 +422,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", - "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -586,45 +596,117 @@ } }, "node_modules/@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "dependencies": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/template/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/traverse": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", - "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", + "node_modules/@babel/template/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": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.5", - "@babel/types": "^7.18.4", + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/template/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/@babel/template/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/@babel/template/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/@babel/template/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/@babel/template/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/@babel/template/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/@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -633,17 +715,68 @@ } }, "node_modules/@babel/traverse/node_modules/@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "dependencies": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" }, "engines": { "node": ">=6.9.0" } }, + "node_modules/@babel/traverse/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/@babel/traverse/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/@babel/traverse/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/@babel/traverse/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/@babel/traverse/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/@babel/traverse/node_modules/globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -653,13 +786,35 @@ "node": ">=4" } }, + "node_modules/@babel/traverse/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/@babel/traverse/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/@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" }, "engines": { @@ -993,6 +1148,14 @@ "node": ">= 4" } }, + "node_modules/@fastify/busboy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", + "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==", + "engines": { + "node": ">=14" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", @@ -1539,9 +1702,9 @@ } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true, "engines": { "node": ">=6.0.0" @@ -1557,19 +1720,19 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -2769,17 +2932,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "node_modules/busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "dependencies": { - "streamsearch": "^1.1.0" - }, - "engines": { - "node": ">=10.16.0" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -8012,14 +8164,6 @@ "promise-polyfill": "^1.1.6" } }, - "node_modules/streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==", - "engines": { - "node": ">=10.0.0" - } - }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -8667,11 +8811,11 @@ } }, "node_modules/undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", + "version": "5.26.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.4.tgz", + "integrity": "sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==", "dependencies": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" }, "engines": { "node": ">=14.0" @@ -9255,23 +9399,24 @@ } }, "@babel/generator": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.2.tgz", - "integrity": "sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", "dev": true, "requires": { - "@babel/types": "^7.18.2", - "@jridgewell/gen-mapping": "^0.3.0", + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", "jsesc": "^2.5.1" }, "dependencies": { "@jridgewell/gen-mapping": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz", - "integrity": "sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg==", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", "dev": true, "requires": { - "@jridgewell/set-array": "^1.0.0", + "@jridgewell/set-array": "^1.0.1", "@jridgewell/sourcemap-codec": "^1.4.10", "@jridgewell/trace-mapping": "^0.3.9" } @@ -9299,28 +9444,28 @@ } }, "@babel/helper-environment-visitor": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz", - "integrity": "sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", "dev": true }, "@babel/helper-function-name": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz", - "integrity": "sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", "dev": true, "requires": { - "@babel/template": "^7.16.7", - "@babel/types": "^7.17.0" + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" } }, "@babel/helper-hoist-variables": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz", - "integrity": "sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg==", + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, "@babel/helper-module-imports": { @@ -9364,18 +9509,24 @@ } }, "@babel/helper-split-export-declaration": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz", - "integrity": "sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw==", + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", "dev": true, "requires": { - "@babel/types": "^7.16.7" + "@babel/types": "^7.22.5" } }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, "@babel/helper-validator-identifier": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz", - "integrity": "sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", "dev": true }, "@babel/helper-validator-option": { @@ -9396,13 +9547,13 @@ } }, "@babel/highlight": { - "version": "7.17.12", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.17.12.tgz", - "integrity": "sha512-7yykMVF3hfZY2jsHZEEgLc+3x4o1O+fYyULu11GynEUQNwB6lua+IIQn1FiJxNucd5UlyJryrwsOh8PL9Sn8Qg==", + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", - "chalk": "^2.0.0", + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", "js-tokens": "^4.0.0" }, "dependencies": { @@ -9465,9 +9616,9 @@ } }, "@babel/parser": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.5.tgz", - "integrity": "sha512-YZWVaglMiplo7v8f1oMQ5ZPQr0vn7HPeZXxXWsxXJRjGVrzUFn9OxFQl1sb5wzfootjA/yChhW84BV+383FSOw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -9588,69 +9739,184 @@ } }, "@babel/template": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.16.7.tgz", - "integrity": "sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w==", + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", "dev": true, "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/parser": "^7.16.7", - "@babel/types": "^7.16.7" + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" }, "dependencies": { "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + } + }, + "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, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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, + "requires": { + "color-name": "1.1.3" + } + }, + "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 + }, + "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 + }, + "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 + }, + "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, + "requires": { + "has-flag": "^3.0.0" } } } }, "@babel/traverse": { - "version": "7.18.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.5.tgz", - "integrity": "sha512-aKXj1KT66sBj0vVzk6rEeAO6Z9aiiQ68wfDgge3nHhA/my6xMM/7HGQUNumKZaoa2qUPQ5whJG9aAifsxUKfLA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "@babel/generator": "^7.18.2", - "@babel/helper-environment-visitor": "^7.18.2", - "@babel/helper-function-name": "^7.17.9", - "@babel/helper-hoist-variables": "^7.16.7", - "@babel/helper-split-export-declaration": "^7.16.7", - "@babel/parser": "^7.18.5", - "@babel/types": "^7.18.4", + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", "debug": "^4.1.0", "globals": "^11.1.0" }, "dependencies": { "@babel/code-frame": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.16.7.tgz", - "integrity": "sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==", + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", "dev": true, "requires": { - "@babel/highlight": "^7.16.7" + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" } }, + "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, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "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, + "requires": { + "color-name": "1.1.3" + } + }, + "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 + }, + "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 + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true + }, + "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 + }, + "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, + "requires": { + "has-flag": "^3.0.0" + } } } }, "@babel/types": { - "version": "7.18.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.4.tgz", - "integrity": "sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw==", + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.16.7", + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", "to-fast-properties": "^2.0.0" } }, @@ -9972,6 +10238,11 @@ } } }, + "@fastify/busboy": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.0.0.tgz", + "integrity": "sha512-JUFJad5lv7jxj926GPgymrWQxxjPYuJNiNjNMzqT+HiuP6Vl3dk5xzG+8sTX96np0ZAluvaMzPsjhHZ5rNuNQQ==" + }, "@humanwhocodes/config-array": { "version": "0.5.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.5.0.tgz", @@ -10410,9 +10681,9 @@ } }, "@jridgewell/resolve-uri": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.0.7.tgz", - "integrity": "sha512-8cXDaBBHOr2pQ7j77Y6Vp5VDT2sIqWyWQ56TjEq4ih/a4iST3dItRe8Q9fp0rrIl9DoKhWQtUQz/YpOxLkXbNA==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", "dev": true }, "@jridgewell/set-array": { @@ -10422,19 +10693,19 @@ "dev": true }, "@jridgewell/sourcemap-codec": { - "version": "1.4.13", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.13.tgz", - "integrity": "sha512-GryiOJmNcWbovBxTfZSF71V/mXbgcV3MewDe3kIMCLyIh5e7SKAeUZs+rMnJ8jkMolZ/4/VsdBmMrw3l+VdZ3w==", + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz", - "integrity": "sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w==", + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, "@nodelib/fs.scandir": { @@ -11336,14 +11607,6 @@ "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", "dev": true }, - "busboy": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", - "integrity": "sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==", - "requires": { - "streamsearch": "^1.1.0" - } - }, "call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -15291,11 +15554,6 @@ "promise-polyfill": "^1.1.6" } }, - "streamsearch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-1.1.0.tgz", - "integrity": "sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==" - }, "string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -15748,11 +16006,11 @@ } }, "undici": { - "version": "5.23.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-5.23.0.tgz", - "integrity": "sha512-1D7w+fvRsqlQ9GscLBwcAJinqcZGHUKjbOmXdlE/v8BvEGXjeWAax+341q44EuTcHXXnfyKNbKRq4Lg7OzhMmg==", + "version": "5.26.4", + "resolved": "https://registry.npmjs.org/undici/-/undici-5.26.4.tgz", + "integrity": "sha512-OG+QOf0fTLtazL9P9X7yqWxQ+Z0395Wk6DSkyTxtaq3wQEjIroVe7Y4asCX/vcCxYpNGMnwz8F0qbRYUoaQVMw==", "requires": { - "busboy": "^1.6.0" + "@fastify/busboy": "^2.0.0" } }, "universalify": { diff --git a/resources/test/DummyData/DummyUserCredentialResource/dummy-user-credential-user-with-pod.ttl b/resources/test/DummyData/DummyUserCredentialResource/dummy-user-credential-user-with-pod.ttl index 63f5442..a40da90 100644 --- a/resources/test/DummyData/DummyUserCredentialResource/dummy-user-credential-user-with-pod.ttl +++ b/resources/test/DummyData/DummyUserCredentialResource/dummy-user-credential-user-with-pod.ttl @@ -29,5 +29,5 @@ prefix inrupt_common: inrupt_common:dataHierarchyFirst ; # The Solid Pod to load data into (should be a string, and not an IRI!). - solid:webId "https://test.example.com/test-user/profile/card#me" ; + solid:webId "https://test.example.com/test-user/webid" ; solid:storageRoot "https://test-user.different.example.com/" . diff --git a/src/applicationSetup.ts b/src/applicationSetup.ts index 50cc22c..bda1fce 100644 --- a/src/applicationSetup.ts +++ b/src/applicationSetup.ts @@ -57,7 +57,7 @@ const debug = debugModule(`${APPLICATION_NAME}:applicationSetup`); // These default values can be useful if we wanted to populate a triplestore // even if no Solid Pod details are provided at all. -const DEFAULT_WEBID = "https://test.example.com/test-user/profile/card#me"; +const DEFAULT_WEBID = "https://test.example.com/test-user/webid"; export const DEFAULT_STORAGE_ROOT_PREFIX = "https://different.domain.example.com/testStorageRoot/user-GUID-";