diff --git a/.gitignore b/.gitignore index 8a8cb030..664b4463 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ venv/ credentials.py dist/ +# node +node_modules/ # any previous versions of schemas **/dataset_**.json **/catalog_**.json diff --git a/docs/diagrams/mermaid/dest/arcgis-1.svg b/docs/diagrams/mermaid/dest/arcgis-1.svg new file mode 100644 index 00000000..0d5538fc --- /dev/null +++ b/docs/diagrams/mermaid/dest/arcgis-1.svg @@ -0,0 +1 @@ +Import StageYesNoYesNoYesYesNoerrorYesNoYesNoYesYesNoNoIMPORT STARTEDIs Object Empty?SkipGet Existing Harvest ObjectDoes the object exist?Mark Previous Harvest Object as not currentShould the dataset be deleted?Delete PackageIs the Object content empty?ErrorArcGIS Package CreateIMPORT ENDEDIs the Status new?Default CreateDefault UpdateIs the Status new?Generate GUIDSave Object Reference in PackageCreate New PackageIs the Status changed?Does the object exist?Update DatasetFetch StageFETCH STARTEDNothing to doFETCH ENDEDGather StageYesNoYesNoGATHER STARTEDAre there extra search parameters?Add search to basic queryQuery All data from all timesBuild data 100 rows at a timeQuery ServerGet Existing Harvest ObjectsCalculate new objectsCreate New ObjectCalculate deleted objectsCalculate changed objectsIs the Date different?SkipGATHER ENDED \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/arcgis.md b/docs/diagrams/mermaid/dest/arcgis.md new file mode 100644 index 00000000..fa9809e0 --- /dev/null +++ b/docs/diagrams/mermaid/dest/arcgis.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/dcat-1.svg b/docs/diagrams/mermaid/dest/dcat-1.svg new file mode 100644 index 00000000..7a7a37f6 --- /dev/null +++ b/docs/diagrams/mermaid/dest/dcat-1.svg @@ -0,0 +1 @@ +Import StageYesNoYesNoYesNoNoYesNoYesNoYesNoYesNoYesNoIMPORT STARTEDIs the dataset empty?IMPORT ENDEDDoes the dataset have a title?Parse SchemaVersion, isCollection, CollectioPkgId, catalogValuesErrorschema_version = 1.0is_collection=falseparent_pkg_id=empty_strcatalog_values=noneDoes Parent exist?fetch_parentNew package titleIs the title valid?Is validator schema federal or non-federal?Source Config DefaultsFederal ValidationNon-Federal ValidationValidate DatasetGet Owner OrganizationMake Upstream Content HashAssemble Basic DatasetAdd Unique Dataset InfoIs the package geospatial?Mark as geospatialIs the package a collection?Mark as Collection ParentMark as Collection ChildTrack catalog values in datasetDoes the dataset exist already?Get Existing Package InfoCreate New PackagePreserve existing resourcesUpdate DatasetMake this package the Current Harvest ObjectFetch StageFETCH STARTEDNothing to doFETCH ENDEDGather StageNoYesNoYesYesNoYesNoYesNoYesNoYesNoNoYesYesNoYesYesNoYesYesNoNoDisjunctionDisjunctionYesNoYesNoInverseYesNoexceptionGATHER STARTEDLoad Remote CatalogconformsTo is supported schema?ErrorDoes schema_version exist?Source DatasetsCatalog Valuesschema_version = 1.0Schema VersionGet Existing DatasetsExisting DatasetsIs Parent?Existing Parent Dataset IdentifiersIs Parent Demoted?Parent Identifiers who no longer have childrenIs Dataset Promoted?New Parent Dataset IdentifiersLoad Harvest Source ConfigSource Config FilterSource Config DefaultsIs Identifier Parent AND Child?For Each Source Dataset STARTdataset contains key-value specified in filter?SkipDoes dataset have identifier?Has the identifier been seen before?Unique DatasetsIs the unique dataset an existing dataset?Does the dataset have an existing hash?Seen DatasetsNew package idSource HashIs Dataset Active?Make Upstream Content HashCreate Harvest ObjectIs Hash the same?Append__is_collectionAppend__collection_pkg_idIs Parent?Harvest_firstHarvest_secondFor Each Source Dataset ENDFor Each Existing Dataset STARTIs Dataset Deleted?Delete DatasetFor Each Existing Dataset ENDGATHER ENDED \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/dcat.md b/docs/diagrams/mermaid/dest/dcat.md new file mode 100644 index 00000000..e8065201 --- /dev/null +++ b/docs/diagrams/mermaid/dest/dcat.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/h20_compare_dcat-1.svg b/docs/diagrams/mermaid/dest/h20_compare_dcat-1.svg new file mode 100644 index 00000000..d48df51c --- /dev/null +++ b/docs/diagrams/mermaid/dest/h20_compare_dcat-1.svg @@ -0,0 +1 @@ +CatalogHarvest source1-to-N1-to-NID found; Hash not sameID not found in CatalogID not found in Harvest SourceID found; Hash sameFaceted Solr Querycreate `id: source_hash` hashmapDownload Harvest SourceExtract datasetsHash datasetcompare hashsesCreate new datasetDelete old datasetUpdate existing datasetPass \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/h20_compare_dcat.md b/docs/diagrams/mermaid/dest/h20_compare_dcat.md new file mode 100644 index 00000000..44318af5 --- /dev/null +++ b/docs/diagrams/mermaid/dest/h20_compare_dcat.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/new_harvesting-1.svg b/docs/diagrams/mermaid/dest/new_harvesting-1.svg new file mode 100644 index 00000000..b67ad168 --- /dev/null +++ b/docs/diagrams/mermaid/dest/new_harvesting-1.svg @@ -0,0 +1 @@ +SOURCE CREATIONExtract Faceted Catalog SourceCompare Source Catalog to Data.gov CatalogLoad into Data.gov CatalogValidate DatasetTransform Schema of DatasetEndNo Changes?Datasets to Delete?Datasets to Add or Update?Manual TriggerScheduled Trigger \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/new_harvesting.md b/docs/diagrams/mermaid/dest/new_harvesting.md new file mode 100644 index 00000000..bd4ab206 --- /dev/null +++ b/docs/diagrams/mermaid/dest/new_harvesting.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/old_harvesting-1.svg b/docs/diagrams/mermaid/dest/old_harvesting-1.svg new file mode 100644 index 00000000..65a67a5b --- /dev/null +++ b/docs/diagrams/mermaid/dest/old_harvesting-1.svg @@ -0,0 +1 @@ +SOURCE CREATIONGATHER STAGEFETCH STAGEIMPORT STAGEManual TriggerScheduled Trigger \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/old_harvesting.md b/docs/diagrams/mermaid/dest/old_harvesting.md new file mode 100644 index 00000000..be3d1912 --- /dev/null +++ b/docs/diagrams/mermaid/dest/old_harvesting.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/single_xml-1.svg b/docs/diagrams/mermaid/dest/single_xml-1.svg new file mode 100644 index 00000000..c3002e46 --- /dev/null +++ b/docs/diagrams/mermaid/dest/single_xml-1.svg @@ -0,0 +1 @@ +Import StageNoYesNoYesNoNoSuccesstranformYesNovalidnot validYesNoNoNoYesYesNoYesNoYesNoNoYesYesexceptionYesexceptionYesIMPORT STARTEDIs Object Empty?Is the Object being forcible imported?Mark Existing Object as ChangedGet status from GatherGet Existing ObjectShould the dataset be deleted?deleteIs document ISO?Transform to ISOSave Content (ISO)Parse ISO DocumentIs the Object content empty?Validate DatasetContinue if validation has errors?IMPORT ENDEDMake this package the Current Harvest ObjectIs the GUID current?Update GUIDDoes the GUID exist?Generate GUIDGet Modified DateCreate Package Data ..see reference in code..Is the Harvest Source Private?Mark Object as privateIs the Harvest Source part of a Topic?Mark Object as part of topicMark Object as geospatialMake this package the Current Harvest ObjectIs the Status new?Create New Packageis_modified_newerTransfer old object job history to new objectDelete old objectReindex package to reflect new dateUpdate DatasetErrorSkipFetch StageFETCH STARTEDNothing to doFETCH ENDEDGather StageYesNoYesNoExceptionGATHER STARTEDDownload XML FileDoes the object exist?Get Existing ObjectCreate New ObjectMark Existing Object as ChangedGuess Metadata StandardIs document ISO?Save Content (ISO)Save Original Content (non-ISO)GATHER ENDEDError \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/single_xml.md b/docs/diagrams/mermaid/dest/single_xml.md new file mode 100644 index 00000000..3b64426b --- /dev/null +++ b/docs/diagrams/mermaid/dest/single_xml.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/dest/waf_xml-1.svg b/docs/diagrams/mermaid/dest/waf_xml-1.svg new file mode 100644 index 00000000..527b271e --- /dev/null +++ b/docs/diagrams/mermaid/dest/waf_xml-1.svg @@ -0,0 +1 @@ +Import StageNoYesNoYesNoNoSuccesstranformYesNovalidnot validYesNoNoNoYesYesNoYesNoYesNoNoYesYesexceptionYesexceptionYesIMPORT STARTEDIs Object Empty?Is the Object being forcible imported?change_object_2Get status from Gatherget_existing_object_2Should the dataset be deleted?deleteIs document ISO?Transform to ISOsave_content_2Parse ISO DocumentIs the Object content empty?Validate DatasetContinue if validation has errors?IMPORT ENDEDMake this package the Current Harvest ObjectIs the GUID current?Update GUIDDoes the GUID exist?Generate GUIDGet Modified DateCreate Package Data ..see reference in code..Is the Harvest Source Private?Mark Object as privateIs the Harvest Source part of a Topic?Mark Object as part of topicMark Object as geospatialMake this package the Current Harvest ObjectIs the Status new?Create New Packageis_modified_newerTransfer old object job history to new objectDelete old objectReindex package to reflect new dateUpdate DatasetErrorSkipFetch StageYesNoNo URLExceptionYesNoFETCH STARTEDShould the dataset be deleted?SkipGet URL from ObjectErrorDownload XML FileGuess Metadata StandardIs document ISO?Save Content (ISO)Save Original Content (non-ISO)FETCH ENDEDGather StageExceptionExceptionNoYesNoYesNoGATHER STARTEDGet Source Root URLErrorDetermine the WAF Server TypeLoad Current ObjectsExtract Source ObjectsCompare Source and Current ObjectsDoes the source object have a date?New DatasetsDeleted DatasetsChanged DatasetsFor Each New ObjectCreate GUID based on hash of new objectCreate New ObjectEnd For New ObjectFor Each Changed ObjectEnd For Changed ObjectFor Each Deleted ObjectMark the existing object as not currentEnd For Deleted ObjectIs there data to process?Return IDSReturn NONEGATHER ENDED \ No newline at end of file diff --git a/docs/diagrams/mermaid/dest/waf_xml.md b/docs/diagrams/mermaid/dest/waf_xml.md new file mode 100644 index 00000000..86be8d15 --- /dev/null +++ b/docs/diagrams/mermaid/dest/waf_xml.md @@ -0,0 +1 @@ + diff --git a/docs/diagrams/mermaid/makeDoc.mjs b/docs/diagrams/mermaid/makeDoc.mjs new file mode 100644 index 00000000..b8bad157 --- /dev/null +++ b/docs/diagrams/mermaid/makeDoc.mjs @@ -0,0 +1,20 @@ +import { run } from "@mermaid-js/mermaid-cli" +import { readdir } from 'node:fs/promises'; +import { resolve } from 'node:path'; + +(async (req, res) => { + try { + let fileSrc = resolve('./docs/diagrams/mermaid/src') + let fileDest = resolve('./docs/diagrams/mermaid/dest') + const files = await readdir(fileSrc); + for (const file of files) { + console.log(`Found file: ${file}`); + await run( + `${fileSrc}/${file}`, `${fileDest}/${file}`, {puppeteerConfig: {"headless": "old"}}, + ) + console.log(` `) + } + } catch (err) { + console.error(err) + } +})(); diff --git a/docs/diagrams/mermaid/src/arcgis.md b/docs/diagrams/mermaid/src/arcgis.md new file mode 100644 index 00000000..5e095195 --- /dev/null +++ b/docs/diagrams/mermaid/src/arcgis.md @@ -0,0 +1,115 @@ +```mermaid +flowchart LR + + %% Algorithm + gather_stage ==> fetch_stage + fetch_stage ==> import_stage + + subgraph gather_stage [Gather Stage] + direction TB + gs([GATHER STARTED]) + ge([GATHER ENDED]) + gs ==> is_extra_search_criteria + is_extra_search_criteria == Yes ==> add_to_query + is_extra_search_criteria == No ==>basic_query + add_to_query ==> basic_query + basic_query ==> get_for_all_time + get_for_all_time ==> query_arcgis + query_arcgis ==> get_current_objects + get_current_objects ==> compute_new + compute_new ==> create_object + compute_new ==> compute_deleted + compute_deleted ==> create_object + compute_deleted ==> compute_changed + compute_changed ==> is_date_different + is_date_different == Yes ==> create_object + is_date_different == No ==> skip + compute_changed ==> ge + end + subgraph fetch_stage [Fetch Stage] + direction TB + fs([FETCH STARTED]) + fe([FETCH ENDED]) + fs ==> do_nothing + do_nothing ==> fe + end + subgraph import_stage [Import Stage] + direction TB + is([IMPORT STARTED]) + ie([IMPORT ENDED]) + is ==> is_object_empty + is_object_empty-. Yes .-> skip_2 + is_object_empty == No ==> get_existing_object + get_existing_object ==> is_existing_object + is_existing_object == Yes ==> mark_not_current + is_existing_object == No ==> is_delete + mark_not_current ==> is_delete + is_delete == Yes ==> delete + delete ==> is_object_content_empty + is_object_content_empty-. Yes .-> error + is_object_content_empty == No ==> make_package_dict + %% Code: https://github.com/GSA/ckanext-geodatagov/blob/984dc47087f981c15f7878bef5a96970adb78125/ckanext/geodatagov/harvesters/arcgis.py#L338-L431 + make_package_dict-. error .-> ie + make_package_dict ==> is_status_new + is_status_new == Yes ==> default_create_package_schema + is_status_new == No ==> default_update_package_schema + default_update_package_schema ==> is_status_new_2 + default_create_package_schema ==> is_status_new_2 + is_status_new_2 == Yes ==> generate_guid + generate_guid ==> save_object_reference + save_object_reference ==> create + is_status_new_2 == No ==> is_status_changed + is_status_changed == Yes ==> is_existing_object_2 + is_existing_object_2 == Yes ==> mark_not_current + is_existing_object_2 == No ==> update + mark_not_current ==> update + update ==> ie + create ==> ie + is_status_changed == No ==> ie + end + + %% Data + error[\Error/] + skip[/Skip\] + skip_2[/Skip\] + + %% Functons + %% Code: https://github.com/ckan/ckan/blob/master/ckan/logic/schema.py#L115-L194 + default_update_package_schema[[Default Update]] + default_create_package_schema[[Default Create]] + + create_object[[Create New Object]] + update[[Update Dataset]] + do_nothing[[Nothing to do]] + create[[Create New Package]] + delete[[Delete Package]] + save_object_reference[[Save Object Reference in Package]] + generate_guid[[Generate GUID]] + get_existing_object[[Get Existing Harvest Object]] + mark_not_current[[Mark Previous Harvest Object as not current]] + add_to_query[[Add search to basic query]] + basic_query[[Query All data from all times]] + get_for_all_time[[Build data 100 rows at a time]] + query_arcgis[[Query Server]] + get_current_objects[[Get Existing Harvest Objects]] + compute_new[[Calculate new objects]] + compute_deleted[[Calculate deleted objects]] + compute_changed[[Calculate changed objects]] + + %% Code: https://github.com/GSA/ckanext-geodatagov/blob/984dc47087f981c15f7878bef5a96970adb78125/ckanext/geodatagov/harvesters/arcgis.py#L338-L431 + make_package_dict[[ArcGIS Package Create]] + + + %% Conditional Checks + is_extra_search_criteria{Are there extra search parameters?} + is_existing_object{Does the object exist?} + is_existing_object_2{Does the object exist?} + is_object_empty{Is Object Empty?} + is_object_content_empty{Is the Object content empty?} + is_delete{Should the dataset be deleted?} + is_status_new{Is the Status new?} + is_status_new_2{Is the Status new?} + is_status_changed{Is the Status changed?} + is_date_different{Is the Date different?} + +``` diff --git a/docs/diagrams/mermaid/src/dcat.md b/docs/diagrams/mermaid/src/dcat.md new file mode 100644 index 00000000..174f58e9 --- /dev/null +++ b/docs/diagrams/mermaid/src/dcat.md @@ -0,0 +1,225 @@ +```mermaid +flowchart LR + + %% Algorithm + gather_stage ==> fetch_stage + fetch_stage ==> import_stage + + subgraph gather_stage [Gather Stage] + direction TB + gs([GATHER STARTED]) + ge([GATHER ENDED]) + gs ==> load_remote_catalog + load_remote_catalog ==> validate_conforms_to + validate_conforms_to == No ==> error + validate_conforms_to == Yes ==> check_schema_version + load_remote_catalog --> source_data + load_remote_catalog --> catalog_values + catalog_values --> check_schema_version + check_schema_version-- No -->default_schema_version + check_schema_version-- Yes -->schema_version + schema_version --> get_existing_datasets + default_schema_version --> get_existing_datasets + get_existing_datasets --> existing_datasets + get_existing_datasets ==> is_parent_ + is_parent_ == Yes ==> existing_parents + existing_parents --> is_parent_demoted + is_parent_ == No ==> is_parent_demoted + is_parent_demoted -- Yes --> orphaned_parents + is_parent_demoted == No ==> is_parent_promoted + existing_datasets --> is_parent_promoted + is_parent_promoted -- Yes --> new_parents + is_parent_promoted == No ==> load_config + load_config --> hc_filter + load_config --> hc_defaults + load_config ==> is_identifier_both + is_identifier_both-. Yes .-> error + is_identifier_both == No ==> for_each_dataset + hc_filter --> dataset_contains_filter + for_each_dataset ==> dataset_contains_filter + dataset_contains_filter-. Yes .-> skip + dataset_contains_filter == No ==> has_identifier + has_identifier-. No .-> error + has_identifier == Yes ==> multiple_identifier + multiple_identifier-. Yes .-> skip + multiple_identifier == No ==> unique_datsets + unique_datsets --> unique_existing + unique_existing == Yes ==> hash_exists + unique_existing -- Yes --> seen_datasets + unique_existing == No ==> new_pkg_id + hash_exists == Yes ==> get_source_hash + get_source_hash ==> is_active + is_active == Yes ==> make_upstream_content_hash + is_active == No ==> HarvestObjectExtra + hash_exists == No ==> make_upstream_content_hash + orphaned_parents-- Disjunction -->make_upstream_content_hash + new_parents-- Disjunction -->make_upstream_content_hash + make_upstream_content_hash ==> check_hash + check_hash-. Yes .-> skip + check_hash-- No -->HarvestObjectExtra + new_pkg_id --> HarvestObjectExtra + Append__is_collection --> HarvestObjectExtra + schema_version --> HarvestObjectExtra + default_schema_version --> HarvestObjectExtra + catalog_values --> HarvestObjectExtra + Append__collection_pkg_id --> HarvestObjectExtra + HarvestObjectExtra ==> is_parent_2 + is_parent_2 == Yes ==> Harvest_first + is_parent_2 == No ==> Harvest_second + Harvest_first ==> for_each_dataset_end + Harvest_second ==> for_each_dataset_end + for_each_dataset_end ==> for_each_existing + for_each_existing --> seen_datasets + for_each_existing ==> is_deleted + seen_datasets-. Inverse .-> skip + is_deleted-. Yes .-> skip + seen_datasets --> delete + is_deleted== No ==>delete + delete-. exception .-> error + delete ==> for_each_existing_end + for_each_existing_end ==> ge + end + subgraph fetch_stage [Fetch Stage] + direction TB + fs([FETCH STARTED]) + fe([FETCH ENDED]) + fs ==> do_nothing + do_nothing ==> fe + end + subgraph import_stage [Import Stage] + direction TB + is([IMPORT STARTED]) + ie([IMPORT ENDED]) + is ==> empty_dataset + empty_dataset == Yes ==> ie + empty_dataset == No ==> has_title + has_title == Yes ==> extract_extras + has_title-. No .->error_2 + extract_extras --> default_schema_version_2 + extract_extras --> default_collection + extract_extras --> default_parent + extract_extras --> default_catalog + extract_extras ==> does_parent_exist + does_parent_exist == Yes ==> fetch_parent + does_parent_exist == No ==> new_pkg_title + does_parent_exist-. No .->error_2 + default_collection --> does_parent_exist + default_parent --> does_parent_exist + fetch_parent ==> new_pkg_title + new_pkg_title ==> is_title_valid + is_title_valid== Yes ==> is_federal + is_title_valid-. No .->error_2 + default_schema_version_2 --> is_federal + hc_defaults_2 --> is_federal + new_pkg_title ==> is_federal + is_federal == Yes ==> federal_validation + is_federal == No ==> non_federal_validation + federal_validation ==> validate_dataset + non_federal_validation ==> validate_dataset + validate_dataset ==> get_owner_org + get_owner_org ==> make_upstream_content_hash_2 + make_upstream_content_hash_2 ==> assemble_basic_dataset_info + assemble_basic_dataset_info ==> add_dataset_specific_info + add_dataset_specific_info ==> is_geospatial + is_geospatial == Yes ==> tag_geospatial + is_geospatial == No ==> is_collection + tag_geospatial ==> is_collection + is_collection == Yes ==> tag_collection_parent + is_collection == No ==> tag_collection_child + tag_collection_parent ==> tag_catalog_values + tag_collection_child ==> tag_catalog_values + tag_catalog_values ==> is_existing + is_existing == Yes ==> get_existing_pkg + is_existing == No ==> create + get_existing_pkg ==> avoid_resource_overwriting + avoid_resource_overwriting ==> update + create ==> update_object_reference + update ==> update_object_reference + update_object_reference ==> ie + end + + + %% Data + error[\Error/] + error_2[\Error/] + skip[/Skip\] + source_data[(Source Datasets)] + catalog_values[(Catalog Values)] + schema_version[(Schema Version)] + %% all_parents[(All Parent Identifiers)] + existing_datasets[(Existing Datasets)] + existing_parents[(Existing Parent Dataset Identifiers)] + new_parents[(New Parent Dataset Identifiers)] + orphaned_parents[(Parent Identifiers who no longer have children)] + unique_datsets[(Unique Datasets)] + seen_datasets[(Seen Datasets)] + default_schema_version[(schema_version = 1.0)] + default_schema_version_2[(schema_version = 1.0)] + default_collection[(is_collection=false)] + default_parent[(parent_pkg_id=empty_str)] + default_catalog[(catalog_values=none)] + hc_filter[(Source Config Filter)] + hc_defaults[(Source Config Defaults)] + hc_defaults_2[(Source Config Defaults)] + new_pkg_id[(New package id)] + HarvestObjectExtra[(Create Harvest Object)] + new_pkg_title[(New package title)] + + %% Functons + load_remote_catalog[[Load Remote Catalog]] + make_upstream_content_hash[[Make Upstream Content Hash]] + make_upstream_content_hash_2[[Make Upstream Content Hash]] + load_config[[Load Harvest Source Config]] + get_existing_datasets[[Get Existing Datasets]] + get_source_hash[[Source Hash]] + %% set_dataset_info[[Set Dataset Info]] + for_each_dataset[[For Each Source Dataset START]] + for_each_dataset_end[[For Each Source Dataset END]] + for_each_existing[[For Each Existing Dataset START]] + for_each_existing_end[[For Each Existing Dataset END]] + update[[Update Dataset]] + delete[[Delete Dataset]] + do_nothing[[Nothing to do]] + extract_extras[[Parse SchemaVersion, isCollection, CollectioPkgId, catalogValues]] + federal_validation[[Federal Validation]] + non_federal_validation[[Non-Federal Validation]] + validate_dataset[[Validate Dataset]] + get_owner_org[[Get Owner Organization]] + assemble_basic_dataset_info[[Assemble Basic Dataset]] + add_dataset_specific_info[[Add Unique Dataset Info]] + tag_collection_parent[[Mark as Collection Parent]] + tag_collection_child[[Mark as Collection Child]] + tag_geospatial[[Mark as geospatial]] + tag_catalog_values[[Track catalog values in dataset]] + get_existing_pkg[[Get Existing Package Info]] + create[[Create New Package]] + avoid_resource_overwriting[[Preserve existing resources]] + update_object_reference[[Make this package the Current Harvest Object]] + + + %% Conditional Checks + validate_conforms_to{conformsTo is supported schema?} + check_schema_version{Does schema_version exist?} + is_parent_{Is Parent?} + is_parent_2{Is Parent?} + is_parent_demoted{Is Parent Demoted?} + is_parent_promoted{Is Dataset Promoted?} + is_identifier_both{Is Identifier Parent AND Child?} + dataset_contains_filter{dataset contains key-value specified in filter?} + has_identifier{Does dataset have identifier?} + multiple_identifier{Has the identifier been seen before?} + unique_existing{Is the unique dataset an existing dataset?} + hash_exists{Does the dataset have an existing hash?} + check_hash{Is Hash the same?} + is_active{Is Dataset Active?} + is_deleted{Is Dataset Deleted?} + empty_dataset{Is the dataset empty?} + is_federal{Is validator schema federal or non-federal?} + is_existing{Is it an existing dataset?} + is_geospatial{Is the package geospatial?} + is_collection{Is the package a collection?} + is_existing{Does the dataset exist already?} + has_title{Does the dataset have a title?} + does_parent_exist{Does Parent exist?} + is_title_valid{Is the title valid?} +``` diff --git a/docs/diagrams/mermaid/src/h20_compare_dcat.md b/docs/diagrams/mermaid/src/h20_compare_dcat.md new file mode 100644 index 00000000..99f05899 --- /dev/null +++ b/docs/diagrams/mermaid/src/h20_compare_dcat.md @@ -0,0 +1,35 @@ +```mermaid +flowchart TD + +subgraph Harvest source + getHarvest([Download Harvest Source]) + extractHarvest([Extract datasets]) + hashDataset([Hash dataset]) +end + +subgraph Catalog + queryCKAN([Faceted Solr Query]) + extractHash([create `id: source_hash` hashmap]) +end + +%% Operations + compareHash{compare hashses} + createDataset([Create new dataset]) + deleteDataset([Delete old dataset]) + updateDataset([Update existing dataset]) + + +%% flow + getHarvest -- 1-to-N --> extractHarvest + extractHarvest --> hashDataset + hashDataset --> compareHash + + queryCKAN -- 1-to-N --> extractHash + extractHash --> compareHash + + + compareHash -- ID found; Hash not same --> updateDataset + compareHash -- ID not found in Catalog --> createDataset + compareHash -- ID not found in Harvest Source --> deleteDataset + compareHash -- ID found; Hash same --> Pass([Pass]) +``` diff --git a/docs/diagrams/mermaid/src/new_harvesting.md b/docs/diagrams/mermaid/src/new_harvesting.md new file mode 100644 index 00000000..e5ec1c1f --- /dev/null +++ b/docs/diagrams/mermaid/src/new_harvesting.md @@ -0,0 +1,34 @@ +```mermaid +flowchart TD + %% Operations + sc([SOURCE CREATION]) + extract([Extract Faceted Catalog Source]) + compare([Compare Source Catalog to Data.gov Catalog]) + load([Load into Data.gov Catalog]) + validate([Validate Dataset]) + transform([Transform Schema of Dataset]) + completed([End]) + + %% Conditions + nochanges{No Changes?} + deletions{Datasets to Delete?} + updates{Datasets to Add or Update?} + manual{Manual Trigger} + scheduled{Scheduled Trigger} + + sc --> manual + sc --> scheduled + manual --> extract + scheduled --> extract + extract --> compare + compare --> deletions + compare --> updates + deletions --> load + updates --> validate + validate --> transform + transform --> validate + validate --> load + load --> completed + compare --> nochanges + nochanges --> completed +``` diff --git a/docs/diagrams/mermaid/src/old_harvesting.md b/docs/diagrams/mermaid/src/old_harvesting.md new file mode 100644 index 00000000..ff397c78 --- /dev/null +++ b/docs/diagrams/mermaid/src/old_harvesting.md @@ -0,0 +1,19 @@ +```mermaid +flowchart LR + %% Operations + sc([SOURCE CREATION]) + gs([GATHER STAGE]) + fs([FETCH STAGE]) + is([IMPORT STAGE]) + + %% Conditions + manual{Manual Trigger} + scheduled{Scheduled Trigger} + + sc --> manual + sc --> scheduled + manual --> gs + scheduled --> gs + gs --> fs + fs --> is +``` diff --git a/docs/diagrams/mermaid/src/single_xml.md b/docs/diagrams/mermaid/src/single_xml.md new file mode 100644 index 00000000..41746f35 --- /dev/null +++ b/docs/diagrams/mermaid/src/single_xml.md @@ -0,0 +1,144 @@ +```mermaid +flowchart LR + + %% Algorithm + gather_stage ==> fetch_stage + fetch_stage ==> import_stage + + subgraph gather_stage [Gather Stage] + direction TB + gs([GATHER STARTED]) + ge([GATHER ENDED]) + gs ==> _get_content_as_unicode + _get_content_as_unicode ==> is_existing_object + is_existing_object == Yes ==> get_existing_object + is_existing_object == No ==> create_object + get_existing_object ==> change_object + change_object ==> guess_standard + create_object ==> guess_standard + guess_standard ==> is_iso + is_iso == Yes ==> save_content + is_iso == No ==> save_original_document + save_content ==> ge + save_original_document ==> ge + _get_content_as_unicode-. Exception .-> error + end + subgraph fetch_stage [Fetch Stage] + direction TB + fs([FETCH STARTED]) + fe([FETCH ENDED]) + fs ==> do_nothing + do_nothing ==> fe + end + subgraph import_stage [Import Stage] + direction TB + is([IMPORT STARTED]) + ie([IMPORT ENDED]) + is ==> is_object_empty + is_object_empty == No ==> is_force_import + is_force_import == Yes ==> change_object_2 + is_force_import == No ==> check_status_from_gather + change_object_2 ==> get_existing_object_2 + check_status_from_gather ==> get_existing_object_2 + get_existing_object_2 ==> is_delete + is_delete == Yes ==> delete + is_delete == No ==> is_iso_2 + is_iso_2 == No ==> transform_to_iso + transform_to_iso == Success ==> save_content_2 + save_content_2 == tranform ==> parse_iso + is_iso_2 == Yes ==> is_object_content_empty + is_object_content_empty == No ==> _validate_document + _validate_document == valid ==> parse_iso + _validate_document == not valid ==> continue_on_validation_errors + continue_on_validation_errors == Yes ==> parse_iso + continue_on_validation_errors == No ==> ie + parse_iso ==> update_object_reference + update_object_reference ==> is_guid_current + is_guid_current == No ==> update_guid + update_guid ==> is_guid_present + is_guid_present == No ==> generate_guid + is_guid_present == Yes ==> get_modified_date + generate_guid ==> get_modified_date + get_modified_date ==> spatial_package_create + spatial_package_create ==> is_source_private + is_source_private == Yes ==> mark_object_private + %% BUG: if source marked as private --> harvest --> changed to public --> harvest --> datasets remain private + is_source_private == No ==> is_source_part_of_topic + mark_object_private ==> is_source_part_of_topic + is_source_part_of_topic == Yes ==> mark_object_part_of_topic + is_source_part_of_topic == No ==> mark_as_geospatial + mark_object_part_of_topic ==> mark_as_geospatial + mark_as_geospatial ==> update_object_reference_2 + update_object_reference_2 ==> is_status_new + is_status_new == Yes ==> create + is_status_new == No ==> is_modified_newer + is_modified_newer == No ==> transfer_job_history + transfer_job_history ==> delete_old_object + delete_old_object ==> reindex_package + is_modified_newer == Yes ==> update + create ==> ie + update ==> ie + is_object_content_empty-. Yes .-> error_2 + parse_iso-. exception .-> error_2 + is_guid_current-. Yes .-> error_2 + get_modified_date-. exception .-> error_2 + is_object_empty-. Yes .-> skip + reindex_package -.-> skip + end + + %% Data + error[\Error/] + error_2[\Error/] + skip[/Skip\] + + %% Functons + + %% Code: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/base.py#L835-L860 + _get_content_as_unicode[[Download XML File]] + + get_existing_object[[Get Existing Object]] + get_existing_object_2[[Get Existing Object]] + create_object[[Create New Object]] + change_object[[Mark Existing Object as Changed]] + change_object_2[[Mark Existing Object as Changed]] + guess_standard[[Guess Metadata Standard]] + save_content[["Save Content (ISO)"]] + save_content_2[["Save Content (ISO)"]] + save_original_document[["Save Original Content (non-ISO)"]] + update[[Update Dataset]] + do_nothing[[Nothing to do]] + create[[Create New Package]] + update_object_reference[[Make this package the Current Harvest Object]] + update_object_reference_2[[Make this package the Current Harvest Object]] + transform_to_iso[[Transform to ISO]] + _validate_document[[Validate Dataset]] + parse_iso[[Parse ISO Document]] + update_guid[[Update GUID]] + generate_guid[[Generate GUID]] + check_status_from_gather[[Get status from Gather]] + get_modified_date[[Get Modified Date]] + mark_object_private[[Mark Object as private]] + mark_object_part_of_topic[[Mark Object as part of topic]] + mark_as_geospatial[[Mark Object as geospatial]] + transfer_job_history[[Transfer old object job history to new object]] + delete_old_object[[Delete old object]] + reindex_package[[Reindex package to reflect new date]] + %% Spatial Package Create: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/base.py#L233-L492 + spatial_package_create[[Create Package Data ..see reference in code..]] + + + %% Conditional Checks + is_existing_object{Does the object exist?} + is_iso{Is document ISO?} + is_iso_2{Is document ISO?} + is_object_empty{Is Object Empty?} + is_force_import{Is the Object being forcible imported?} + is_object_content_empty{Is the Object content empty?} + continue_on_validation_errors{Continue if validation has errors?} + is_guid_current{Is the GUID current?} + is_guid_present{Does the GUID exist?} + is_delete{Should the dataset be deleted?} + is_source_private{Is the Harvest Source Private?} + is_source_part_of_topic{Is the Harvest Source part of a Topic?} + is_status_new{Is the Status new?} +``` diff --git a/docs/diagrams/mermaid/src/waf_xml.md b/docs/diagrams/mermaid/src/waf_xml.md new file mode 100644 index 00000000..6627a3b6 --- /dev/null +++ b/docs/diagrams/mermaid/src/waf_xml.md @@ -0,0 +1,196 @@ +```mermaid +flowchart LR + + %% Algorithm + gather_stage ==> fetch_stage + fetch_stage ==> import_stage + + subgraph gather_stage [Gather Stage] + direction TB + gs([GATHER STARTED]) + ge([GATHER ENDED]) + gs ==> get_source_url + get_source_url-. Exception .-> error + get_source_url ==> _get_scraper + _get_scraper ==> get_current_objects + get_current_objects ==> _extract_waf + _extract_waf-. Exception .-> error + _extract_waf ==> compare + compare ==> is_date_present + compare --> new_datasets + compare --> deleted_datasets + compare --> changed_datasets + is_date_present -- No --> changed_datasets + is_date_present == Yes ==> for_each_new + is_date_present == No ==> for_each_new + for_each_new ==> hash_new + hash_new --> create_object + hash_new ==> end_each_new + end_each_new ==> for_each_changed + for_each_changed --> create_object + for_each_changed ==> end_each_changed + end_each_changed ==> for_each_deleted + for_each_deleted --> create_object + for_each_deleted ==> make_not_current + make_not_current ==> end_each_deleted + end_each_deleted ==> is_ids + is_ids == Yes ==> return_ids + is_ids == No ==> return_none + return_ids ==> ge + return_none ==> ge + end + subgraph fetch_stage [Fetch Stage] + direction TB + fs([FETCH STARTED]) + fe([FETCH ENDED]) + fs ==> is_delete + is_delete-. Yes .-> skip + is_delete == No ==> get_location + get_location-. No URL .-> error_2 + get_location ==> _get_content_as_unicode + _get_content_as_unicode-. Exception .-> error_2 + _get_content_as_unicode ==> guess_standard + guess_standard ==> is_iso + is_iso == Yes ==> save_content + is_iso == No ==> save_original_document + save_content ==> fe + save_original_document ==> fe + end + subgraph import_stage [Import Stage] + %% WAFHarvester does not implement this code, it inherits from + %% SpatialHarvester, which is shared with DocHarvester + direction TB + is([IMPORT STARTED]) + ie([IMPORT ENDED]) + is ==> is_object_empty + is_object_empty == No ==> is_force_import + is_force_import == Yes ==> change_object_2 + is_force_import == No ==> check_status_from_gather + change_object_2 ==> get_existing_object_2 + check_status_from_gather ==> get_existing_object_2 + get_existing_object_2 ==> is_delete_2 + is_delete_2 == Yes ==> delete + is_delete_2 == No ==> is_iso_2 + is_iso_2 == No ==> transform_to_iso + transform_to_iso == Success ==> save_content_2 + save_content_2 == tranform ==> parse_iso + is_iso_2 == Yes ==> is_object_content_empty + is_object_content_empty == No ==> _validate_document + _validate_document == valid ==> parse_iso + _validate_document == not valid ==> continue_on_validation_errors + continue_on_validation_errors == Yes ==> parse_iso + continue_on_validation_errors == No ==> ie + parse_iso ==> update_object_reference + update_object_reference ==> is_guid_current + is_guid_current == No ==> update_guid + update_guid ==> is_guid_present + is_guid_present == No ==> generate_guid + is_guid_present == Yes ==> get_modified_date + generate_guid ==> get_modified_date + get_modified_date ==> spatial_package_create + spatial_package_create ==> is_source_private + is_source_private == Yes ==> mark_object_private + %% BUG: if source marked as private --> harvest --> changed to public --> harvest --> datasets remain private + is_source_private == No ==> is_source_part_of_topic + mark_object_private ==> is_source_part_of_topic + is_source_part_of_topic == Yes ==> mark_object_part_of_topic + is_source_part_of_topic == No ==> mark_as_geospatial + mark_object_part_of_topic ==> mark_as_geospatial + mark_as_geospatial ==> update_object_reference_2 + update_object_reference_2 ==> is_status_new + is_status_new == Yes ==> create + is_status_new == No ==> is_modified_newer + is_modified_newer == No ==> transfer_job_history + transfer_job_history ==> delete_old_object + delete_old_object ==> reindex_package + is_modified_newer == Yes ==> update + create ==> ie + update ==> ie + is_object_content_empty-. Yes .-> error_3 + parse_iso-. exception .-> error_3 + is_guid_current-. Yes .-> error_3 + get_modified_date-. exception .-> error_3 + is_object_empty-. Yes .-> skip_2 + reindex_package -.-> skip_2 + end + + %% Data + error[\Error/] + error_2[\Error/] + error_3[\Error/] + skip[/Skip\] + skip_2[/Skip\] + new_datasets[(New Datasets)] + deleted_datasets[(Deleted Datasets)] + changed_datasets[(Changed Datasets)] + create_object[(Create New Object)] + + %% Functons + get_source_url[[Get Source Root URL]] + + %% Code: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/waf.py#L269-L277 + _get_scraper[[Determine the WAF Server Type]] + + get_current_objects[[Load Current Objects]] + + %% Code: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/waf.py#L279-L334 + _extract_waf[[Extract Source Objects]] + + compare[[Compare Source and Current Objects]] + for_each_new[[For Each New Object]] + hash_new[[Create GUID based on hash of new object]] + end_each_new[[End For New Object]] + for_each_changed[[For Each Changed Object]] + end_each_changed[[End For Changed Object]] + for_each_deleted[[For Each Deleted Object]] + make_not_current[[Mark the existing object as not current]] + end_each_deleted[[End For Deleted Object]] + return_ids[[Return IDS]] + return_none[[Return NONE]] + get_location[[Get URL from Object]] + + %% Code: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/base.py#L835-L860 + _get_content_as_unicode[[Download XML File]] + + guess_standard[[Guess Metadata Standard]] + save_content[["Save Content (ISO)"]] + save_original_document[["Save Original Content (non-ISO)"]] + update[[Update Dataset]] + create[[Create New Package]] + update_object_reference[[Make this package the Current Harvest Object]] + update_object_reference_2[[Make this package the Current Harvest Object]] + transform_to_iso[[Transform to ISO]] + _validate_document[[Validate Dataset]] + parse_iso[[Parse ISO Document]] + update_guid[[Update GUID]] + generate_guid[[Generate GUID]] + check_status_from_gather[[Get status from Gather]] + get_modified_date[[Get Modified Date]] + mark_object_private[[Mark Object as private]] + mark_object_part_of_topic[[Mark Object as part of topic]] + mark_as_geospatial[[Mark Object as geospatial]] + transfer_job_history[[Transfer old object job history to new object]] + delete_old_object[[Delete old object]] + reindex_package[[Reindex package to reflect new date]] + + %% Spatial Package Create: https://github.com/ckan/ckanext-spatial/blob/e59a295431247fcd605fe55bb4fd9a2ecfc28d2b/ckanext/spatial/harvesters/base.py#L233-L492 + spatial_package_create[[Create Package Data ..see reference in code..]] + + + %% Conditional Checks + is_date_present{Does the source object have a date?} + is_ids{Is there data to process?} + is_iso{Is document ISO?} + is_iso_2{Is document ISO?} + is_object_empty{Is Object Empty?} + is_force_import{Is the Object being forcible imported?} + is_object_content_empty{Is the Object content empty?} + continue_on_validation_errors{Continue if validation has errors?} + is_guid_current{Is the GUID current?} + is_guid_present{Does the GUID exist?} + is_delete{Should the dataset be deleted?} + is_delete_2{Should the dataset be deleted?} + is_source_private{Is the Harvest Source Private?} + is_source_part_of_topic{Is the Harvest Source part of a Topic?} + is_status_new{Is the Status new?} +``` diff --git a/docs/diagrams/uml/out/erd/harvester2.0 ERD.png b/docs/diagrams/uml/out/erd/harvester2.0 ERD.png new file mode 100644 index 00000000..9661113d Binary files /dev/null and b/docs/diagrams/uml/out/erd/harvester2.0 ERD.png differ diff --git a/docs/diagrams/uml/src/README.md b/docs/diagrams/uml/src/README.md new file mode 100644 index 00000000..66a5e9a3 --- /dev/null +++ b/docs/diagrams/uml/src/README.md @@ -0,0 +1,12 @@ +## How do we organize and display data on data.gov? + +- Navigating to the [datasets](https://catalog.data.gov/dataset) page we see the following "filters" + - topics + - topic categories + - dataset type + - tags + - formats + - organization types + - organizations + - publishers + - bureaus diff --git a/docs/diagrams/uml/src/erd.plantuml b/docs/diagrams/uml/src/erd.plantuml new file mode 100644 index 00000000..0a54ea05 --- /dev/null +++ b/docs/diagrams/uml/src/erd.plantuml @@ -0,0 +1,102 @@ +@startuml harvester2.0 ERD + +skinparam linetype ortho + +' ERD +card "Entity Relationship Diagram" as entities { + entity "harvest_source" as source { + uuid : uuid (PK) + -- + name: text + notifications_emails: array( txt ) + organization_name: txt + frequency: text + config: json + urls: array( txt ) + schema_validation_type: text + } + + entity "harvest_record" as record { + uuid : uuid (PK) + -- + source_id: uuid (FK) + job_id: uuid (FK) + status: text + s3_path: text + } + + entity "harvest_job" as job { + uuid : uuid (PK) + -- + source_id: uuid (FK) + status: text + date_created + date_finished: datetime + extract_started: datetime + extract_finished: datetime + compare_started: datetime + compare_finished: datetime + records_added: smallint + records_updated: smallint + records_deleted: smallint + records_errored: smallint + records_ignored: smallint + } + + entity "harvest_error" as error { + uuid : uuid (PK) + -- + job_id: uuid (FK) + record_id: uuid (FK) + record_reported_id: text + date_created: datetime + error_type: text + severity: enum + message: text + + } +} + +' lookup tables +card "Lookup Tables" as lookup { + + entity "data_format" as data_format { + name: text (PK) + -- + mime_type: text + } +} + +' enumerators +card "Enumerators" as enumerators { + + enum error_severity { + ERROR + CRITICAL + } + + enum job_status { + CREATE + PROCESSING + COMPLETE + } + + enum schema_validation { + DCATUS + ISO1911 + } + + enum record_status { + STALE + ACTIVE + INVALID + } +} + +' relationships +source ||--|{ job +source ||--|{ record +job ||--|{ record +job ||-|{ error + +@enduml diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000..e4f8b4e2 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,1216 @@ +{ + "name": "datagov-harvesting-logic", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "datagov-harvesting-logic", + "version": "1.0.0", + "license": "ISC", + "devDependencies": { + "@mermaid-js/mermaid-cli": "^10.6.1" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.23.5", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.5.tgz", + "integrity": "sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/code-frame/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/code-frame/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/code-frame/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/helper-validator-identifier": { + "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" + } + }, + "node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/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/highlight/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/highlight/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/@mermaid-js/mermaid-cli": { + "version": "10.6.1", + "resolved": "https://registry.npmjs.org/@mermaid-js/mermaid-cli/-/mermaid-cli-10.6.1.tgz", + "integrity": "sha512-OH2uOXW3/GBaMGagVF7Fzu/9TJrGge+Bu/+Tm8OyIaRBaKa2NN+3SggJOmr5s51oTPaGKu/X1XBDoauvtlXAPg==", + "dev": true, + "dependencies": { + "chalk": "^5.0.1", + "commander": "^10.0.0", + "puppeteer": "^19.0.0" + }, + "bin": { + "mmdc": "src/cli.js" + }, + "engines": { + "node": "^14.13 || >=16.0" + } + }, + "node_modules/@mermaid-js/mermaid-cli/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@mermaid-js/mermaid-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@puppeteer/browsers": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-0.5.0.tgz", + "integrity": "sha512-Uw6oB7VvmPRLE4iKsjuOh8zgDabhNX67dzo8U/BB0f9527qx+4eeUs+korU98OhG5C4ubg7ufBgVi63XYwS6TQ==", + "dev": true, + "dependencies": { + "debug": "4.3.4", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "yargs": "17.7.1" + }, + "bin": { + "browsers": "lib/cjs/main-cli.js" + }, + "engines": { + "node": ">=14.1.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@puppeteer/browsers/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/@puppeteer/browsers/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/@puppeteer/browsers/node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/@puppeteer/browsers/node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/@types/node": { + "version": "20.10.4", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.10.4.tgz", + "integrity": "sha512-D08YG6rr8X90YB56tSIuBaddy/UXAA9RKJoFvrsnogAum/0pmjkgi4+2nx96A330FmioegBWmEYQ+syqCFaveg==", + "dev": true, + "optional": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agent-base/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/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "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/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "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" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "node_modules/chromium-bidi": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/chromium-bidi/-/chromium-bidi-0.4.7.tgz", + "integrity": "sha512-6+mJuFXwTMU6I3vYLs6IL8A1DyQTPjCfIL971X0aMPVGRbGnNfl6i6Cl0NMbxi2bRYLGESt9T2ZIMRM5PAEcIQ==", + "dev": true, + "dependencies": { + "mitt": "3.0.0" + }, + "peerDependencies": { + "devtools-protocol": "*" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/cosmiconfig": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.1.3.tgz", + "integrity": "sha512-/UkO2JKI18b5jVMJUp0lvKFMpa/Gye+ZgZjKD+DGEN9y7NRcf/nK1A0sp67ONmKtnDCNMS44E6jrk0Yc3bDuUw==", + "dev": true, + "dependencies": { + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "parse-json": "^5.0.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + } + }, + "node_modules/cross-fetch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-3.1.5.tgz", + "integrity": "sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==", + "dev": true, + "dependencies": { + "node-fetch": "2.6.7" + } + }, + "node_modules/devtools-protocol": { + "version": "0.0.1107588", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.1107588.tgz", + "integrity": "sha512-yIR+pG9x65Xko7bErCUSQaDLrO/P1p3JUzEk7JCU4DowPcGHkTGUGQapcfcLc4qj0UaALwZ+cr0riFgiqpixcg==", + "dev": true + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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/fs-constants": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", + "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", + "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-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", + "dev": true, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/https-proxy-agent/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/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/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true + }, + "node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true + }, + "node_modules/mitt": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.0.tgz", + "integrity": "sha512-7dX2/10ITVyqh4aOSVI9gdape+t9l2/8QxHrFmUXu4EEUpdlxl6RudZUPZoc+zuY2hk1j7XxVroIVIan/pD/SQ==", + "dev": true + }, + "node_modules/mkdirp-classic": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", + "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", + "dev": true + }, + "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/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "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/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "dev": true + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/puppeteer": { + "version": "19.11.1", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-19.11.1.tgz", + "integrity": "sha512-39olGaX2djYUdhaQQHDZ0T0GwEp+5f9UB9HmEP0qHfdQHIq0xGQZuAZ5TLnJIc/88SrPLpEflPC+xUqOTv3c5g==", + "deprecated": "< 21.3.7 is no longer supported", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@puppeteer/browsers": "0.5.0", + "cosmiconfig": "8.1.3", + "https-proxy-agent": "5.0.1", + "progress": "2.0.3", + "proxy-from-env": "1.1.0", + "puppeteer-core": "19.11.1" + } + }, + "node_modules/puppeteer-core": { + "version": "19.11.1", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-19.11.1.tgz", + "integrity": "sha512-qcuC2Uf0Fwdj9wNtaTZ2OvYRraXpAK+puwwVW8ofOhOgLPZyz1c68tsorfIZyCUOpyBisjr+xByu7BMbEYMepA==", + "dev": true, + "dependencies": { + "@puppeteer/browsers": "0.5.0", + "chromium-bidi": "0.4.7", + "cross-fetch": "3.1.5", + "debug": "4.3.4", + "devtools-protocol": "0.0.1107588", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.1", + "proxy-from-env": "1.1.0", + "tar-fs": "2.1.1", + "unbzip2-stream": "1.4.3", + "ws": "8.13.0" + }, + "engines": { + "node": ">=14.14.0" + }, + "peerDependencies": { + "typescript": ">= 4.7.4" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/puppeteer-core/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/puppeteer-core/node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + }, + "bin": { + "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" + } + }, + "node_modules/puppeteer-core/node_modules/fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/puppeteer-core/node_modules/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/puppeteer/node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "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/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar-fs": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", + "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "dev": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "node_modules/tar-stream": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", + "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", + "dev": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar-stream/node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/tar-stream/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/tar-stream/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/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/unbzip2-stream": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", + "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "dev": true, + "dependencies": { + "buffer": "^5.2.1", + "through": "^2.3.8" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true, + "optional": true + }, + "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/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, + "node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/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/wrap-ansi/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/wrap-ansi/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/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "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/ws": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", + "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..d1b4d303 --- /dev/null +++ b/package.json @@ -0,0 +1,19 @@ +{ + "name": "datagov-harvesting-logic", + "version": "1.0.0", + "description": "This is a library that will be utilized for metadata extraction, validation, transformation, and loading into the data.gov catalog.", + "main": "index.js", + "directories": { + "doc": "docs", + "test": "tests" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "makeDoc": "node ./docs/diagrams/mermaid/makeDoc.mjs" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "@mermaid-js/mermaid-cli": "^10.6.1" + } +}