From a220c73d81341751aaef586051e86de008f792a2 Mon Sep 17 00:00:00 2001 From: Hawken Rives Date: Sun, 17 Aug 2025 15:21:09 -0400 Subject: [PATCH 1/4] begin adding pglite support --- modules/gob-examine-student/index.js | 16 +- modules/gob-examine-student/package.json | 3 +- .../source/apply-filter.js | 6 +- .../source/apply-fulfillment-to-expression.js | 2 +- .../source/apply-fulfillment-to-result.js | 4 +- .../gob-examine-student/source/assert-keys.js | 2 +- .../source/check-for-course.js | 4 +- .../source/collect-matches.js | 7 +- .../source/collect-taken-courses.js | 7 +- .../source/compare-course-to-course.js | 4 +- .../source/compare-course-to-qualification.js | 9 +- .../source/compute-chunk.js | 38 +- .../source/compute-count-with-operator.js | 3 +- modules/gob-examine-student/source/compute.js | 18 +- .../source/count-courses.js | 7 +- .../source/count-credits.js | 2 +- .../source/count-departments.js | 6 +- .../gob-examine-student/source/count-terms.js | 2 +- .../gob-examine-student/source/evaluate.js | 6 +- .../source/exclude-course.js | 6 +- .../source/filter-by-where-clause.js | 16 +- .../gob-examine-student/source/find-course.js | 6 +- .../source/find-leaf-requirements.js | 11 +- .../source/get-departments.js | 2 +- .../source/get-fulfillment.js | 4 +- .../source/get-matches-from-children.js | 10 +- .../source/get-matches-from-filter.js | 4 +- .../source/get-occurrences.js | 6 +- .../source/get-override.js | 4 +- .../source/has-override.js | 6 +- .../source/humanize-operator.js | 3 +- .../source/simplify-course.js | 2 +- .../gob-hanson-format/convert-department.js | 2 +- modules/gob-hanson-format/enhance-hanson.js | 9 +- modules/gob-hanson-format/index.js | 10 +- modules/gob-hanson-format/make-area-slug.js | 2 +- modules/gob-hanson-format/package.json | 3 +- .../gob-hanson-format/parse-hanson-string.js | 6 +- modules/gob-web-database/index.js | 288 ++++++- modules/gob-web-database/package.json | 2 + modules/gob-web-database/schema-orange.js | 54 ++ modules/gob-web-database/worker.js | 13 + modules/gob-web/helpers/db.js | 4 +- .../source/cache-item-hash.js | 13 +- .../source/clean-prior-data.js | 37 +- modules/gob-worker-load-data/source/db.js | 5 - .../source/get-cache-store-name.js | 14 - .../source/needs-update.js | 10 +- .../source/remove-duplicate-areas.js | 21 +- .../gob-worker-load-data/source/store-data.js | 36 +- package-lock.json | 708 ++++++++++++++++-- package.json | 23 +- 52 files changed, 1182 insertions(+), 304 deletions(-) create mode 100644 modules/gob-web-database/schema-orange.js create mode 100644 modules/gob-web-database/worker.js delete mode 100644 modules/gob-worker-load-data/source/db.js delete mode 100644 modules/gob-worker-load-data/source/get-cache-store-name.js diff --git a/modules/gob-examine-student/index.js b/modules/gob-examine-student/index.js index 907abd59d..e84d0eb92 100644 --- a/modules/gob-examine-student/index.js +++ b/modules/gob-examine-student/index.js @@ -1,10 +1,10 @@ // @flow -export { evaluate } from "./source/evaluate" -export { countCredits } from "./source/count-credits" -export { default as pathToOverride } from "./source/path-to-override" -export { default as pluralizeArea } from "./source/pluralize-area" -export { default as humanizeOperator } from "./source/humanize-operator" -export { default as simplifyCourse } from "./source/simplify-course" -export { default as isRequirementName } from "./source/is-requirement-name" -export * from "./source/types" +export { evaluate } from "./source/evaluate.js" +export { countCredits } from "./source/count-credits.js" +export { default as pathToOverride } from "./source/path-to-override.js" +export { default as pluralizeArea } from "./source/pluralize-area.js" +export { default as humanizeOperator } from "./source/humanize-operator.js" +export { default as simplifyCourse } from "./source/simplify-course.js" +export { default as isRequirementName } from "./source/is-requirement-name.js" +export * from "./source/types.js" diff --git a/modules/gob-examine-student/package.json b/modules/gob-examine-student/package.json index ab15c2c1f..567f2ca21 100644 --- a/modules/gob-examine-student/package.json +++ b/modules/gob-examine-student/package.json @@ -2,9 +2,10 @@ "engines": { "node": ">=22" }, + "type": "module", "name": "@gob/examine-student", "version": "3.0.0-rc.2", - "main": "index.js", + "module": "index.js", "repository": "hawkrives/gobbldygook", "author": "Hawken MacKay Rives", "license": "MIT", diff --git a/modules/gob-examine-student/source/apply-filter.js b/modules/gob-examine-student/source/apply-filter.js index eb6b6359f..9969a6f8c 100644 --- a/modules/gob-examine-student/source/apply-filter.js +++ b/modules/gob-examine-student/source/apply-filter.js @@ -1,7 +1,7 @@ // @flow -import checkForCourse from "./check-for-course" -import filterByWhereClause from "./filter-by-where-clause" -import type { FilterExpression, Course } from "./types" +import checkForCourse from "./check-for-course.js" +import filterByWhereClause from "./filter-by-where-clause.js" +import type { FilterExpression, Course } from "./types.js" const filterByOfExpression = (courses: Array, $of: Array) => $of.filter((course) => checkForCourse(course, courses)) diff --git a/modules/gob-examine-student/source/apply-fulfillment-to-expression.js b/modules/gob-examine-student/source/apply-fulfillment-to-expression.js index 665f6fefe..25864ccd8 100644 --- a/modules/gob-examine-student/source/apply-fulfillment-to-expression.js +++ b/modules/gob-examine-student/source/apply-fulfillment-to-expression.js @@ -1,5 +1,5 @@ // @flow -import type { OrExpression, Expression, Fulfillment } from "./types" +import type { OrExpression, Expression, Fulfillment } from "./types.js" export default function applyFulfillmentToExpression( expr: Expression, diff --git a/modules/gob-examine-student/source/apply-fulfillment-to-result.js b/modules/gob-examine-student/source/apply-fulfillment-to-result.js index fdd62b020..2ec28e21f 100644 --- a/modules/gob-examine-student/source/apply-fulfillment-to-result.js +++ b/modules/gob-examine-student/source/apply-fulfillment-to-result.js @@ -1,6 +1,6 @@ // @flow -import computeCountWithOperator from "./compute-count-with-operator" -import type { Fulfillment, Expression, Course } from "./types" +import computeCountWithOperator from "./compute-count-with-operator.js" +import type { Fulfillment, Expression, Course } from "./types.js" type ReturnType = { computedResult: boolean, diff --git a/modules/gob-examine-student/source/assert-keys.js b/modules/gob-examine-student/source/assert-keys.js index 543fc7bfe..33977024f 100644 --- a/modules/gob-examine-student/source/assert-keys.js +++ b/modules/gob-examine-student/source/assert-keys.js @@ -1,5 +1,5 @@ // @flow -import reject from "lodash/reject" +import { reject } from "lodash" /** * Throws a ReferenceError if any requested key is missing. diff --git a/modules/gob-examine-student/source/check-for-course.js b/modules/gob-examine-student/source/check-for-course.js index 964c4d9fc..3160f2e4a 100644 --- a/modules/gob-examine-student/source/check-for-course.js +++ b/modules/gob-examine-student/source/check-for-course.js @@ -1,7 +1,7 @@ // @flow -import compareCourseToCourse from "./compare-course-to-course" -import type { Course } from "./types" +import compareCourseToCourse from "./compare-course-to-course.js" +import type { Course } from "./types.js" /** * Checks if a course exists in an array of courses diff --git a/modules/gob-examine-student/source/collect-matches.js b/modules/gob-examine-student/source/collect-matches.js index 859161c46..28887c449 100644 --- a/modules/gob-examine-student/source/collect-matches.js +++ b/modules/gob-examine-student/source/collect-matches.js @@ -1,9 +1,8 @@ // @flow -import assertKeys from "./assert-keys" -import flatMap from "lodash/flatMap" -import uniqBy from "lodash/uniqBy" +import assertKeys from "./assert-keys.js" +import { flatMap, uniqBy } from "lodash" import stringify from "stabilize" -import type { Expression, Requirement, Course } from "./types" +import type { Expression, Requirement, Course } from "./types.js" /** * Collects matched courses from a result object diff --git a/modules/gob-examine-student/source/collect-taken-courses.js b/modules/gob-examine-student/source/collect-taken-courses.js index 45c6d5401..5928e3be8 100644 --- a/modules/gob-examine-student/source/collect-taken-courses.js +++ b/modules/gob-examine-student/source/collect-taken-courses.js @@ -1,9 +1,6 @@ // @flow -import isPlainObject from "lodash/isPlainObject" -import flattenDeep from "lodash/flattenDeep" -import uniq from "lodash/uniq" -import values from "lodash/values" -import type { Expression, Course } from "./types" +import { isPlainObject, flattenDeep, uniq, values } from "lodash" +import type { Expression, Course } from "./types.js" export default function collectTakenCourses(expr: Expression): Course[] { // this function needs to end up with a list of all of the courses diff --git a/modules/gob-examine-student/source/compare-course-to-course.js b/modules/gob-examine-student/source/compare-course-to-course.js index 790935b3d..55cd27dc2 100644 --- a/modules/gob-examine-student/source/compare-course-to-course.js +++ b/modules/gob-examine-student/source/compare-course-to-course.js @@ -1,6 +1,6 @@ // @flow -import isEqualWith from "lodash/isEqualWith" -import type { Course } from "./types" +import { isEqualWith } from "lodash" +import type { Course } from "./types.js" const baseKeys = new Set([ "department", diff --git a/modules/gob-examine-student/source/compare-course-to-qualification.js b/modules/gob-examine-student/source/compare-course-to-qualification.js index 2a359f650..c9c0075a1 100644 --- a/modules/gob-examine-student/source/compare-course-to-qualification.js +++ b/modules/gob-examine-student/source/compare-course-to-qualification.js @@ -1,10 +1,7 @@ // @flow -import isPlainObject from "lodash/isPlainObject" -import includes from "lodash/includes" -import every from "lodash/every" -import some from "lodash/some" -import assertKeys from "./assert-keys" -import type { Course, Qualification } from "./types" +import { isPlainObject, includes, every, some } from "lodash" +import assertKeys from "./assert-keys.js" +import type { Course, Qualification } from "./types.js" /** * Compares a course property against a MongoDB-style operator diff --git a/modules/gob-examine-student/source/compute-chunk.js b/modules/gob-examine-student/source/compute-chunk.js index 48235c46d..734efb196 100644 --- a/modules/gob-examine-student/source/compute-chunk.js +++ b/modules/gob-examine-student/source/compute-chunk.js @@ -1,24 +1,22 @@ // @flow -import keys from "lodash/keys" -import take from "lodash/take" -import xor from "lodash/xor" +import { keys, take, xor } from "lodash" import stringify from "stabilize" -import applyFulfillmentToResult from "./apply-fulfillment-to-result" -import assertKeys from "./assert-keys" -import collectMatches from "./collect-matches" -import collectTakenCourses from "./collect-taken-courses" -import computeCountWithOperator from "./compute-count-with-operator" -import countCourses from "./count-courses" -import { countCredits } from "./count-credits" -import { countTerms } from "./count-terms" -import countDepartments from "./count-departments" -import excludeCourse from "./exclude-course" -import filterByWhereClause from "./filter-by-where-clause" -import findCourse from "./find-course" -import getMatchesFromChildren from "./get-matches-from-children" -import getMatchesFromFilter from "./get-matches-from-filter" -import getOccurrences from "./get-occurrences" -import simplifyCourse from "./simplify-course" +import applyFulfillmentToResult from "./apply-fulfillment-to-result.js" +import assertKeys from "./assert-keys.js" +import collectMatches from "./collect-matches.js" +import collectTakenCourses from "./collect-taken-courses.js" +import computeCountWithOperator from "./compute-count-with-operator.js" +import countCourses from "./count-courses.js" +import { countCredits } from "./count-credits.js" +import { countTerms } from "./count-terms.js" +import countDepartments from "./count-departments.js" +import excludeCourse from "./exclude-course.js" +import filterByWhereClause from "./filter-by-where-clause.js" +import findCourse from "./find-course.js" +import getMatchesFromChildren from "./get-matches-from-children.js" +import getMatchesFromFilter from "./get-matches-from-filter.js" +import getOccurrences from "./get-occurrences.js" +import simplifyCourse from "./simplify-course.js" import type { Expression, @@ -32,7 +30,7 @@ import type { OfExpression, ReferenceExpression, WhereExpression, -} from "./types" +} from "./types.js" type StringifiedCourse = string diff --git a/modules/gob-examine-student/source/compute-count-with-operator.js b/modules/gob-examine-student/source/compute-count-with-operator.js index 5edb9f3d8..857b792c8 100644 --- a/modules/gob-examine-student/source/compute-count-with-operator.js +++ b/modules/gob-examine-student/source/compute-count-with-operator.js @@ -1,5 +1,6 @@ // @flow -import type { CounterOperatorEnum } from "./types" +import type { CounterOperatorEnum } from "./types.js" + export default function computeCountWithOperator({ comparator, has, diff --git a/modules/gob-examine-student/source/compute.js b/modules/gob-examine-student/source/compute.js index d3b7b78e4..2f477f351 100644 --- a/modules/gob-examine-student/source/compute.js +++ b/modules/gob-examine-student/source/compute.js @@ -1,12 +1,12 @@ // @flow -import applyFilter from "./apply-filter" -import applyFulfillmentToExpression from "./apply-fulfillment-to-expression" -import computeChunk from "./compute-chunk" -import getFulfillment from "./get-fulfillment" -import getOverride from "./get-override" -import hasOverride from "./has-override" -import isRequirementName from "./is-requirement-name" -import mapValues from "lodash/mapValues" +import applyFilter from "./apply-filter.js" +import applyFulfillmentToExpression from "./apply-fulfillment-to-expression.js" +import computeChunk from "./compute-chunk.js" +import getFulfillment from "./get-fulfillment.js" +import getOverride from "./get-override.js" +import hasOverride from "./has-override.js" +import isRequirementName from "./is-requirement-name.js" +import { mapValues } from "lodash" import type { ParsedHansonFile, ParsedHansonRequirement, @@ -14,7 +14,7 @@ import type { Course, OverridesObject, FulfillmentsObject, -} from "./types" +} from "./types.js" // The overall computation is done by compute, which is in charge of computing // sub-requirements and such. diff --git a/modules/gob-examine-student/source/count-courses.js b/modules/gob-examine-student/source/count-courses.js index 995e2428a..202468daf 100644 --- a/modules/gob-examine-student/source/count-courses.js +++ b/modules/gob-examine-student/source/count-courses.js @@ -1,8 +1,7 @@ // @flow -import uniqBy from "lodash/uniqBy" -import size from "lodash/size" -import simplifyCourse from "./simplify-course" -import type { Course } from "./types" +import { uniqBy, size } from "lodash" +import simplifyCourse from "./simplify-course.js" +import type { Course } from "./types.js" /** * Counts the number of unique courses in a list of courses diff --git a/modules/gob-examine-student/source/count-credits.js b/modules/gob-examine-student/source/count-credits.js index 6e1fd1625..693bbeba0 100644 --- a/modules/gob-examine-student/source/count-credits.js +++ b/modules/gob-examine-student/source/count-credits.js @@ -1,6 +1,6 @@ // @flow -import sumBy from "lodash/sumBy" +import { sumBy } from "lodash" import { type Course as CourseType } from "@gob/types" // Sums up the number of credits offered by a set of courses diff --git a/modules/gob-examine-student/source/count-departments.js b/modules/gob-examine-student/source/count-departments.js index 22b856970..2f7c8e488 100644 --- a/modules/gob-examine-student/source/count-departments.js +++ b/modules/gob-examine-student/source/count-departments.js @@ -1,7 +1,7 @@ // @flow -import compact from "lodash/compact" -import getDepartments from "./get-departments" -import type { Course } from "./types" +import { compact } from "lodash" +import getDepartments from "./get-departments.js" +import type { Course } from "./types.js" /** * Counts the number of unique departments in a list of courses diff --git a/modules/gob-examine-student/source/count-terms.js b/modules/gob-examine-student/source/count-terms.js index c0fe18bac..82ee6e651 100644 --- a/modules/gob-examine-student/source/count-terms.js +++ b/modules/gob-examine-student/source/count-terms.js @@ -1,5 +1,5 @@ // @flow -import type { Course } from "./types" +import type { Course } from "./types.js" /** * Counts the number of unique terms from a list of courses diff --git a/modules/gob-examine-student/source/evaluate.js b/modules/gob-examine-student/source/evaluate.js index 42fb599f6..ff3275928 100644 --- a/modules/gob-examine-student/source/evaluate.js +++ b/modules/gob-examine-student/source/evaluate.js @@ -1,13 +1,13 @@ // @flow -import assertKeys from "./assert-keys" -import compute from "./compute" +import assertKeys from "./assert-keys.js" +import compute from "./compute.js" import type { Course, ParsedHansonFile, OverridesObject, FulfillmentsObject, EvaluationResult, -} from "./types" +} from "./types.js" type Input = { area: ParsedHansonFile, diff --git a/modules/gob-examine-student/source/exclude-course.js b/modules/gob-examine-student/source/exclude-course.js index ba1f11745..000915318 100644 --- a/modules/gob-examine-student/source/exclude-course.js +++ b/modules/gob-examine-student/source/exclude-course.js @@ -1,7 +1,7 @@ // @flow -import reject from "lodash/reject" -import compareCourseToCourse from "./compare-course-to-course" -import type { Course } from "./types" +import { reject } from "lodash" +import compareCourseToCourse from "./compare-course-to-course.js" +import type { Course } from "./types.js" /** * Removes a course from a list of courses diff --git a/modules/gob-examine-student/source/filter-by-where-clause.js b/modules/gob-examine-student/source/filter-by-where-clause.js index b2699269c..234f33841 100644 --- a/modules/gob-examine-student/source/filter-by-where-clause.js +++ b/modules/gob-examine-student/source/filter-by-where-clause.js @@ -1,21 +1,15 @@ // @flow -import filter from "lodash/filter" -import forEach from "lodash/forEach" -import map from "lodash/map" -import max from "lodash/max" -import min from "lodash/min" -import take from "lodash/take" -import uniqBy from "lodash/uniqBy" -import assertKeys from "./assert-keys" -import compareCourseToQualification from "./compare-course-to-qualification" -import simplifyCourse from "./simplify-course" +import { filter, forEach, map, max, min, take, uniqBy } from "lodash" +import assertKeys from "./assert-keys.js" +import compareCourseToQualification from "./compare-course-to-qualification.js" +import simplifyCourse from "./simplify-course.js" import type { Course, Qualifier, Qualification, Counter, QualificationFunctionValue, -} from "./types" +} from "./types.js" export default function filterByWhereClause( baseList: Course[], diff --git a/modules/gob-examine-student/source/find-course.js b/modules/gob-examine-student/source/find-course.js index 86d3e5aa4..edcd8ebef 100644 --- a/modules/gob-examine-student/source/find-course.js +++ b/modules/gob-examine-student/source/find-course.js @@ -1,7 +1,7 @@ // @flow -import find from "lodash/find" -import compareCourseToCourse from "./compare-course-to-course" -import type { Course } from "./types" +import { find } from "lodash" +import compareCourseToCourse from "./compare-course-to-course.js" +import type { Course } from "./types.js" /** * Finds a course in a list of courses diff --git a/modules/gob-examine-student/source/find-leaf-requirements.js b/modules/gob-examine-student/source/find-leaf-requirements.js index fd3eda6dc..91a885ab3 100644 --- a/modules/gob-examine-student/source/find-leaf-requirements.js +++ b/modules/gob-examine-student/source/find-leaf-requirements.js @@ -1,12 +1,7 @@ // @flow -import flatten from "lodash/flatten" -import map from "lodash/map" -import compact from "lodash/compact" -import isPlainObject from "lodash/isPlainObject" -import keys from "lodash/keys" -import some from "lodash/some" -import isRequirementName from "./is-requirement-name" -import type { Requirement } from "./types" +import { flatten, map, compact, isPlainObject, keys, some } from "lodash" +import isRequirementName from "./is-requirement-name.js" +import type { Requirement } from "./types.js" /** * Searches recursively through a requirement tree to find all of the diff --git a/modules/gob-examine-student/source/get-departments.js b/modules/gob-examine-student/source/get-departments.js index 5581d1323..5f2826ff8 100644 --- a/modules/gob-examine-student/source/get-departments.js +++ b/modules/gob-examine-student/source/get-departments.js @@ -1,5 +1,5 @@ // @flow -import type { Course } from "./types" +import type { Course } from "./types.js" /** * Gets the list of unique departments from a list of courses diff --git a/modules/gob-examine-student/source/get-fulfillment.js b/modules/gob-examine-student/source/get-fulfillment.js index 706810c85..ab813282f 100644 --- a/modules/gob-examine-student/source/get-fulfillment.js +++ b/modules/gob-examine-student/source/get-fulfillment.js @@ -1,6 +1,6 @@ // @flow -import pathToOverride from "./path-to-override" -import type { FulfillmentsPath, FulfillmentsObject } from "./types" +import pathToOverride from "./path-to-override.js" +import type { FulfillmentsPath, FulfillmentsObject } from "./types.js" export default function getFulfillment( path: FulfillmentsPath, diff --git a/modules/gob-examine-student/source/get-matches-from-children.js b/modules/gob-examine-student/source/get-matches-from-children.js index 9981f0940..553c951a1 100644 --- a/modules/gob-examine-student/source/get-matches-from-children.js +++ b/modules/gob-examine-student/source/get-matches-from-children.js @@ -1,16 +1,14 @@ // @flow -import collectMatches from "./collect-matches" -import isRequirementName from "./is-requirement-name" -import flatten from "lodash/flatten" -import keys from "lodash/keys" -import uniqBy from "lodash/uniqBy" +import collectMatches from "./collect-matches.js" +import isRequirementName from "./is-requirement-name.js" +import { flatten, keys, uniqBy } from "lodash" import stringify from "stabilize" import type { ModifierChildrenExpression, ModifierChildrenWhereExpression, Requirement, Course, -} from "./types" +} from "./types.js" /** * Extract the matched courses from all children. diff --git a/modules/gob-examine-student/source/get-matches-from-filter.js b/modules/gob-examine-student/source/get-matches-from-filter.js index 612c0d63f..4340842e3 100644 --- a/modules/gob-examine-student/source/get-matches-from-filter.js +++ b/modules/gob-examine-student/source/get-matches-from-filter.js @@ -1,6 +1,6 @@ // @flow -import assertKeys from "./assert-keys" -import type { Requirement } from "./types" +import assertKeys from "./assert-keys.js" +import type { Requirement } from "./types.js" /** * Returns the list of matches from a requirement's filter diff --git a/modules/gob-examine-student/source/get-occurrences.js b/modules/gob-examine-student/source/get-occurrences.js index 4c64c1ae4..79e6cae28 100644 --- a/modules/gob-examine-student/source/get-occurrences.js +++ b/modules/gob-examine-student/source/get-occurrences.js @@ -1,7 +1,7 @@ // @flow -import filter from "lodash/filter" -import simplifyCourse from "./simplify-course" -import type { Course } from "./types" +import { filter } from "lodash" +import simplifyCourse from "./simplify-course.js" +import type { Course } from "./types.js" // old version; compares course objects instead of simplified versions // export default function getOccurrences(course, courses) { diff --git a/modules/gob-examine-student/source/get-override.js b/modules/gob-examine-student/source/get-override.js index 96e51af4f..1a9289f64 100644 --- a/modules/gob-examine-student/source/get-override.js +++ b/modules/gob-examine-student/source/get-override.js @@ -1,6 +1,6 @@ // @flow -import pathToOverride from "./path-to-override" -import type { OverridesPath, OverridesObject } from "./types" +import pathToOverride from "./path-to-override.js" +import type { OverridesPath, OverridesObject } from "./types.js" /** * Gets an override from an override object diff --git a/modules/gob-examine-student/source/has-override.js b/modules/gob-examine-student/source/has-override.js index 3566190a2..66d958e01 100644 --- a/modules/gob-examine-student/source/has-override.js +++ b/modules/gob-examine-student/source/has-override.js @@ -1,7 +1,7 @@ // @flow -import has from "lodash/has" -import pathToOverride from "./path-to-override" -import type { OverridesObject, OverridesPath } from "./types" +import { has } from "lodash" +import pathToOverride from "./path-to-override.js" +import type { OverridesObject, OverridesPath } from "./types.js" /** * Checks if an override object has an override diff --git a/modules/gob-examine-student/source/humanize-operator.js b/modules/gob-examine-student/source/humanize-operator.js index 5d9544867..d4d1a7bde 100644 --- a/modules/gob-examine-student/source/humanize-operator.js +++ b/modules/gob-examine-student/source/humanize-operator.js @@ -1,5 +1,6 @@ // @flow -import type { CounterOperatorEnum } from "./types" +import type { CounterOperatorEnum } from "./types.js" + export default function humanizeOperator(operator: CounterOperatorEnum) { if (operator === "$gte") { return "" diff --git a/modules/gob-examine-student/source/simplify-course.js b/modules/gob-examine-student/source/simplify-course.js index 648c3a8f9..ec9433c66 100644 --- a/modules/gob-examine-student/source/simplify-course.js +++ b/modules/gob-examine-student/source/simplify-course.js @@ -1,7 +1,7 @@ // @flow // import memoize from 'lodash/memoize' // import identity from 'lodash/identity' -import type { Course } from "./types" +import type { Course } from "./types.js" /** * Simplifies a course to just the department/number combo. diff --git a/modules/gob-hanson-format/convert-department.js b/modules/gob-hanson-format/convert-department.js index 79bd23dd5..e97856770 100644 --- a/modules/gob-hanson-format/convert-department.js +++ b/modules/gob-hanson-format/convert-department.js @@ -1,5 +1,5 @@ // @flow -import forEach from "lodash/forEach" +import { forEach } from "lodash" const shortDepartmentAbbreviationsToFullDepartmentAbbreviations = { AR: "ART", diff --git a/modules/gob-hanson-format/enhance-hanson.js b/modules/gob-hanson-format/enhance-hanson.js index f76d3c90b..d97d63d99 100644 --- a/modules/gob-hanson-format/enhance-hanson.js +++ b/modules/gob-hanson-format/enhance-hanson.js @@ -1,10 +1,9 @@ // @flow -import isRequirementName from "@gob/examine-student/source/is-requirement-name" -import fromPairs from "lodash/fromPairs" -import toPairs from "lodash/toPairs" -import { makeAreaSlug } from "./make-area-slug" -const { parse } = require("./parse-hanson-string") +import { isRequirementName } from "@gob/examine-student" +import { fromPairs, toPairs } from "lodash" +import { makeAreaSlug } from "./make-area-slug.js" +import { parse } from "./parse-hanson-string.js" type PegStartRule = "Filter" | "Result" diff --git a/modules/gob-hanson-format/index.js b/modules/gob-hanson-format/index.js index baeb1a411..d64c77947 100644 --- a/modules/gob-hanson-format/index.js +++ b/modules/gob-hanson-format/index.js @@ -1,8 +1,8 @@ // @flow -export { expandDepartment, normalizeDepartment } from "./convert-department" -export { enhanceHanson } from "./enhance-hanson" -export { makeAreaSlug } from "./make-area-slug" -export { parse } from "./parse-hanson-string" +export { expandDepartment, normalizeDepartment } from "./convert-department.js" +export { enhanceHanson } from "./enhance-hanson.js" +export { makeAreaSlug } from "./make-area-slug.js" +export { parse } from "./parse-hanson-string.js" -export type { ParsedHansonRequirement, ParsedHansonFile } from "./types" +export type { ParsedHansonRequirement, ParsedHansonFile } from "./types.js" diff --git a/modules/gob-hanson-format/make-area-slug.js b/modules/gob-hanson-format/make-area-slug.js index 83f3f2b92..9cf02b944 100644 --- a/modules/gob-hanson-format/make-area-slug.js +++ b/modules/gob-hanson-format/make-area-slug.js @@ -1,5 +1,5 @@ // @flow -import kebabCase from "lodash/kebabCase" +import { kebabCase } from "lodash" export function makeAreaSlug(name: string): string { return kebabCase((name || "").replace(/'/g, "")).toLowerCase() diff --git a/modules/gob-hanson-format/package.json b/modules/gob-hanson-format/package.json index 4dd02a058..a99c2fec6 100644 --- a/modules/gob-hanson-format/package.json +++ b/modules/gob-hanson-format/package.json @@ -3,8 +3,9 @@ "node": ">=22" }, "name": "@gob/hanson-format", + "type": "module", "version": "3.0.0-rc.2", - "main": "index.js", + "module": "index.js", "repository": "hawkrives/gobbldygook", "author": "Hawken MacKay Rives", "license": "MIT", diff --git a/modules/gob-hanson-format/parse-hanson-string.js b/modules/gob-hanson-format/parse-hanson-string.js index 75eb1727b..c0ce8c1bc 100644 --- a/modules/gob-hanson-format/parse-hanson-string.js +++ b/modules/gob-hanson-format/parse-hanson-string.js @@ -4308,7 +4308,5 @@ function peg$parse(input, options) { } } -module.exports = { - SyntaxError: peg$SyntaxError, - parse: peg$parse, -} +export const SyntaxError = peg$SyntaxError +export const parse = peg$parse diff --git a/modules/gob-web-database/index.js b/modules/gob-web-database/index.js index 2825ac26e..fafb4b74f 100644 --- a/modules/gob-web-database/index.js +++ b/modules/gob-web-database/index.js @@ -1,16 +1,284 @@ +/* eslint-disable camelcase */ // @flow -import treo, { Database } from "treo" +import { identifier, raw, sql, query } from "@electric-sql/pglite/template" +import { PGliteWorker } from "@electric-sql/pglite/worker" +import { live } from "@electric-sql/pglite/live" +// import { bloom } from "@electric-sql/pglite/contrib/bloom" +// import { btree_gin } from "@electric-sql/pglite/contrib/btree_gin" +// import { btree_gist } from "@electric-sql/pglite/contrib/btree_gist" +// import { pg_trgm } from "@electric-sql/pglite/contrib/pg_trgm" -import Promise from "es6-promise" -treo.Promise = Promise +const workerUrl = new URL("./worker.js", import.meta.url) +const worker = new Worker(workerUrl, { type: "module" }) +export const db = await PGliteWorker.create(worker, { + dataDir: "idb://gobbldygook-pglite", + relaxedDurability: true, + extensions: { + live, + // bloom, + // btree_gin, + // btree_gist, + // pg_trgm, + }, +}) -import queryTreoDatabase from "@gob/treo-plugin-query" -import batchGet from "@gob/treo-plugin-batch-get" +console.log('"gob-web-database" module initialized with PGliteWorker.') -import defaultSchema from "./schema" +export async function migrate() { + await db.transaction(async (tx) => { + await tx.exec(` + CREATE EXTENSION IF NOT EXISTS live; + CREATE EXTENSION IF NOT EXISTS bloom; + CREATE EXTENSION IF NOT EXISTS btree_gin; + CREATE EXTENSION IF NOT EXISTS btree_gist; + CREATE EXTENSION IF NOT EXISTS pg_trgm; + `) -export const createDatabase = ( - name: string = "gobbldygook", - schema: typeof defaultSchema = defaultSchema, -) => new Database(name, schema).use(queryTreoDatabase()).use(batchGet()) + await tx.exec(` + CREATE TABLE IF NOT EXISTS areas ( + id TEXT PRIMARY KEY NOT NULL, + data JSONB + ); + `) + + await tx.exec(` + CREATE TABLE IF NOT EXISTS areaCache ( + id TEXT PRIMARY KEY NOT NULL, + data JSONB + ); + `) + + await tx.exec(` + CREATE TABLE IF NOT EXISTS courseCache ( + id TEXT PRIMARY KEY NOT NULL, + data JSONB + ); + `) + + await tx.exec(` + CREATE TABLE IF NOT EXISTS courses ( + clbid TEXT PRIMARY KEY NOT NULL, + crsid TEXT, + credits NUMERIC, + dept TEXT, + deptnum TEXT, + department TEXT, + gereqs TEXT[], + groupid TEXT, + grouptype TEXT, + halfcredit BOOLEAN, + level TEXT, + name TEXT, + notes TEXT, + number TEXT[], + pf BOOLEAN, + places TEXT[], + profs TEXT[], + section TEXT, + semester TEXT, + term TEXT, + title TEXT, + type TEXT, + year NUMERIC, + sourcePath TEXT, + words TEXT[], + profWords TEXT[] + ); + `) + + console.log("Database schema migrated successfully.") + }) +} + +/** + * @param {Array} courses - courses + * @returns {Promise} - resolves when courses are inserted + */ +export async function insertCourses(courses) { + await db.transaction(async (tx) => { + // TODO: figure out how to do this in a batch + for (const course of courses) { + // eslint-disable-next-line no-await-in-loop + await tx.sql` + INSERT INTO courses ( + clbid, crsid, credits, dept, + deptnum, department, gereqs, groupid, + grouptype, halfcredit, level, name, + notes, number, pf, places, + profs, section, semester, term, + title, type, year, sourcePath, + words, profWords + ) VALUES ( + ${course.clbid}, ${course.crsid}, ${course.credits}, ${course.dept}, + ${course.deptnum}, ${course.department}, ${course.gereqs}, ${course.groupid}, + ${course.grouptype}, ${course.halfcredit}, ${course.level}, ${course.name}, + ${course.notes}, ${course.number}, ${course.pf}, ${course.places}, + ${course.profs}, ${course.section}, ${course.semester}, ${course.term}, + ${course.title}, ${course.type}, ${course.year}, ${course.sourcePath}, + ${course.words}, ${course.profWords} + ) + ` + } + }) +} + +await migrate() + +/** + * @param {Object} area - area of study + * @returns {Promise} - resolves when area is inserted + */ +export async function insertArea(area) { + await db.transaction(async (tx) => { + await tx.sql` + INSERT INTO areas (id, data) + VALUES (${area.id}, ${JSON.stringify(area)}) + ` + }) +} + +export async function listAreas() { + return db.transaction(async (tx) => { + const result = await tx.sql` + SELECT id, data + FROM areas + ` + return result.rows.map((row) => ({ + id: row.id, + ...JSON.parse(row.data), + })) + }) +} + +export async function removeArea(id) { + await removeAreas([id]) +} + +export async function removeAreas(ids) { + await db.transaction(async (tx) => { + await tx.exec( + `DELETE FROM areas WHERE id IN (${ids.map((id) => `'${id}'`).join(", ")})`, + ) + }) +} + +export async function removeCourse(clbid) { + await removeCourses([clbid]) +} + +export async function removeCourses(clbids) { + await db.transaction(async (tx) => { + await tx.exec( + `DELETE FROM courses WHERE clbid IN (${clbids.map((id) => `'${id}'`).join(", ")})`, + ) + }) +} + +/** + * @param {string} path - course path + * @returns {Promise} - resolves to an object mapping clbid to null for prior courses + **/ +export async function getPriorCourses(path) { + return db.transaction(async (tx) => { + const result = await tx.sql` + SELECT clbid FROM courses WHERE sourcePath = ${path} + ` + return Object.fromEntries(result.rows.map((row) => [row.clbid, null])) + }) +} + +/** + * @param {string} path - area path + * @returns {Promise} - resolves to an object mapping clbid to null for prior courses + **/ +export async function getPriorAreas(path) { + return db.transaction(async (tx) => { + const result = await tx.sql` + SELECT id FROM areas WHERE data->>'sourcePath' = ${path} + ` + return Object.fromEntries(result.rows.map((row) => [row.id, null])) + }) +} + +/** + * @param {string} path - course path + * @returns {Promise} - resolves to an object mapping clbid to null for prior courses + **/ +export async function cleanPriorCourses(path) { + return db.transaction(async (tx) => { + await tx.sql`DELETE FROM courses WHERE sourcePath = ${path}` + }) +} + +/** + * @param {string} path - area path + * @returns {Promise} - resolves to an object mapping clbid to null for prior courses + **/ +export async function cleanPriorAreas(path) { + return db.transaction(async (tx) => { + await tx.sql`DELETE FROM areas WHERE data->>'sourcePath' = ${path}` + }) +} + +export async function cleanCourseCache(path) { + return db.transaction(async (tx) => { + await tx.exec(`DELETE FROM courseCache WHERE id = '${path}'`) + }) +} + +export async function cleanAreaCache(path) { + return db.transaction(async (tx) => { + await tx.exec(`DELETE FROM areaCache WHERE id = '${path}'`) + }) +} + +/** + * @param {InfoFileTypeEnum} type - + * @returns {identifier} - + */ +function getCacheStoreName(type) { + if (type === "courses") { + return identifier`courseCache` + } else if (type === "areas") { + return identifier`areaCache` + } else { + console.warn(`"${type}" is not a valid store type`) + throw new TypeError(`"${type}" is not a valid store type`) + } +} + +/** + * @param {InfoFileTypeEnum} type - type of file, either "courses" or "areas" + * @param {string} path - path of the file + * @param {string} hash - hash of the file + * @returns {Promise} - resolves to true if the cache needs to be updated, false otherwise + */ +export async function cacheNeedsUpdate(type, path, hash) { + return db.transaction(async (tx) => { + const result = await tx.sql` + SELECT hash FROM ${getCacheStoreName(type)} WHERE id = ${path} + ` + if (result.rows.length === 0) { + return true + } + return result.rows[0].hash !== hash + }) +} + +/** + * @param {string} path - path of the file + * @param {InfoFileTypeEnum} type - type of file, either "courses" or "areas" + * @param {string} hash - hash of the file + * @returns {Promise} - resolves when the cache item is updated + */ +export async function cacheItemHash(path, type, hash) { + console.log(`caching ${path}`) + return db.transaction(async (tx) => { + await tx.sql` + INSERT INTO ${getCacheStoreName(type)} (id, hash) + VALUES (${path}, ${hash}) + ON CONFLICT (id) DO UPDATE SET hash = ${hash} + ` + }) +} diff --git a/modules/gob-web-database/package.json b/modules/gob-web-database/package.json index 7bdefa37a..756669ace 100644 --- a/modules/gob-web-database/package.json +++ b/modules/gob-web-database/package.json @@ -7,9 +7,11 @@ "main": "index.js", "license": "MIT", "dependencies": { + "@electric-sql/pglite": "^0.3.7", "@gob/treo-plugin-batch-get": "^3.0.0-rc.2", "@gob/treo-plugin-query": "^3.0.0-rc.2", "es6-promise": "^4.2.5", + "orange-orm": "^4.7.12", "treo": "^0.6.0-rc2" }, "devDependencies": { diff --git a/modules/gob-web-database/schema-orange.js b/modules/gob-web-database/schema-orange.js new file mode 100644 index 000000000..ba0d0b70d --- /dev/null +++ b/modules/gob-web-database/schema-orange.js @@ -0,0 +1,54 @@ +import orange from "orange-orm" + +// TODO: migrations? +// ... +// oh, I see. You actually create your database schema on your own, +// then you just tell orange what the schema looks like, here. + +const map = orange.map((x) => ({ + areas: x.table("areas").map(({ column }) => ({ + id: column("id").string().primary().notNullExceptInsert(), + data: column("data").json(), + })), + + areaCache: x.table("areaCache").map(({ column }) => ({ + id: column("id").string().primary().notNullExceptInsert(), + data: column("data").json(), + })), + + courseCache: x.table("courseCache").map(({ column }) => ({ + id: column("id").string().primary().notNullExceptInsert(), + data: column("data").json(), + })), + + courses: x.table("courses").map(({ column }) => ({ + clbid: column("clbid").string().primary().notNullExceptInsert(), + crsid: column("crsid").string(), + credits: column("credits").numeric(), + dept: column("dept").string(), + deptnum: column("deptnum").string(), + department: column("department").string(), + gereqs: column("gereqs").string().array(), + groupid: column("groupid").string(), + grouptype: column("grouptype").string(), + halfcredit: column("halfcredit").boolean(), + level: column("level").string(), + name: column("name").string(), + notes: column("notes").string(), + number: column("number").string().array(), + pf: column("pf").boolean(), + places: column("places").string().array(), + profs: column("profs").string().array(), + section: column("section").string(), + semester: column("semester").string(), + term: column("term").string(), + title: column("title").string(), + type: column("type").string(), + year: column("year").numeric(), + sourcePath: column("sourcePath").string(), + words: column("words").string().array(), + profWords: column("profWords").string().array(), + })), +})) + +export default map diff --git a/modules/gob-web-database/worker.js b/modules/gob-web-database/worker.js new file mode 100644 index 000000000..f9da8c31a --- /dev/null +++ b/modules/gob-web-database/worker.js @@ -0,0 +1,13 @@ +// @flow + +import { PGlite } from "@electric-sql/pglite" +import { worker } from "@electric-sql/pglite/worker" + +// TODO: migrate data from indexeddb to pglite + +worker({ + async init() { + // Create and return a PGlite instance + return new PGlite() + }, +}) diff --git a/modules/gob-web/helpers/db.js b/modules/gob-web/helpers/db.js index 3fd0604c2..4ec906477 100644 --- a/modules/gob-web/helpers/db.js +++ b/modules/gob-web/helpers/db.js @@ -1,5 +1,5 @@ // @flow -import { createDatabase } from "@gob/web-database" +import { db } from "@gob/web-database" -export const db = createDatabase() +export { db } diff --git a/modules/gob-worker-load-data/source/cache-item-hash.js b/modules/gob-worker-load-data/source/cache-item-hash.js index b1e2f09a9..9993eae3d 100644 --- a/modules/gob-worker-load-data/source/cache-item-hash.js +++ b/modules/gob-worker-load-data/source/cache-item-hash.js @@ -1,14 +1,5 @@ // @flow -import { db } from "./db" -import getCacheStoreName from "./get-cache-store-name" -import type { InfoFileTypeEnum } from "./types" +import { cacheItemHash } from "@gob/web-database" -export default function cacheItemHash( - path: string, - type: InfoFileTypeEnum, - hash: string, -) { - console.log(`caching ${path}`) - return db.store(getCacheStoreName(type)).put({ id: path, path, hash }) -} +export default cacheItemHash diff --git a/modules/gob-worker-load-data/source/clean-prior-data.js b/modules/gob-worker-load-data/source/clean-prior-data.js index 729c61195..df94ed3ea 100644 --- a/modules/gob-worker-load-data/source/clean-prior-data.js +++ b/modules/gob-worker-load-data/source/clean-prior-data.js @@ -1,44 +1,27 @@ // @flow -import { db } from "./db" -import range from "idb-range" -import fromPairs from "lodash/fromPairs" -import getCacheStoreName from "./get-cache-store-name" +import { + cleanPriorCourses, + cleanPriorAreas, + cleanCourseCache, + cleanAreaCache, +} from "@gob/web-database" import type { InfoFileTypeEnum } from "./types" -export function getPriorCourses(path: string) { - return db - .store("courses") - .index("sourcePath") - .getAll(range({ eq: path })) - .then((oldItems) => fromPairs(oldItems.map((item) => [item.clbid, null]))) -} - -export function getPriorAreas(path: string) { - return db - .store("areas") - .getAll(range({ eq: path })) - .then((oldItems) => - fromPairs(oldItems.map((item) => [item.sourcePath, null])), - ) -} - export default async function cleanPriorData( path: string, type: InfoFileTypeEnum, ) { console.log(`cleaning ${path}`) - let operations if (type === "courses") { - operations = await getPriorCourses(path) + await cleanPriorCourses(path) + await cleanCourseCache(path) } else if (type === "areas") { - operations = await getPriorAreas(path) + await cleanPriorAreas(path) + await cleanAreaCache(path) } else { console.warn(`"${type}" is not a valid store type`) throw new TypeError(`"${type}" is not a valid store type`) } - - await db.store(type).batch(operations) - await db.store(getCacheStoreName(type)).del(path) } diff --git a/modules/gob-worker-load-data/source/db.js b/modules/gob-worker-load-data/source/db.js deleted file mode 100644 index 3fd0604c2..000000000 --- a/modules/gob-worker-load-data/source/db.js +++ /dev/null @@ -1,5 +0,0 @@ -// @flow - -import { createDatabase } from "@gob/web-database" - -export const db = createDatabase() diff --git a/modules/gob-worker-load-data/source/get-cache-store-name.js b/modules/gob-worker-load-data/source/get-cache-store-name.js deleted file mode 100644 index 33f2888d2..000000000 --- a/modules/gob-worker-load-data/source/get-cache-store-name.js +++ /dev/null @@ -1,14 +0,0 @@ -// @flow - -import type { InfoFileTypeEnum } from "./types" - -export default function getCacheStoreName(type: InfoFileTypeEnum) { - if (type === "courses") { - return "courseCache" - } else if (type === "areas") { - return "areaCache" - } else { - console.warn(`"${type}" is not a valid store type`) - throw new TypeError(`"${type}" is not a valid store type`) - } -} diff --git a/modules/gob-worker-load-data/source/needs-update.js b/modules/gob-worker-load-data/source/needs-update.js index 65b34ea57..478745ec4 100644 --- a/modules/gob-worker-load-data/source/needs-update.js +++ b/modules/gob-worker-load-data/source/needs-update.js @@ -1,7 +1,6 @@ // @flow -import { db } from "./db" -import getCacheStoreName from "./get-cache-store-name" +import { cacheNeedsUpdate } from "@gob/web-database" import type { InfoFileTypeEnum } from "./types" export default function needsUpdate( @@ -9,10 +8,5 @@ export default function needsUpdate( path: string, hash: string, ) { - return db - .store(getCacheStoreName(type)) - .get(path) - .then((dbresult) => { - return dbresult ? dbresult.hash !== hash : true - }) + return cacheNeedsUpdate(type, path, hash) } diff --git a/modules/gob-worker-load-data/source/remove-duplicate-areas.js b/modules/gob-worker-load-data/source/remove-duplicate-areas.js index 9cf2c1955..0e868ca8b 100644 --- a/modules/gob-worker-load-data/source/remove-duplicate-areas.js +++ b/modules/gob-worker-load-data/source/remove-duplicate-areas.js @@ -1,9 +1,7 @@ // @flow -import { db } from "./db" +import { listAreas, removeArea } from "@gob/web-database" import groupBy from "lodash/groupBy" -import filter from "lodash/filter" -import fromPairs from "lodash/fromPairs" import sortBy from "lodash/sortBy" type AreaOfStudy = { @@ -14,7 +12,7 @@ type AreaOfStudy = { } export function buildRemoveAreaOps(areas: AreaOfStudy[]) { - return fromPairs(areas.map((item) => [item.sourcePath, null])) + return Object.fromEntries(areas.map((item) => [item.sourcePath, null])) } // TODO: add logging to this function @@ -29,7 +27,9 @@ export function generateOps(allAreas: AreaOfStudy[]) { allAreas, (area) => `{${area.name}, ${area.type}, ${area.revision}}`, ) - const duplicateGroup = filter(grouped, (list) => list.length > 1) + const duplicateGroup = Object.values(grouped).filter( + (list) => list.length > 1, + ) let ops = {} for (let dupsList of duplicateGroup) { @@ -56,7 +56,14 @@ export function generateOps(allAreas: AreaOfStudy[]) { } export default async function removeDuplicateAreas() { - let allAreas = await db.store("areas").getAll() + let allAreas = await listAreas() let ops = generateOps(allAreas) - return db.store("areas").batch(ops) + for (const [areaId, removeIfNull] of Object.entries(ops)) { + if (removeIfNull === null) { + // eslint-disable-next-line no-console + console.log(`Removing area: ${areaId}`) + // eslint-disable-next-line no-await-in-loop + await removeArea(areaId) + } + } } diff --git a/modules/gob-worker-load-data/source/store-data.js b/modules/gob-worker-load-data/source/store-data.js index 36ee6ffad..e07a6987a 100644 --- a/modules/gob-worker-load-data/source/store-data.js +++ b/modules/gob-worker-load-data/source/store-data.js @@ -3,14 +3,14 @@ import present from "present" import prepareCourse from "./lib-prepare-course" import { quotaExceededError } from "./lib-dispatch" -import { db } from "./db" +import { insertArea, insertCourses } from "@gob/web-database" import type { InfoFileTypeEnum } from "./types" import prettyMs from "pretty-ms" type BasicCourse = Object type BasicArea = { type: string } -export function storeCourses(path: string, data: Array) { +export async function storeCourses(path: string, data: Array) { console.log(`courses: storing ${path}`) let coursesToStore = data.map((course) => ({ @@ -19,15 +19,13 @@ export function storeCourses(path: string, data: Array) { sourcePath: path, })) - const start = present() - - const onSuccess = () => { + try { + const start = present() + await insertCourses(coursesToStore) let time = present() - start console.log(`stored ${coursesToStore.length} courses in ${prettyMs(time)}.`) - } - - // istanbul ignore next - const onFailure = (err) => { + } catch (err) { + // istanbul ignore next const db = err.target.db.name const errorName = err.target.error.name @@ -35,14 +33,11 @@ export function storeCourses(path: string, data: Array) { if (errorName === "QuotaExceededError") { quotaExceededError(db) } - throw err } - - return db.store("courses").batch(coursesToStore).then(onSuccess, onFailure) } -export function storeArea(path: string, data: BasicArea) { +export async function storeArea(path: string, data: BasicArea) { console.log(`areas: storing ${path}`) const area = { @@ -52,15 +47,13 @@ export function storeArea(path: string, data: BasicArea) { dateAdded: new Date(), } - const start = present() - - const onSuccess = () => { + try { + const start = present() + await insertArea(area) let time = present() - start console.log(`stored area ${path} in ${prettyMs(time)}.`) - } - - // istanbul ignore next - const onFailure = (err) => { + } catch (err) { + // istanbul ignore next const db = err.target.db.name const errorName = err.target.error.name @@ -68,11 +61,8 @@ export function storeArea(path: string, data: BasicArea) { if (errorName === "QuotaExceededError") { quotaExceededError(db) } - throw err } - - return db.store("areas").put(area).then(onSuccess, onFailure) } export default function storeData( diff --git a/package-lock.json b/package-lock.json index f8cca6860..098f16960 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,28 @@ "name": "gobbldygook", "version": "3.0.0-rc.2", "workspaces": [ - "modules/*" + "./modules/gob-cli", + "./modules/gob-colors", + "./modules/gob-courses", + "./modules/gob-examine-student", + "./modules/gob-hanson-format", + "./modules/gob-hanson-format-cli", + "./modules/gob-lib", + "./modules/gob-object-student", + "./modules/gob-schedule-builder", + "./modules/gob-schedule-conflicts", + "./modules/gob-school-st-olaf-college", + "./modules/gob-school-st-olaf-college-sis-import", + "./modules/gob-search-queries", + "./modules/gob-search-queries-cli", + "./modules/gob-treo-plugin-batch-get", + "./modules/gob-treo-plugin-query", + "./modules/gob-types", + "./modules/gob-web", + "./modules/gob-web-database", + "./modules/gob-webpack-plugin-html", + "./modules/gob-worker-check-student", + "./modules/gob-worker-load-data" ], "devDependencies": { "@babel/core": "7.28.0", @@ -396,9 +417,11 @@ "version": "3.0.0-rc.2", "license": "MIT", "dependencies": { + "@electric-sql/pglite": "^0.3.7", "@gob/treo-plugin-batch-get": "^3.0.0-rc.2", "@gob/treo-plugin-query": "^3.0.0-rc.2", "es6-promise": "^4.2.5", + "orange-orm": "^4.7.12", "treo": "^0.6.0-rc2" }, "devDependencies": { @@ -2391,6 +2414,12 @@ "integrity": "sha512-tE2cPhAq+WFnA9XrfMfP+u/6L63eH7+PmONMNSXtP6kPt/iUXnwkDsxc1Q6lUP1oM3LsmWBrxn+/93M8JE6fpA==", "license": "MIT" }, + "node_modules/@cloudflare/workers-types": { + "version": "4.20250816.0", + "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-4.20250816.0.tgz", + "integrity": "sha512-R9ADrrINo1CqTwCddH39Tjlsc3grim6KeO7l8yddNbldH3uTkaAXYCzO0WiyLG7irLzLDrZVc4tLhN6BO3tdFw==", + "license": "MIT OR Apache-2.0" + }, "node_modules/@codemirror/autocomplete": { "version": "6.18.6", "resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.18.6.tgz", @@ -2509,6 +2538,12 @@ "node": ">=14.17.0" } }, + "node_modules/@electric-sql/pglite": { + "version": "0.3.7", + "resolved": "https://registry.npmjs.org/@electric-sql/pglite/-/pglite-0.3.7.tgz", + "integrity": "sha512-5c3mybVrhxu5s47zFZtIGdG8YHkKCBENOmqxnNBjY53ZoDhADY/c5UqBDl159b7qtkzNPtbbb893wL9zi1kAuw==", + "license": "Apache-2.0" + }, "node_modules/@emotion/babel-utils": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/@emotion/babel-utils/-/babel-utils-0.6.10.tgz", @@ -2827,7 +2862,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", - "dev": true, "license": "MIT", "engines": { "node": "20 || >=22" @@ -2837,7 +2871,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", - "dev": true, "license": "MIT", "dependencies": { "@isaacs/balanced-match": "^4.0.1" @@ -2846,6 +2879,102 @@ "node": "20 || >=22" } }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.0.tgz", + "integrity": "sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", @@ -3322,6 +3451,15 @@ "@lezer/common": "^1.0.0" } }, + "node_modules/@lroal/on-change": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@lroal/on-change/-/on-change-4.0.2.tgz", + "integrity": "sha512-k2wiMxzPu7xAAittX4DTyYlk1Y+ElCi6Ni5OyQLDV8Qjallm1FXOIWZOmiH+GOxC6kj4a3dCCAVmzrI3/HUBiA==", + "license": "ISC", + "dependencies": { + "on-change": "^4.0.1" + } + }, "node_modules/@marijn/find-cluster-break": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz", @@ -3530,6 +3668,12 @@ "node": ">=10" } }, + "node_modules/@tediousjs/connection-string": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/@tediousjs/connection-string/-/connection-string-0.4.4.tgz", + "integrity": "sha512-Qssn7gmOILmqD0zkfA09YyFd52UajWYkLTTSi4Dx/XZaUuVcx4W4guv2rAVc5mm8wYRdonmG/HfFH3PS6izXAg==", + "license": "MIT" + }, "node_modules/@testing-library/dom": { "version": "10.4.1", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.1.tgz", @@ -3723,7 +3867,6 @@ "version": "1.19.6", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", - "dev": true, "license": "MIT", "dependencies": { "@types/connect": "*", @@ -3762,7 +3905,6 @@ "version": "3.4.38", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*" @@ -3790,7 +3932,6 @@ "version": "4.17.23", "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", - "dev": true, "license": "MIT", "dependencies": { "@types/body-parser": "*", @@ -3816,7 +3957,6 @@ "version": "4.19.6", "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", - "dev": true, "license": "MIT", "dependencies": { "@types/node": "*", @@ -3895,7 +4035,6 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", - "dev": true, "license": "MIT" }, "node_modules/@types/http-proxy": { @@ -3974,7 +4113,6 @@ "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", - "dev": true, "license": "MIT" }, "node_modules/@types/minimist": { @@ -4005,6 +4143,15 @@ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", "license": "MIT" }, + "node_modules/@types/oracledb": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/@types/oracledb/-/oracledb-6.9.1.tgz", + "integrity": "sha512-rXDnApyfaki0dvHuqzQvfirK6yHbtEO5nJ4CXKHrZYdwNAx4PjddqoCXdN1dZaEnZxXFwCy9xEWyIemL8EI/NQ==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/parse-json": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz", @@ -4021,14 +4168,12 @@ "version": "6.14.0", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/range-parser": { "version": "1.2.7", "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", - "dev": true, "license": "MIT" }, "node_modules/@types/react": { @@ -4079,7 +4224,6 @@ "version": "0.17.5", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", - "dev": true, "license": "MIT", "dependencies": { "@types/mime": "^1", @@ -4112,7 +4256,6 @@ "version": "1.15.8", "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "dev": true, "license": "MIT", "dependencies": { "@types/http-errors": "*", @@ -4137,6 +4280,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/tedious": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/@types/tedious/-/tedious-4.0.14.tgz", + "integrity": "sha512-KHPsfX/FoVbUGbyYvk1q9MMQHLPeRZhRJZdO45Q4YjvFkv4hMNghCWTvy7rdKessBsmtz4euWCWAB6/tVpI1Iw==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/tough-cookie": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz", @@ -4643,7 +4795,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -4899,6 +5050,15 @@ "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, + "node_modules/ast-module-types": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ast-module-types/-/ast-module-types-6.0.1.tgz", + "integrity": "sha512-WHw67kLXYbZuHTmcdbIrVArCq5wxo6NEuj3hiYAWr8mwJeC+C2mMCIBIWCiDoCye/OF/xelc+teJ1ERoWmnEIA==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/async-function": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-function/-/async-function-1.0.0.tgz", @@ -4913,7 +5073,6 @@ "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true, "license": "MIT" }, "node_modules/atob": { @@ -4964,6 +5123,17 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.11.0.tgz", + "integrity": "sha512-1Lx3WLFQWm3ooKDYZD1eXmoGO9fxYQjrycfHFC8P0sCfQVXyROp0p9PFWBehewBOdCwHc+f/b8I0fMto5eSfwA==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.4", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/babel-jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", @@ -5671,7 +5841,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -6022,7 +6191,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -6422,7 +6590,6 @@ "version": "7.0.6", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", - "dev": true, "license": "MIT", "dependencies": { "path-key": "^3.1.0", @@ -6967,7 +7134,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4.0" @@ -7005,6 +7171,15 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", @@ -7137,7 +7312,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.1", @@ -7268,6 +7442,12 @@ "node": ">=4" } }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "license": "MIT" + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -7298,7 +7478,6 @@ "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, "license": "MIT" }, "node_modules/emojis-list": { @@ -7471,7 +7650,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7481,7 +7659,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -7525,7 +7702,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -7538,7 +7714,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", - "dev": true, "license": "MIT", "dependencies": { "es-errors": "^1.3.0", @@ -8257,6 +8432,18 @@ "node": ">= 0.8.0" } }, + "node_modules/expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==", + "license": "MIT", + "dependencies": { + "homedir-polyfill": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/expect": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", @@ -8352,7 +8539,12 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, + "license": "MIT" + }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", "license": "MIT" }, "node_modules/fast-json-stable-stringify": { @@ -8373,7 +8565,6 @@ "version": "3.0.6", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", - "dev": true, "funding": [ { "type": "github", @@ -8661,6 +8852,21 @@ "node": ">=8" } }, + "node_modules/findup-sync": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-5.0.0.tgz", + "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==", + "license": "MIT", + "dependencies": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.3", + "micromatch": "^4.0.4", + "resolve-dir": "^1.0.1" + }, + "engines": { + "node": ">= 10.13.0" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -8776,10 +8982,9 @@ "license": "MIT" }, "node_modules/follow-redirects": { - "version": "1.14.8", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.8.tgz", - "integrity": "sha512-1x0S9UVJHsQprFcEC/qnNzBLcIxsjAV905f/UkQxbclCsoTWlacCNOpQa/anodLl2uaEKFhfWOvM2Qg77+15zA==", - "dev": true, + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", "funding": [ { "type": "individual", @@ -8812,11 +9017,38 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/foreground-child/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/form-data": { "version": "4.0.4", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", - "dev": true, "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -8973,7 +9205,6 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", "dependencies": { "call-bind-apply-helpers": "^1.0.2", @@ -8998,7 +9229,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", "dependencies": { "dunder-proto": "^1.0.1", @@ -9091,6 +9321,48 @@ "dev": true, "license": "BSD-2-Clause" }, + "node_modules/global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "license": "MIT", + "dependencies": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, "node_modules/globals": { "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", @@ -9186,7 +9458,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9312,7 +9583,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -9325,7 +9595,6 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", - "dev": true, "license": "MIT", "dependencies": { "has-symbols": "^1.0.3" @@ -9358,6 +9627,18 @@ "react-is": "^16.7.0" } }, + "node_modules/homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "license": "MIT", + "dependencies": { + "parse-passwd": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/hosted-git-info": { "version": "2.8.9", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", @@ -9701,6 +9982,12 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "license": "ISC" + }, "node_modules/internal-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.1.0.tgz", @@ -9927,7 +10214,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -9953,7 +10239,6 @@ "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, "license": "MIT", "engines": { "node": ">=8" @@ -9992,7 +10277,6 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" @@ -10063,7 +10347,6 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.12.0" @@ -10318,6 +10601,15 @@ "integrity": "sha512-00pwt/Jf7IaRh5m2Dp93Iw8LG2cd3OpDj3NrD1XPNUpAWVxPvBP296p4IiGmIU4Ur0f3f56IoIM+fS2pFYF+tQ==", "license": "MIT" }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", @@ -10351,7 +10643,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true, "license": "ISC" }, "node_modules/isobject": { @@ -10478,6 +10769,21 @@ "node": ">= 0.4" } }, + "node_modules/jackspeak": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz", + "integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==", + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/jest": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", @@ -11676,7 +11982,6 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.4" @@ -12005,7 +12310,6 @@ "version": "4.0.8", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -12019,7 +12323,6 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", - "dev": true, "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -12032,7 +12335,6 @@ "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -12055,7 +12357,6 @@ "version": "2.1.35", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "dev": true, "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -12068,7 +12369,6 @@ "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -12174,6 +12474,15 @@ "node": ">=0.10.0" } }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, "node_modules/mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -12223,6 +12532,22 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/module-definition": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/module-definition/-/module-definition-6.0.1.tgz", + "integrity": "sha512-FeVc50FTfVVQnolk/WQT8MX+2WVcDnTGiq6Wo+/+lJ2ET1bRVi3HG3YlJUfqagNMc/kUlFSoR96AJkxGpKz13g==", + "license": "MIT", + "dependencies": { + "ast-module-types": "^6.0.1", + "node-source-walk": "^7.0.1" + }, + "bin": { + "module-definition": "bin/cli.js" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -12356,6 +12681,18 @@ "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", "license": "MIT" }, + "node_modules/node-source-walk": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/node-source-walk/-/node-source-walk-7.0.1.tgz", + "integrity": "sha512-3VW/8JpPqPvnJvseXowjZcirPisssnBuDikk6JIZ8jQzF7KJQX52iPFX4RYYxLycYH7IbMRSPUOga/esVjy5Yg==", + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.7" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/nopt": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz", @@ -12565,6 +12902,18 @@ "dev": true, "license": "MIT" }, + "node_modules/on-change": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/on-change/-/on-change-4.0.2.tgz", + "integrity": "sha512-cMtCyuJmTx/bg2HCpHo3ZLeF7FZnBOapLqZHr2AlLeJ5Ul0Zu2mUJJz051Fdwu/Et2YW04ZD+TtU+gVy0ACNCA==", + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/on-change?sponsor=1" + } + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -12650,6 +12999,150 @@ "node": ">= 0.8.0" } }, + "node_modules/orange-orm": { + "version": "4.7.12", + "resolved": "https://registry.npmjs.org/orange-orm/-/orange-orm-4.7.12.tgz", + "integrity": "sha512-MNgtlgnrUEs63iqx8KjD1J850VbW+F0QCMTw6spUTPKg3WRBmUcHZ8W031CVor9Mg+EZaQfliPX3drnc1xY3Uw==", + "license": "ISC", + "dependencies": { + "@cloudflare/workers-types": "^4.20241106.0", + "@lroal/on-change": "^4.0.2", + "@tediousjs/connection-string": "^0.4.1", + "@types/express": "^4.17.13", + "@types/oracledb": "^6.0.4", + "@types/tedious": "^4.0.14", + "ajv": "^8.17.1", + "axios": "^1.6.2", + "fast-json-patch": "^3.1.1", + "findup-sync": "^5.0.0", + "glob": "^10.3.4 || ^11.0.2", + "module-definition": "^4.0.0 || ^5.0.0 || || ^6.0.0", + "rfdc": "^1.2.0", + "uuid": "^8.3.2 || ^9.0.0 || ^10.0.0 || ^11.1.0" + }, + "bin": { + "orange-orm": "bin/rdb.js" + }, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/lroal" + }, + "peerDependencies": { + "@electric-sql/pglite": "^0.3.0", + "msnodesqlv8": "^4.1.0", + "mysql2": "^2.2.5 || ^3.9.4", + "oracledb": "^6.3.0", + "pg": "^8.5.1", + "pg-query-stream": "^3.3.2", + "sqlite3": "^5.0.2", + "tedious": "^15.1.2 || ^16.0.0 || ^18.1.0 || || ^19.0.0" + }, + "peerDependenciesMeta": { + "@electric-sql/pglite": { + "optional": true + }, + "msnodesqlv8": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-native": { + "optional": true + }, + "pg-query-stream": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/orange-orm/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/orange-orm/node_modules/glob": { + "version": "11.0.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.3.tgz", + "integrity": "sha512-2Nim7dha1KVkaiF4q6Dj+ngPPMdfvLJEOpZk/jKiUAkqKebpGAWQXAq9z1xu9HKu5lWfqw/FASuccEjyznjPaA==", + "license": "ISC", + "dependencies": { + "foreground-child": "^3.3.1", + "jackspeak": "^4.1.1", + "minimatch": "^10.0.3", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^2.0.0" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/orange-orm/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/orange-orm/node_modules/minimatch": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.0.3.tgz", + "integrity": "sha512-IPZ167aShDZZUMdRk66cyQAW3qr0WzbHkPdMYa8bzZhlHhO3jALbKdxcaak7W9FfT2rZNpQuUu4Od7ILEpXSaw==", + "license": "ISC", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/orange-orm/node_modules/uuid": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-11.1.0.tgz", + "integrity": "sha512-0/A9rDy9P7cJ+8w1c9WD9V//9Wj15Ce2MPz8Ri6032usz+NfePxx5AcN3bN+r6ZL6jEo066/yNYB3tn4pQEx+A==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/esm/bin/uuid" + } + }, "node_modules/ord": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/ord/-/ord-1.0.1.tgz", @@ -12797,6 +13290,12 @@ "node": ">=6" } }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "license": "BlueOak-1.0.0" + }, "node_modules/parallel-transform": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", @@ -12845,6 +13344,15 @@ "node": ">=6" } }, + "node_modules/parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/parse5": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", @@ -12906,7 +13414,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -12918,6 +13425,31 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "license": "MIT" }, + "node_modules/path-scurry": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.0.tgz", + "integrity": "sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg==", + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^11.0.0", + "minipass": "^7.1.2" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.1.0.tgz", + "integrity": "sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==", + "license": "ISC", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -13356,6 +13888,12 @@ "node": ">= 0.10" } }, + "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==", + "license": "MIT" + }, "node_modules/psl": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.15.0.tgz", @@ -14172,7 +14710,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -14228,6 +14765,19 @@ "node": ">=8" } }, + "node_modules/resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==", + "license": "MIT", + "dependencies": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "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", @@ -14283,6 +14833,12 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "license": "MIT" + }, "node_modules/rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -14899,7 +15455,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "dev": true, "license": "MIT", "dependencies": { "shebang-regex": "^3.0.0" @@ -14912,7 +15467,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", - "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -15360,7 +15914,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -15371,6 +15924,21 @@ "node": ">=8" } }, + "node_modules/string-width-cjs": { + "name": "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==", + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/string.prototype.matchall": { "version": "4.0.12", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", @@ -15471,7 +16039,19 @@ "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/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" }, @@ -15867,7 +16447,6 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -16962,7 +17541,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, "license": "ISC", "dependencies": { "isexe": "^2.0.0" @@ -17136,6 +17714,24 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "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==", + "license": "MIT", + "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/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 9a9c503aa..56ff658ea 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,28 @@ "version": "3.0.0-rc.2", "private": true, "workspaces": [ - "modules/*" + "./modules/gob-cli", + "./modules/gob-colors", + "./modules/gob-courses", + "./modules/gob-examine-student", + "./modules/gob-hanson-format", + "./modules/gob-hanson-format-cli", + "./modules/gob-lib", + "./modules/gob-object-student", + "./modules/gob-schedule-builder", + "./modules/gob-schedule-conflicts", + "./modules/gob-school-st-olaf-college", + "./modules/gob-school-st-olaf-college-sis-import", + "./modules/gob-search-queries", + "./modules/gob-search-queries-cli", + "./modules/gob-treo-plugin-batch-get", + "./modules/gob-treo-plugin-query", + "./modules/gob-types", + "./modules/gob-web", + "./modules/gob-web-database", + "./modules/gob-webpack-plugin-html", + "./modules/gob-worker-check-student", + "./modules/gob-worker-load-data" ], "jest": { "testEnvironment": "jsdom", From 8b5f312d1dda7aa3d6155853622d3e4116327d65 Mon Sep 17 00:00:00 2001 From: Hawken Rives Date: Sun, 17 Aug 2025 18:15:22 -0400 Subject: [PATCH 2/4] Update index.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- modules/gob-web-database/index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/gob-web-database/index.js b/modules/gob-web-database/index.js index fafb4b74f..7ec5da5b1 100644 --- a/modules/gob-web-database/index.js +++ b/modules/gob-web-database/index.js @@ -159,7 +159,9 @@ export async function removeAreas(ids) { await db.transaction(async (tx) => { await tx.exec( `DELETE FROM areas WHERE id IN (${ids.map((id) => `'${id}'`).join(", ")})`, - ) + await tx.sql` + DELETE FROM areas WHERE id IN (${ids}) + ` }) } From f1e0b50825b73c3410a0f23694bd0fc2aabfea4e Mon Sep 17 00:00:00 2001 From: Hawken Rives Date: Sun, 17 Aug 2025 18:15:38 -0400 Subject: [PATCH 3/4] Update index.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- modules/gob-web-database/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gob-web-database/index.js b/modules/gob-web-database/index.js index 7ec5da5b1..08863472a 100644 --- a/modules/gob-web-database/index.js +++ b/modules/gob-web-database/index.js @@ -225,7 +225,7 @@ export async function cleanPriorAreas(path) { export async function cleanCourseCache(path) { return db.transaction(async (tx) => { - await tx.exec(`DELETE FROM courseCache WHERE id = '${path}'`) + await tx.sql`DELETE FROM courseCache WHERE id = ${path}` }) } From e9834c82d10f09237a7aea40209e52dcfbabf0ce Mon Sep 17 00:00:00 2001 From: Hawken Rives Date: Sun, 17 Aug 2025 18:15:44 -0400 Subject: [PATCH 4/4] Update index.js Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- modules/gob-web-database/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/gob-web-database/index.js b/modules/gob-web-database/index.js index 08863472a..5f9137ad8 100644 --- a/modules/gob-web-database/index.js +++ b/modules/gob-web-database/index.js @@ -231,7 +231,7 @@ export async function cleanCourseCache(path) { export async function cleanAreaCache(path) { return db.transaction(async (tx) => { - await tx.exec(`DELETE FROM areaCache WHERE id = '${path}'`) + await tx.sql`DELETE FROM areaCache WHERE id = ${path}` }) }