@playcademy/sandbox 0.5.2-beta.2 → 0.5.2-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -198,7 +198,8 @@ var AUTH_PROVIDER_IDS, DEMO_DISPLAY_NAME_PLACEHOLDER = "Demo Player";
198
198
  var init_auth = __esm(() => {
199
199
  AUTH_PROVIDER_IDS = {
200
200
  TIMEBACK: "timeback",
201
- TIMEBACK_LTI: "timeback-lti"
201
+ TIMEBACK_LTI: "timeback-lti",
202
+ PLAYCADEMY: "playcademy"
202
203
  };
203
204
  });
204
205
 
@@ -1078,7 +1079,7 @@ var package_default;
1078
1079
  var init_package = __esm(() => {
1079
1080
  package_default = {
1080
1081
  name: "@playcademy/sandbox",
1081
- version: "0.5.2-beta.2",
1082
+ version: "0.5.2-beta.4",
1082
1083
  description: "Local development server for Playcademy game development",
1083
1084
  type: "module",
1084
1085
  exports: {
@@ -11323,23 +11324,31 @@ var init_table6 = __esm(() => {
11323
11324
  });
11324
11325
 
11325
11326
  // ../data/src/domains/timeback/table.ts
11326
- var gameTimebackIntegrations, gameTimebackAssessmentTests, gameTimebackMetricDiscrepancyVerifications;
11327
+ var gameTimebackIntegrationStatusEnum, gameTimebackIntegrations, gameTimebackAssessmentTests, gameTimebackMetricDiscrepancyVerifications;
11327
11328
  var init_table7 = __esm(() => {
11329
+ init_drizzle_orm();
11328
11330
  init_pg_core();
11329
11331
  init_table5();
11330
11332
  init_table3();
11333
+ gameTimebackIntegrationStatusEnum = pgEnum("game_timeback_integration_status", [
11334
+ "active",
11335
+ "deactivated"
11336
+ ]);
11331
11337
  gameTimebackIntegrations = pgTable("game_timeback_integrations", {
11332
11338
  id: uuid("id").primaryKey().defaultRandom(),
11333
11339
  gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11334
11340
  courseId: text("course_id").notNull(),
11335
11341
  grade: integer("grade").notNull(),
11336
11342
  subject: text("subject").notNull(),
11343
+ status: gameTimebackIntegrationStatusEnum("status"),
11337
11344
  totalXp: integer("total_xp"),
11338
11345
  lastVerifiedAt: timestamp("last_verified_at", { withTimezone: true }),
11346
+ deactivatedAt: timestamp("deactivated_at", { withTimezone: true }),
11347
+ reactivatedAt: timestamp("reactivated_at", { withTimezone: true }),
11339
11348
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
11340
11349
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
11341
11350
  }, (table3) => [
11342
- uniqueIndex("game_timeback_integrations_game_grade_subject_idx").on(table3.gameId, table3.grade, table3.subject)
11351
+ uniqueIndex("game_timeback_integrations_game_grade_subject_idx").on(table3.gameId, table3.grade, table3.subject).where(sql`${table3.status} IS DISTINCT FROM 'deactivated'`)
11343
11352
  ]);
11344
11353
  gameTimebackAssessmentTests = pgTable("game_timeback_assessment_tests", {
11345
11354
  id: uuid("id").primaryKey().defaultRandom(),
@@ -11382,6 +11391,7 @@ __export(exports_tables_index, {
11382
11391
  gameTypeEnum: () => gameTypeEnum,
11383
11392
  gameTimebackMetricDiscrepancyVerifications: () => gameTimebackMetricDiscrepancyVerifications,
11384
11393
  gameTimebackIntegrations: () => gameTimebackIntegrations,
11394
+ gameTimebackIntegrationStatusEnum: () => gameTimebackIntegrationStatusEnum,
11385
11395
  gameTimebackAssessmentTests: () => gameTimebackAssessmentTests,
11386
11396
  gameScoresRelations: () => gameScoresRelations,
11387
11397
  gameScores: () => gameScores,
@@ -24673,6 +24683,7 @@ var init_helpers = __esm(() => {
24673
24683
 
24674
24684
  // ../cloudflare/src/playcademy/provider/provider.ts
24675
24685
  var init_provider = __esm(() => {
24686
+ init_src();
24676
24687
  init_src();
24677
24688
  init_core();
24678
24689
  init_constants2();
@@ -27768,6 +27779,20 @@ var init_game_member_service = __esm(() => {
27768
27779
  init_spans();
27769
27780
  init_errors();
27770
27781
  });
27782
+ // ../data/src/domains/timeback/helpers.ts
27783
+ function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
27784
+ return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
27785
+ }
27786
+ var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
27787
+ var init_helpers2 = __esm(() => {
27788
+ init_drizzle_orm();
27789
+ init_table7();
27790
+ });
27791
+
27792
+ // ../data/src/helpers.index.ts
27793
+ var init_helpers_index = __esm(() => {
27794
+ init_helpers2();
27795
+ });
27771
27796
 
27772
27797
  // ../utils/src/fns.ts
27773
27798
  function sleep(ms) {
@@ -27777,15 +27802,584 @@ function sleep(ms) {
27777
27802
  return new Promise((resolve) => setTimeout(resolve, ms));
27778
27803
  }
27779
27804
 
27805
+ // ../timeback/dist/types.js
27806
+ function isObject(value) {
27807
+ return typeof value === "object" && value !== null;
27808
+ }
27809
+ function isCourseMetadata(value) {
27810
+ return isObject(value);
27811
+ }
27812
+ function isResourceMetadata(value) {
27813
+ return isObject(value);
27814
+ }
27815
+ function isPlaycademyResourceMetadata(value) {
27816
+ if (!isObject(value)) {
27817
+ return false;
27818
+ }
27819
+ if (!("mastery" in value) || value.mastery === undefined) {
27820
+ return true;
27821
+ }
27822
+ return isObject(value.mastery);
27823
+ }
27824
+ function isTimebackSubject(value) {
27825
+ return typeof value === "string" && SUBJECT_VALUES.includes(value);
27826
+ }
27827
+ function isTimebackGrade(value) {
27828
+ return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES.includes(value);
27829
+ }
27830
+ var __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants3, SUBJECT_VALUES, GRADE_VALUES;
27831
+ var init_types2 = __esm(() => {
27832
+ init_src();
27833
+ init_constants3 = __esm2(() => {
27834
+ TIMEBACK_API_URLS = {
27835
+ production: "https://api.alpha-1edtech.ai",
27836
+ staging: "https://api.staging.alpha-1edtech.com"
27837
+ };
27838
+ TIMEBACK_AUTH_URLS = {
27839
+ production: "https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com",
27840
+ staging: "https://alpha-auth-development-idp.auth.us-west-2.amazoncognito.com"
27841
+ };
27842
+ CALIPER_API_URLS = {
27843
+ production: "https://caliper.alpha-1edtech.ai",
27844
+ staging: "https://caliper-staging.alpha-1edtech.com"
27845
+ };
27846
+ ONEROSTER_ENDPOINTS = {
27847
+ organizations: "/ims/oneroster/rostering/v1p2/orgs",
27848
+ courses: "/ims/oneroster/rostering/v1p2/courses",
27849
+ courseComponents: "/ims/oneroster/rostering/v1p2/courses/components",
27850
+ resources: "/ims/oneroster/resources/v1p2/resources",
27851
+ componentResources: "/ims/oneroster/rostering/v1p2/courses/component-resources",
27852
+ classes: "/ims/oneroster/rostering/v1p2/classes",
27853
+ enrollments: "/ims/oneroster/rostering/v1p2/enrollments",
27854
+ assessmentLineItems: "/ims/oneroster/gradebook/v1p2/assessmentLineItems",
27855
+ assessmentResults: "/ims/oneroster/gradebook/v1p2/assessmentResults",
27856
+ users: "/ims/oneroster/rostering/v1p2/users"
27857
+ };
27858
+ QTI_ENDPOINTS = {
27859
+ assessmentTests: "/assessment-tests",
27860
+ assessmentItems: "/assessment-items"
27861
+ };
27862
+ CALIPER_ENDPOINTS = {
27863
+ event: "/caliper/event",
27864
+ events: "/caliper/events",
27865
+ validate: "/caliper/event/validate"
27866
+ };
27867
+ CALIPER_CONSTANTS = {
27868
+ context: "http://purl.imsglobal.org/ctx/caliper/v1p2",
27869
+ profile: "TimebackProfile",
27870
+ dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2"
27871
+ };
27872
+ TIMEBACK_EVENT_TYPES = {
27873
+ activityEvent: "ActivityEvent",
27874
+ timeSpentEvent: "TimeSpentEvent"
27875
+ };
27876
+ TIMEBACK_ACTIONS = {
27877
+ completed: "Completed",
27878
+ spentTime: "SpentTime"
27879
+ };
27880
+ TIMEBACK_TYPES = {
27881
+ user: "TimebackUser",
27882
+ activityContext: "TimebackActivityContext",
27883
+ activityMetricsCollection: "TimebackActivityMetricsCollection",
27884
+ timeSpentMetricsCollection: "TimebackTimeSpentMetricsCollection"
27885
+ };
27886
+ ACTIVITY_METRIC_TYPES = {
27887
+ totalQuestions: "totalQuestions",
27888
+ correctQuestions: "correctQuestions",
27889
+ xpEarned: "xpEarned",
27890
+ masteredUnits: "masteredUnits"
27891
+ };
27892
+ TIME_METRIC_TYPES = {
27893
+ active: "active",
27894
+ inactive: "inactive",
27895
+ waste: "waste",
27896
+ unknown: "unknown",
27897
+ antiPattern: "anti-pattern"
27898
+ };
27899
+ TIMEBACK_SUBJECTS = [
27900
+ "Math",
27901
+ "FastMath",
27902
+ "Science",
27903
+ "Social Studies",
27904
+ "Language",
27905
+ "Reading",
27906
+ "Vocabulary",
27907
+ "Writing"
27908
+ ];
27909
+ TIMEBACK_GRADE_LEVELS = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
27910
+ TIMEBACK_GRADE_LEVEL_LABELS = {
27911
+ "-1": "pre-k",
27912
+ "0": "kindergarten",
27913
+ "1": "1st grade",
27914
+ "2": "2nd grade",
27915
+ "3": "3rd grade",
27916
+ "4": "4th grade",
27917
+ "5": "5th grade",
27918
+ "6": "6th grade",
27919
+ "7": "7th grade",
27920
+ "8": "8th grade",
27921
+ "9": "9th grade",
27922
+ "10": "10th grade",
27923
+ "11": "11th grade",
27924
+ "12": "12th grade",
27925
+ "13": "AP"
27926
+ };
27927
+ CALIPER_SUBJECTS = {
27928
+ Reading: "Reading",
27929
+ Language: "Language",
27930
+ Vocabulary: "Vocabulary",
27931
+ SocialStudies: "Social Studies",
27932
+ Writing: "Writing",
27933
+ Science: "Science",
27934
+ FastMath: "FastMath",
27935
+ Math: "Math",
27936
+ None: "None"
27937
+ };
27938
+ ONEROSTER_STATUS = {
27939
+ active: "active",
27940
+ toBeDeleted: "tobedeleted"
27941
+ };
27942
+ SCORE_STATUS = {
27943
+ exempt: "exempt",
27944
+ fullyGraded: "fully graded",
27945
+ notSubmitted: "not submitted",
27946
+ partiallyGraded: "partially graded",
27947
+ submitted: "submitted"
27948
+ };
27949
+ ENV_VARS = {
27950
+ clientId: "TIMEBACK_CLIENT_ID",
27951
+ clientSecret: "TIMEBACK_CLIENT_SECRET",
27952
+ baseUrl: "TIMEBACK_BASE_URL",
27953
+ environment: "TIMEBACK_ENVIRONMENT",
27954
+ vendorResourceId: "TIMEBACK_VENDOR_RESOURCE_ID",
27955
+ launchBaseUrl: "GAME_URL",
27956
+ qtiClientId: "QTI_CLIENT_ID",
27957
+ qtiClientSecret: "QTI_CLIENT_SECRET",
27958
+ qtiAuthUrl: "QTI_AUTH_URL"
27959
+ };
27960
+ HTTP_DEFAULTS = {
27961
+ timeout: 30000,
27962
+ retries: 3,
27963
+ retryBackoffBase: 2
27964
+ };
27965
+ AUTH_DEFAULTS = {
27966
+ tokenCacheDuration: 50000
27967
+ };
27968
+ CACHE_DEFAULTS = {
27969
+ defaultTTL: 10 * 60 * 1000,
27970
+ defaultMaxSize: 500,
27971
+ defaultName: "TimebackCache",
27972
+ studentTTL: 10 * 60 * 1000,
27973
+ studentMaxSize: 500,
27974
+ assessmentTTL: 30 * 60 * 1000,
27975
+ assessmentMaxSize: 200,
27976
+ enrollmentTTL: 5 * 1000,
27977
+ enrollmentMaxSize: 100
27978
+ };
27979
+ CONFIG_DEFAULTS = {
27980
+ fileNames: ["timeback.config.js", "timeback.config.json"]
27981
+ };
27982
+ PLAYCADEMY_DEFAULTS = {
27983
+ organization: TIMEBACK_ORG_SOURCED_ID,
27984
+ launchBaseUrls: PLAYCADEMY_BASE_URLS
27985
+ };
27986
+ RESOURCE_DEFAULTS = {
27987
+ organization: {
27988
+ name: TIMEBACK_ORG_NAME,
27989
+ type: TIMEBACK_ORG_TYPE
27990
+ },
27991
+ course: {
27992
+ gradingScheme: TIMEBACK_COURSE_DEFAULTS.gradingScheme,
27993
+ level: TIMEBACK_COURSE_DEFAULTS.level,
27994
+ metadata: {
27995
+ goals: TIMEBACK_COURSE_DEFAULTS.goals,
27996
+ metrics: TIMEBACK_COURSE_DEFAULTS.metrics
27997
+ }
27998
+ },
27999
+ component: TIMEBACK_COMPONENT_DEFAULTS,
28000
+ resource: TIMEBACK_RESOURCE_DEFAULTS,
28001
+ componentResource: TIMEBACK_COMPONENT_RESOURCE_DEFAULTS
28002
+ };
28003
+ HTTP_STATUS = {
28004
+ CLIENT_ERROR_MIN: 400,
28005
+ CLIENT_ERROR_MAX: 500,
28006
+ SERVER_ERROR_MIN: 500
28007
+ };
28008
+ ERROR_NAMES = {
28009
+ timebackAuth: "TimebackAuthError",
28010
+ timebackApi: "TimebackApiError",
28011
+ timebackConfig: "TimebackConfigError",
28012
+ timebackSdk: "TimebackSDKError"
28013
+ };
28014
+ });
28015
+ init_constants3();
28016
+ SUBJECT_VALUES = TIMEBACK_SUBJECTS;
28017
+ GRADE_VALUES = TIMEBACK_GRADE_LEVELS;
28018
+ });
28019
+
28020
+ // ../utils/src/string.ts
28021
+ function kebabToTitleCase(kebabStr) {
28022
+ return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
28023
+ }
28024
+
28025
+ // ../api-core/src/utils/timeback.util.ts
28026
+ function isRecord2(value) {
28027
+ return typeof value === "object" && value !== null;
28028
+ }
28029
+ function filterEnrollmentsByGame(enrollments, gameId) {
28030
+ return enrollments.filter((enrollment) => enrollment.gameId === gameId).map(({ gameId: _, ...enrollment }) => enrollment);
28031
+ }
28032
+ function mapEnrollmentsToUserEnrollments(enrollments, integrations) {
28033
+ const enrollmentByCourse = new Map(enrollments.map((enrollment) => [enrollment.courseId, enrollment]));
28034
+ const courseToSchool = new Map(enrollments.filter((enrollment) => enrollment.school?.id).map((enrollment) => [enrollment.courseId, enrollment.school.id]));
28035
+ return integrations.map((integration) => {
28036
+ const enrollment = enrollmentByCourse.get(integration.courseId);
28037
+ return {
28038
+ gameId: integration.gameId,
28039
+ grade: integration.grade,
28040
+ subject: integration.subject,
28041
+ courseId: integration.courseId,
28042
+ orgId: courseToSchool.get(integration.courseId),
28043
+ ...enrollment ? { id: enrollment.sourcedId } : {}
28044
+ };
28045
+ });
28046
+ }
28047
+ function buildGameTimebackSummaries(integrations) {
28048
+ const summaries = {};
28049
+ for (const integration of integrations) {
28050
+ const summary = summaries[integration.gameId] ?? {
28051
+ subject: null,
28052
+ hasActiveIntegration: false,
28053
+ hasRemovedIntegration: false
28054
+ };
28055
+ const isRemoved = integration.status === DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS;
28056
+ if (isRemoved) {
28057
+ summary.hasRemovedIntegration = true;
28058
+ } else {
28059
+ summary.hasActiveIntegration = true;
28060
+ summary.subject ??= integration.subject;
28061
+ }
28062
+ summaries[integration.gameId] = summary;
28063
+ }
28064
+ return summaries;
28065
+ }
28066
+ function getStringValue(value) {
28067
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
28068
+ }
28069
+ function parseSourcedIdFromUrl(url) {
28070
+ if (!url) {
28071
+ return;
28072
+ }
28073
+ const trimmed = url.trim().replace(/\/$/, "");
28074
+ if (!trimmed) {
28075
+ return;
28076
+ }
28077
+ const segments = trimmed.split("/");
28078
+ const lastSegment = segments.at(-1);
28079
+ return lastSegment ? decodeURIComponent(lastSegment) : undefined;
28080
+ }
28081
+ function getGeneratedMetricValue(event, type) {
28082
+ const items = event.generated?.items;
28083
+ if (!Array.isArray(items)) {
28084
+ return;
28085
+ }
28086
+ const metric = items.find((item) => item?.type === type);
28087
+ if (!metric) {
28088
+ return;
28089
+ }
28090
+ const value = typeof metric.value === "number" ? metric.value : Number(metric.value);
28091
+ return Number.isFinite(value) ? value : undefined;
28092
+ }
28093
+ function getMergedCaliperExtensions(event) {
28094
+ const objectActivityExtensions = isRecord2(event.object.activity?.extensions) ? event.object.activity.extensions : undefined;
28095
+ const generatedExtensions = isRecord2(event.generated?.extensions) ? event.generated.extensions : undefined;
28096
+ const eventExtensions = isRecord2(event.extensions) ? event.extensions : undefined;
28097
+ return {
28098
+ ...objectActivityExtensions,
28099
+ ...generatedExtensions,
28100
+ ...eventExtensions
28101
+ };
28102
+ }
28103
+ function getPlaycademyMetadata(event) {
28104
+ const extensions = getMergedCaliperExtensions(event);
28105
+ return isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
28106
+ }
28107
+ function getActivityId(event, playcademy) {
28108
+ const metadataActivityId = getStringValue(playcademy?.activityId);
28109
+ if (metadataActivityId) {
28110
+ return metadataActivityId;
28111
+ }
28112
+ const activityId = getStringValue(event.object.activity?.id);
28113
+ if (activityId) {
28114
+ return activityId;
28115
+ }
28116
+ const objectId = getStringValue(event.object.id);
28117
+ if (!objectId) {
28118
+ return;
28119
+ }
28120
+ const trimmed = objectId.replace(/\/$/, "");
28121
+ const segments = trimmed.split("/");
28122
+ const activityIndex = segments.lastIndexOf("activities");
28123
+ if (activityIndex !== -1 && segments.length >= activityIndex + 3) {
28124
+ const candidate = segments[activityIndex + 2];
28125
+ return candidate ? decodeURIComponent(candidate) : undefined;
28126
+ }
28127
+ return;
28128
+ }
28129
+ function buildResourceMetadata({
28130
+ baseMetadata,
28131
+ subject,
28132
+ grade,
28133
+ totalXp,
28134
+ masterableUnits
28135
+ }) {
28136
+ const normalizedBaseMetadata = isResourceMetadata(baseMetadata) ? baseMetadata : undefined;
28137
+ const metadata2 = {
28138
+ ...normalizedBaseMetadata
28139
+ };
28140
+ metadata2.subject = subject;
28141
+ metadata2.grades = [grade];
28142
+ metadata2.xp = totalXp;
28143
+ if (masterableUnits !== undefined && masterableUnits !== null) {
28144
+ const existingPlaycademy = isPlaycademyResourceMetadata(metadata2.playcademy) ? metadata2.playcademy : undefined;
28145
+ metadata2.playcademy = {
28146
+ ...existingPlaycademy,
28147
+ mastery: {
28148
+ ...existingPlaycademy?.mastery,
28149
+ masterableUnits
28150
+ }
28151
+ };
28152
+ }
28153
+ return metadata2;
28154
+ }
28155
+ function getDurationSecondsFromExtensions(event) {
28156
+ const extensions = getMergedCaliperExtensions(event);
28157
+ const playcademy = isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
28158
+ const rawValue = extensions.durationSeconds ?? playcademy?.durationSeconds;
28159
+ const value = typeof rawValue === "number" ? rawValue : Number(rawValue);
28160
+ return Number.isFinite(value) ? value : undefined;
28161
+ }
28162
+ function getCanonicalRunId(session2) {
28163
+ const sessionId = getStringValue(session2?.id);
28164
+ if (!sessionId) {
28165
+ return;
28166
+ }
28167
+ return sessionId.replace(/^urn:uuid:/, "");
28168
+ }
28169
+ function getResumeId(event) {
28170
+ const playcademy = getPlaycademyMetadata(event);
28171
+ return getStringValue(playcademy?.resumeId);
28172
+ }
28173
+ function isCaliperRemediationOrCompletionEvent(event) {
28174
+ const playcademy = getPlaycademyMetadata(event);
28175
+ return REMEDIATION_OR_COMPLETION_EVENT_KINDS.has(getStringValue(playcademy?.eventKind) || "");
28176
+ }
28177
+ function groupCaliperEventsByRun(events) {
28178
+ const groups = new Map;
28179
+ for (const event of events) {
28180
+ const objectId = getStringValue(event.object.id) || "unknown-activity";
28181
+ const groupKey = `${objectId}::${getStringValue(event.session?.id) || event.externalId}`;
28182
+ const existing = groups.get(groupKey);
28183
+ if (existing) {
28184
+ existing.push(event);
28185
+ } else {
28186
+ groups.set(groupKey, [event]);
28187
+ }
28188
+ }
28189
+ return groups;
28190
+ }
28191
+ function findCaliperEventGroupContainingExternalId(events, externalId) {
28192
+ const targetExternalId = externalId.trim();
28193
+ if (!targetExternalId) {
28194
+ return;
28195
+ }
28196
+ return [...groupCaliperEventsByRun(events).values()].find((group) => group.some((event) => event.externalId === targetExternalId));
28197
+ }
28198
+ function mapCaliperEventGroupToActivity(events, relevantCourseIds) {
28199
+ if (events.length === 0) {
28200
+ return null;
28201
+ }
28202
+ const sortedEvents = events.toSorted((a, b) => a.eventTime.localeCompare(b.eventTime));
28203
+ const activityEvent = [...sortedEvents].toReversed().find((event) => event.type === "ActivityEvent");
28204
+ const contextSource = activityEvent || sortedEvents.at(-1);
28205
+ if (!contextSource) {
28206
+ return null;
28207
+ }
28208
+ const ctx = parseCaliperEventContext(contextSource, relevantCourseIds);
28209
+ if (!ctx) {
28210
+ return null;
28211
+ }
28212
+ const score = activityEvent !== undefined ? (() => {
28213
+ const totalQuestions = getGeneratedMetricValue(activityEvent, "totalQuestions");
28214
+ const correctQuestions = getGeneratedMetricValue(activityEvent, "correctQuestions");
28215
+ if (totalQuestions === undefined || correctQuestions === undefined || totalQuestions <= 0) {
28216
+ return;
28217
+ }
28218
+ return correctQuestions / totalQuestions * 100;
28219
+ })() : undefined;
28220
+ const xpEarned = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "xpEarned") : undefined;
28221
+ const masteredUnits = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "masteredUnits") : undefined;
28222
+ const timeSpentEvents = sortedEvents.filter((event) => event.type === "TimeSpentEvent");
28223
+ let totalActiveTimeSeconds;
28224
+ if (timeSpentEvents.length > 0) {
28225
+ totalActiveTimeSeconds = timeSpentEvents.reduce((sum, event) => sum + (getGeneratedMetricValue(event, "active") ?? 0), 0);
28226
+ } else if (activityEvent !== undefined) {
28227
+ totalActiveTimeSeconds = getDurationSecondsFromExtensions(activityEvent);
28228
+ }
28229
+ const fallbackActivityId = getActivityId(contextSource, getPlaycademyMetadata(contextSource));
28230
+ const occurredAt = getStringValue(activityEvent?.eventTime) || getStringValue(sortedEvents.at(-1)?.eventTime);
28231
+ const runId = getCanonicalRunId(contextSource.session);
28232
+ const resumeIds = new Set(sortedEvents.map((event) => getResumeId(event)).filter((resumeId) => resumeId !== undefined));
28233
+ const sessionCount = resumeIds.size > 0 ? resumeIds.size : 1;
28234
+ const kind = activityEvent !== undefined ? "activity" : "activity-in-progress";
28235
+ if (!occurredAt) {
28236
+ return null;
28237
+ }
28238
+ return {
28239
+ id: activityEvent?.externalId || sortedEvents.at(-1)?.externalId || events[0].externalId,
28240
+ kind,
28241
+ occurredAt,
28242
+ courseId: ctx.courseId,
28243
+ title: getStringValue(activityEvent?.object.activity?.name) || ctx.titleFromEvent || (fallbackActivityId ? kebabToTitleCase(fallbackActivityId) : "Activity completed"),
28244
+ ...ctx.activityId ? { activityId: ctx.activityId } : {},
28245
+ ...ctx.appName ? { appName: ctx.appName } : {},
28246
+ ...score !== undefined ? { score } : {},
28247
+ ...xpEarned !== undefined ? { xpDelta: xpEarned } : {},
28248
+ ...masteredUnits !== undefined ? { masteredUnitsDelta: masteredUnits } : {},
28249
+ ...totalActiveTimeSeconds !== undefined ? { timeDeltaSeconds: totalActiveTimeSeconds } : {},
28250
+ ...runId ? { runId } : {},
28251
+ ...sessionCount > 0 ? { sessionCount } : {}
28252
+ };
28253
+ }
28254
+ function parseCaliperEventContext(event, relevantCourseIds) {
28255
+ const playcademy = getPlaycademyMetadata(event);
28256
+ const courseId = getStringValue(playcademy?.courseId) || parseSourcedIdFromUrl(event.object.course?.id);
28257
+ if (!courseId || !relevantCourseIds.has(courseId)) {
28258
+ return null;
28259
+ }
28260
+ const occurredAt = getStringValue(event.eventTime);
28261
+ if (!occurredAt) {
28262
+ return null;
28263
+ }
28264
+ return {
28265
+ courseId,
28266
+ occurredAt,
28267
+ eventKind: getStringValue(playcademy?.eventKind),
28268
+ source: getStringValue(playcademy?.source),
28269
+ reason: getStringValue(playcademy?.reason),
28270
+ titleFromEvent: getStringValue(event.object.activity?.name),
28271
+ appName: getStringValue(event.object.app?.name),
28272
+ activityId: getActivityId(event, playcademy)
28273
+ };
28274
+ }
28275
+ function mapTimeSpentRemediation(event, ctx) {
28276
+ if (ctx.eventKind !== "remediation-time") {
28277
+ return null;
28278
+ }
28279
+ return {
28280
+ id: event.externalId,
28281
+ kind: "remediation-time",
28282
+ occurredAt: ctx.occurredAt,
28283
+ courseId: ctx.courseId,
28284
+ title: "Time Adjustment",
28285
+ activityId: ctx.activityId,
28286
+ appName: ctx.appName,
28287
+ reason: ctx.reason,
28288
+ timeDeltaSeconds: getGeneratedMetricValue(event, "active")
28289
+ };
28290
+ }
28291
+ function mapActivityRemediation(event, ctx) {
28292
+ if (ctx.eventKind === "remediation-xp") {
28293
+ return {
28294
+ id: event.externalId,
28295
+ kind: "remediation-xp",
28296
+ occurredAt: ctx.occurredAt,
28297
+ courseId: ctx.courseId,
28298
+ title: "XP Adjustment",
28299
+ activityId: ctx.activityId,
28300
+ appName: ctx.appName,
28301
+ reason: ctx.reason,
28302
+ xpDelta: getGeneratedMetricValue(event, "xpEarned"),
28303
+ masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
28304
+ };
28305
+ }
28306
+ if (ctx.eventKind === "remediation-mastery") {
28307
+ return {
28308
+ id: event.externalId,
28309
+ kind: "remediation-mastery",
28310
+ occurredAt: ctx.occurredAt,
28311
+ courseId: ctx.courseId,
28312
+ title: "Mastery Adjustment",
28313
+ activityId: ctx.activityId,
28314
+ appName: ctx.appName,
28315
+ reason: ctx.reason,
28316
+ xpDelta: getGeneratedMetricValue(event, "xpEarned"),
28317
+ masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
28318
+ };
28319
+ }
28320
+ if (ctx.eventKind === "course-completed") {
28321
+ return {
28322
+ id: event.externalId,
28323
+ kind: "course-completed",
28324
+ occurredAt: ctx.occurredAt,
28325
+ courseId: ctx.courseId,
28326
+ title: ctx.source === "admin" ? "Course marked complete" : "Course completed",
28327
+ activityId: ctx.activityId,
28328
+ appName: ctx.appName,
28329
+ reason: ctx.reason
28330
+ };
28331
+ }
28332
+ if (ctx.eventKind === "course-resumed") {
28333
+ return {
28334
+ id: event.externalId,
28335
+ kind: "course-resumed",
28336
+ occurredAt: ctx.occurredAt,
28337
+ courseId: ctx.courseId,
28338
+ title: "Course resumed",
28339
+ activityId: ctx.activityId,
28340
+ appName: ctx.appName,
28341
+ reason: ctx.reason
28342
+ };
28343
+ }
28344
+ return null;
28345
+ }
28346
+ function mapCaliperEventToRemediationActivity(event, relevantCourseIds) {
28347
+ const ctx = parseCaliperEventContext(event, relevantCourseIds);
28348
+ if (!ctx) {
28349
+ return null;
28350
+ }
28351
+ if (event.type === "TimeSpentEvent") {
28352
+ return mapTimeSpentRemediation(event, ctx);
28353
+ }
28354
+ if (event.type === "ActivityEvent") {
28355
+ return mapActivityRemediation(event, ctx);
28356
+ }
28357
+ return null;
28358
+ }
28359
+ var REMEDIATION_OR_COMPLETION_EVENT_KINDS;
28360
+ var init_timeback_util = __esm(() => {
28361
+ init_helpers_index();
28362
+ init_types2();
28363
+ REMEDIATION_OR_COMPLETION_EVENT_KINDS = new Set([
28364
+ "remediation-xp",
28365
+ "remediation-time",
28366
+ "remediation-mastery",
28367
+ "course-completed",
28368
+ "course-resumed"
28369
+ ]);
28370
+ });
28371
+
27780
28372
  // ../api-core/src/services/game.service.ts
27781
28373
  var inFlightManifestFetches, GameService;
27782
28374
  var init_game_service = __esm(() => {
27783
28375
  init_drizzle_orm();
27784
28376
  init_src();
28377
+ init_helpers_index();
27785
28378
  init_tables_index();
27786
28379
  init_spans();
27787
28380
  init_errors();
27788
28381
  init_deployment_util();
28382
+ init_timeback_util();
27789
28383
  inFlightManifestFetches = new Map;
27790
28384
  GameService = class GameService {
27791
28385
  deps;
@@ -27929,6 +28523,7 @@ var init_game_service = __esm(() => {
27929
28523
  const db2 = this.deps.db;
27930
28524
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
27931
28525
  columns: { gameId: true, subject: true },
28526
+ where: isActiveGameTimebackIntegrationStatus(),
27932
28527
  orderBy: [asc(gameTimebackIntegrations.createdAt)]
27933
28528
  });
27934
28529
  const subjectMap = {};
@@ -27939,6 +28534,26 @@ var init_game_service = __esm(() => {
27939
28534
  }
27940
28535
  return subjectMap;
27941
28536
  }
28537
+ async getTimebackSummaries(user) {
28538
+ const db2 = this.deps.db;
28539
+ const canSeeAllGames = user.role === "admin" || user.role === "teacher";
28540
+ let accessibleGameIds = null;
28541
+ if (!canSeeAllGames) {
28542
+ const accessibleGames = await this.listAccessible(user);
28543
+ accessibleGameIds = new Set(accessibleGames.map((game2) => game2.id));
28544
+ }
28545
+ if (accessibleGameIds?.size === 0) {
28546
+ return {};
28547
+ }
28548
+ const integrations = await db2.query.gameTimebackIntegrations.findMany({
28549
+ columns: { gameId: true, subject: true, status: true },
28550
+ ...accessibleGameIds && {
28551
+ where: inArray(gameTimebackIntegrations.gameId, [...accessibleGameIds])
28552
+ },
28553
+ orderBy: [asc(gameTimebackIntegrations.createdAt)]
28554
+ });
28555
+ return buildGameTimebackSummaries(integrations);
28556
+ }
27942
28557
  async getById(gameId, caller) {
27943
28558
  const db2 = this.deps.db;
27944
28559
  const game2 = await db2.query.games.findFirst({
@@ -28576,7 +29191,7 @@ var init_client2 = () => {};
28576
29191
 
28577
29192
  // ../alerts/src/discord/types.ts
28578
29193
  var DiscordColors;
28579
- var init_types2 = __esm(() => {
29194
+ var init_types3 = __esm(() => {
28580
29195
  DiscordColors = {
28581
29196
  DEFAULT: 0,
28582
29197
  WHITE: 16777215,
@@ -28614,7 +29229,7 @@ var init_types2 = __esm(() => {
28614
29229
  // ../alerts/src/discord/index.ts
28615
29230
  var init_discord = __esm(() => {
28616
29231
  init_client2();
28617
- init_types2();
29232
+ init_types3();
28618
29233
  });
28619
29234
 
28620
29235
  // ../api-core/src/services/alerts.service.ts
@@ -29745,7 +30360,7 @@ var init_secrets_service = __esm(() => {
29745
30360
 
29746
30361
  // ../edge-play/src/constants.ts
29747
30362
  var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
29748
- var init_constants3 = __esm(() => {
30363
+ var init_constants4 = __esm(() => {
29749
30364
  init_src();
29750
30365
  ROUTES = {
29751
30366
  INDEX: "/api",
@@ -29772,7 +30387,7 @@ function prefixSecrets(secrets) {
29772
30387
  }
29773
30388
  var init_setup2 = __esm(() => {
29774
30389
  init_src();
29775
- init_constants3();
30390
+ init_constants4();
29776
30391
  });
29777
30392
 
29778
30393
  // ../api-core/src/services/seed.service.ts
@@ -30497,11 +31112,11 @@ var init_schemas3 = __esm(() => {
30497
31112
  });
30498
31113
 
30499
31114
  // ../data/src/domains/timeback/schemas.ts
30500
- function isTimebackGrade(value) {
31115
+ function isTimebackGrade2(value) {
30501
31116
  return Number.isInteger(value) && TIMEBACK_GRADES.includes(value);
30502
31117
  }
30503
- function isTimebackSubject(value) {
30504
- return TIMEBACK_SUBJECTS.includes(value);
31118
+ function isTimebackSubject2(value) {
31119
+ return TIMEBACK_SUBJECTS2.includes(value);
30505
31120
  }
30506
31121
  function isValidAdminAttributionDate(value) {
30507
31122
  const match = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
@@ -30515,13 +31130,13 @@ function isValidAdminAttributionDate(value) {
30515
31130
  const date3 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
30516
31131
  return date3.getUTCFullYear() === year && date3.getUTCMonth() + 1 === month && date3.getUTCDate() === day;
30517
31132
  }
30518
- var TIMEBACK_GRADES, TIMEBACK_SUBJECTS, TimebackGradeSchema, TimebackSubjectSchema, CourseGoalsSchema, UpdateGameTimebackIntegrationRequestSchema, TimebackActivityDataSchema, EndActivityRequestSchema, GameRunMetricsSchema, GameCourseMetricsSchema, GameMetricsResponseSchema, AdvanceCourseRequestSchema, UnenrollCourseRequestSchema, HeartbeatRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, AdminAttributionDateSchema, ADMIN_GRANT_XP_MIN = -1e5, ADMIN_GRANT_XP_MAX = 1e5, ADMIN_GRANT_XP_AMOUNT_RANGE_MESSAGE, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ReconcileMasteryForConfigChangeSchema, EnrollStudentRequestSchema, UnenrollStudentRequestSchema, ReactivateEnrollmentRequestSchema, VerifyTimebackMetricDiscrepancyRequestSchema, InsertAssessmentTestSchema, CreateAssessmentRequestSchema, ReorderAssessmentsRequestSchema, ReorderQuestionsRequestSchema;
31133
+ var TIMEBACK_GRADES, TIMEBACK_SUBJECTS2, TimebackGradeSchema, TimebackSubjectSchema, CourseGoalsSchema, UpdateGameTimebackIntegrationRequestSchema, CreateGameTimebackIntegrationRequestSchema, TimebackActivityDataSchema, EndActivityRequestSchema, GameRunMetricsSchema, GameCourseMetricsSchema, GameMetricsResponseSchema, AdvanceCourseRequestSchema, UnenrollCourseRequestSchema, HeartbeatRequestSchema, PopulateStudentRequestSchema, DerivedPlatformCourseConfigSchema, TimebackBaseConfigSchema, PlatformTimebackSetupRequestSchema, AdminTimebackMutationBaseSchema, AdminAttributionDateSchema, ADMIN_GRANT_XP_MIN = -1e5, ADMIN_GRANT_XP_MAX = 1e5, ADMIN_GRANT_XP_AMOUNT_RANGE_MESSAGE, GrantTimebackXpRequestSchema, AdjustTimebackTimeRequestSchema, AdjustTimebackMasteryRequestSchema, ReconcileMasteryForConfigChangeSchema, EnrollStudentRequestSchema, UnenrollStudentRequestSchema, ReactivateEnrollmentRequestSchema, VerifyTimebackMetricDiscrepancyRequestSchema, InsertAssessmentTestSchema, CreateAssessmentRequestSchema, ReorderAssessmentsRequestSchema, ReorderQuestionsRequestSchema;
30519
31134
  var init_schemas4 = __esm(() => {
30520
31135
  init_drizzle_zod();
30521
31136
  init_esm();
30522
31137
  init_table7();
30523
31138
  TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
30524
- TIMEBACK_SUBJECTS = [
31139
+ TIMEBACK_SUBJECTS2 = [
30525
31140
  "Reading",
30526
31141
  "Language",
30527
31142
  "Vocabulary",
@@ -30535,7 +31150,7 @@ var init_schemas4 = __esm(() => {
30535
31150
  TimebackGradeSchema = exports_external.number().int().refine((val) => TIMEBACK_GRADES.includes(val), {
30536
31151
  message: `Grade must be one of: ${TIMEBACK_GRADES.join(", ")}`
30537
31152
  });
30538
- TimebackSubjectSchema = exports_external.enum(TIMEBACK_SUBJECTS);
31153
+ TimebackSubjectSchema = exports_external.enum(TIMEBACK_SUBJECTS2);
30539
31154
  CourseGoalsSchema = exports_external.object({
30540
31155
  dailyXp: exports_external.number().int().nonnegative().nullable().optional(),
30541
31156
  dailyLessons: exports_external.number().int().nonnegative().nullable().optional(),
@@ -30554,6 +31169,15 @@ var init_schemas4 = __esm(() => {
30554
31169
  isSupplemental: exports_external.boolean().optional(),
30555
31170
  timebackVisible: exports_external.boolean().nullable().optional()
30556
31171
  });
31172
+ CreateGameTimebackIntegrationRequestSchema = exports_external.object({
31173
+ title: exports_external.string().trim().min(1),
31174
+ courseCode: exports_external.string().trim().min(1),
31175
+ subject: TimebackSubjectSchema,
31176
+ grade: TimebackGradeSchema,
31177
+ totalXp: exports_external.number().int().positive(),
31178
+ masterableUnits: exports_external.number().int().nonnegative(),
31179
+ level: exports_external.string().trim().min(1).optional()
31180
+ });
30557
31181
  TimebackActivityDataSchema = exports_external.object({
30558
31182
  activityId: exports_external.string().min(1),
30559
31183
  activityName: exports_external.string().optional(),
@@ -30999,10 +31623,6 @@ var init_log = __esm(() => {
30999
31623
  init_ansi();
31000
31624
  init_spinner();
31001
31625
  });
31002
- // ../utils/src/string.ts
31003
- function kebabToTitleCase(kebabStr) {
31004
- return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
31005
- }
31006
31626
  // ../utils/src/timezone.ts
31007
31627
  function formatDateYMDInTimezone(timeZone, date3 = new Date) {
31008
31628
  const parts2 = new Intl.DateTimeFormat("en-US", {
@@ -31112,16 +31732,45 @@ var init_src4 = __esm(() => {
31112
31732
  });
31113
31733
 
31114
31734
  // ../timeback/dist/index.js
31735
+ import { createHash } from "node:crypto";
31115
31736
  import { AsyncLocalStorage } from "node:async_hooks";
31116
31737
  function createOneRosterUrls(baseUrl) {
31117
- const effective = baseUrl || TIMEBACK_API_URLS.production;
31738
+ const effective = baseUrl || TIMEBACK_API_URLS2.production;
31118
31739
  const base = effective.replace(/\/$/, "");
31119
31740
  return {
31120
- user: (userId) => `${base}${ONEROSTER_ENDPOINTS.users}/${userId}`,
31121
- course: (courseId) => `${base}${ONEROSTER_ENDPOINTS.courses}/${courseId}`,
31122
- componentResource: (resourceId) => `${base}${ONEROSTER_ENDPOINTS.componentResources}/${resourceId}`
31741
+ user: (userId) => `${base}${ONEROSTER_ENDPOINTS2.users}/${userId}`,
31742
+ course: (courseId) => `${base}${ONEROSTER_ENDPOINTS2.courses}/${courseId}`,
31743
+ componentResource: (resourceId) => `${base}${ONEROSTER_ENDPOINTS2.componentResources}/${resourceId}`
31123
31744
  };
31124
31745
  }
31746
+ function resolveCourseIdFromCourseUrl(url2) {
31747
+ try {
31748
+ const parts2 = new URL(url2).pathname.split("/").filter(Boolean);
31749
+ const maybeCourses = parts2.at(-2);
31750
+ const maybeId = parts2.at(-1);
31751
+ if (maybeCourses !== "courses" || !maybeId) {
31752
+ return null;
31753
+ }
31754
+ if (UUID_REGEX2.test(maybeId)) {
31755
+ return maybeId;
31756
+ }
31757
+ if (maybeId.length > 2 && !maybeId.includes("/")) {
31758
+ return maybeId;
31759
+ }
31760
+ return null;
31761
+ } catch {
31762
+ return null;
31763
+ }
31764
+ }
31765
+ function computeCaliperLineItemId(objectId, courseSourcedId, courseUrl) {
31766
+ const recovered = resolveCourseIdFromCourseUrl(courseUrl);
31767
+ if (recovered !== courseSourcedId) {
31768
+ throw new ConfigurationError("courseId", `Course id "${courseSourcedId}" is not URL-safe: Timeback Platform would parse it back as ${recovered === null ? "null" : `"${recovered}"`} from the Caliper event, producing a different gradebook line item. Use a UUID or an id with no spaces, slashes, or non-ASCII characters.`);
31769
+ }
31770
+ const idParts = [objectId, courseSourcedId].join("_");
31771
+ const hashedId = createHash("sha256").update(idParts).digest("hex");
31772
+ return `caliper_${hashedId}`;
31773
+ }
31125
31774
  function deriveSourcedIds(courseId) {
31126
31775
  return {
31127
31776
  course: courseId,
@@ -31133,7 +31782,7 @@ function deriveSourcedIds(courseId) {
31133
31782
  async function fetchTimebackConfig(client, courseId) {
31134
31783
  const sourcedIds = deriveSourcedIds(courseId);
31135
31784
  const [org, course, component, resource, componentResource] = await Promise.all([
31136
- client.oneroster.organizations.get(PLAYCADEMY_DEFAULTS.organization),
31785
+ client.oneroster.organizations.get(PLAYCADEMY_DEFAULTS2.organization),
31137
31786
  client.oneroster.courses.get(sourcedIds.course),
31138
31787
  client.oneroster.courseComponents.get(sourcedIds.component),
31139
31788
  client.oneroster.resources.get(sourcedIds.resource),
@@ -31143,7 +31792,7 @@ async function fetchTimebackConfig(client, courseId) {
31143
31792
  organization: {
31144
31793
  name: org.name,
31145
31794
  type: org.type,
31146
- identifier: org.identifier || PLAYCADEMY_DEFAULTS.organization
31795
+ identifier: org.identifier || PLAYCADEMY_DEFAULTS2.organization
31147
31796
  },
31148
31797
  course: {
31149
31798
  title: course.title || "",
@@ -31203,23 +31852,23 @@ async function verifyTimebackResources(client, courseId) {
31203
31852
  }
31204
31853
  };
31205
31854
  }
31206
- function isObject(value) {
31855
+ function isObject2(value) {
31207
31856
  return typeof value === "object" && value !== null;
31208
31857
  }
31209
- function isPlaycademyResourceMetadata(value) {
31210
- if (!isObject(value)) {
31858
+ function isPlaycademyResourceMetadata2(value) {
31859
+ if (!isObject2(value)) {
31211
31860
  return false;
31212
31861
  }
31213
31862
  if (!("mastery" in value) || value.mastery === undefined) {
31214
31863
  return true;
31215
31864
  }
31216
- return isObject(value.mastery);
31865
+ return isObject2(value.mastery);
31217
31866
  }
31218
- function isTimebackSubject2(value) {
31219
- return typeof value === "string" && SUBJECT_VALUES.includes(value);
31867
+ function isTimebackSubject3(value) {
31868
+ return typeof value === "string" && SUBJECT_VALUES2.includes(value);
31220
31869
  }
31221
- function isTimebackGrade2(value) {
31222
- return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES.includes(value);
31870
+ function isTimebackGrade3(value) {
31871
+ return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES2.includes(value);
31223
31872
  }
31224
31873
  async function deleteTimebackResources(client, courseId) {
31225
31874
  const sourcedIds = deriveSourcedIds(courseId);
@@ -31247,17 +31896,7 @@ async function deleteTimebackResources(client, courseId) {
31247
31896
  prerequisites: config2.component.prerequisites,
31248
31897
  prerequisiteCriteria: config2.component.prerequisiteCriteria
31249
31898
  }),
31250
- client.oneroster.resources.update(sourcedIds.resource, {
31251
- sourcedId: sourcedIds.resource,
31252
- status: "tobedeleted",
31253
- title: config2.resource.title,
31254
- vendorResourceId: config2.resource.vendorResourceId,
31255
- vendorId: config2.resource.vendorId,
31256
- applicationId: config2.resource.applicationId,
31257
- roles: config2.resource.roles,
31258
- importance: config2.resource.importance,
31259
- metadata: config2.resource.metadata
31260
- }),
31899
+ client.oneroster.resources.delete(sourcedIds.resource),
31261
31900
  client.oneroster.componentResources.update(sourcedIds.componentResource, {
31262
31901
  sourcedId: sourcedIds.componentResource,
31263
31902
  status: "tobedeleted",
@@ -31270,6 +31909,15 @@ async function deleteTimebackResources(client, courseId) {
31270
31909
  ]);
31271
31910
  setAttribute("app.timeback.resources_deleted", true);
31272
31911
  }
31912
+ async function updateTimebackCourseStatus(client, courseId, status) {
31913
+ const course = await client.oneroster.courses.get(courseId);
31914
+ await client.oneroster.courses.update(courseId, {
31915
+ ...course,
31916
+ sourcedId: courseId,
31917
+ status
31918
+ });
31919
+ setAttribute("app.timeback.course_status", status);
31920
+ }
31273
31921
  async function createCourse(client, config2) {
31274
31922
  const courseData = {
31275
31923
  status: "active",
@@ -31518,14 +32166,14 @@ async function getTimebackTokenResponse(config2) {
31518
32166
  }
31519
32167
  }
31520
32168
  function getAuthUrl(environment = "production") {
31521
- return TIMEBACK_AUTH_URLS[environment];
32169
+ return TIMEBACK_AUTH_URLS2[environment];
31522
32170
  }
31523
32171
  function parseEduBridgeGrade(value) {
31524
32172
  if (value === null || value === undefined || value.trim() === "") {
31525
32173
  return null;
31526
32174
  }
31527
32175
  const parsed = Number(value);
31528
- return isTimebackGrade2(parsed) ? parsed : null;
32176
+ return isTimebackGrade3(parsed) ? parsed : null;
31529
32177
  }
31530
32178
  function normalizeHighestGradeMastered(response, subject) {
31531
32179
  const grades = {
@@ -31602,12 +32250,12 @@ async function withTimebackClientTelemetry(fn) {
31602
32250
  }
31603
32251
  function handleHttpError(res, errorBody, attempt, retries, context2) {
31604
32252
  const error = new TimebackApiError(res.status, res.statusText, errorBody);
31605
- if (res.status >= HTTP_STATUS.CLIENT_ERROR_MIN && res.status < HTTP_STATUS.CLIENT_ERROR_MAX) {
32253
+ if (res.status >= HTTP_STATUS2.CLIENT_ERROR_MIN && res.status < HTTP_STATUS2.CLIENT_ERROR_MAX) {
31606
32254
  recordTimebackHttpFailure();
31607
32255
  throw error;
31608
32256
  }
31609
32257
  if (attempt < retries) {
31610
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32258
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31611
32259
  recordTimebackRetry();
31612
32260
  addEvent("timeback.request_retry", {
31613
32261
  "app.timeback.attempt": attempt + 1,
@@ -31684,7 +32332,7 @@ async function request({
31684
32332
  const result = handleHttpError(res, errorBody, attempt, retries, { method, path });
31685
32333
  lastError = result.error;
31686
32334
  if (result.retry) {
31687
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32335
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31688
32336
  await new Promise((resolve) => setTimeout(resolve, delay));
31689
32337
  }
31690
32338
  } else {
@@ -31696,7 +32344,7 @@ async function request({
31696
32344
  }
31697
32345
  lastError = error instanceof Error ? error : new Error(String(error));
31698
32346
  if (attempt < retries) {
31699
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32347
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31700
32348
  recordTimebackRetry();
31701
32349
  addEvent("timeback.network_retry", {
31702
32350
  "app.timeback.attempt": attempt + 1,
@@ -31745,10 +32393,10 @@ function createCaliperNamespace(client) {
31745
32393
  const envelope = {
31746
32394
  sensor: sensorUrl,
31747
32395
  sendTime: new Date().toISOString(),
31748
- dataVersion: CALIPER_CONSTANTS.dataVersion,
32396
+ dataVersion: CALIPER_CONSTANTS2.dataVersion,
31749
32397
  data: [event]
31750
32398
  };
31751
- return client["requestCaliper"](CALIPER_ENDPOINTS.event, "POST", envelope);
32399
+ return client["requestCaliper"](CALIPER_ENDPOINTS2.event, "POST", envelope);
31752
32400
  },
31753
32401
  emitBatch: async (events, sensorUrl) => {
31754
32402
  if (events.length === 0) {
@@ -31757,10 +32405,10 @@ function createCaliperNamespace(client) {
31757
32405
  const envelope = {
31758
32406
  sensor: sensorUrl,
31759
32407
  sendTime: new Date().toISOString(),
31760
- dataVersion: CALIPER_CONSTANTS.dataVersion,
32408
+ dataVersion: CALIPER_CONSTANTS2.dataVersion,
31761
32409
  data: events
31762
32410
  };
31763
- return client["requestCaliper"](CALIPER_ENDPOINTS.event, "POST", envelope);
32411
+ return client["requestCaliper"](CALIPER_ENDPOINTS2.event, "POST", envelope);
31764
32412
  },
31765
32413
  events: {
31766
32414
  list: async (params = {}) => {
@@ -31790,7 +32438,7 @@ function createCaliperNamespace(client) {
31790
32438
  query.set(`extensions.${key}`, value);
31791
32439
  }
31792
32440
  }
31793
- const requestPath = `${CALIPER_ENDPOINTS.events}?${query.toString()}`;
32441
+ const requestPath = `${CALIPER_ENDPOINTS2.events}?${query.toString()}`;
31794
32442
  return client["requestCaliper"](requestPath, "GET");
31795
32443
  }
31796
32444
  },
@@ -31800,21 +32448,21 @@ function createCaliperNamespace(client) {
31800
32448
  gameId: data.gameId
31801
32449
  });
31802
32450
  const event = {
31803
- "@context": CALIPER_CONSTANTS.context,
32451
+ "@context": CALIPER_CONSTANTS2.context,
31804
32452
  id: `urn:uuid:${crypto.randomUUID()}`,
31805
- type: TIMEBACK_EVENT_TYPES.activityEvent,
32453
+ type: TIMEBACK_EVENT_TYPES2.activityEvent,
31806
32454
  eventTime: data.eventTime || new Date().toISOString(),
31807
- profile: CALIPER_CONSTANTS.profile,
32455
+ profile: CALIPER_CONSTANTS2.profile,
31808
32456
  actor: {
31809
32457
  id: urls.user(data.studentId),
31810
- type: TIMEBACK_TYPES.user,
32458
+ type: TIMEBACK_TYPES2.user,
31811
32459
  email: data.studentEmail
31812
32460
  },
31813
- action: TIMEBACK_ACTIONS.completed,
32461
+ action: TIMEBACK_ACTIONS2.completed,
31814
32462
  ...data.runId ? { session: `urn:uuid:${data.runId}` } : {},
31815
32463
  object: {
31816
32464
  id: data.objectId || caliper.buildActivityUrl(data),
31817
- type: TIMEBACK_TYPES.activityContext,
32465
+ type: TIMEBACK_TYPES2.activityContext,
31818
32466
  subject: data.subject,
31819
32467
  app: {
31820
32468
  name: data.appName
@@ -31828,25 +32476,25 @@ function createCaliperNamespace(client) {
31828
32476
  },
31829
32477
  generated: {
31830
32478
  id: data.generatedId || `urn:timeback:metrics:activity-completion-${crypto.randomUUID()}`,
31831
- type: TIMEBACK_TYPES.activityMetricsCollection,
32479
+ type: TIMEBACK_TYPES2.activityMetricsCollection,
31832
32480
  ...data.includeAttempt === false ? {} : { attempt: data.attemptNumber || 1 },
31833
32481
  items: [
31834
32482
  ...data.totalQuestions !== undefined ? [
31835
32483
  {
31836
- type: ACTIVITY_METRIC_TYPES.totalQuestions,
32484
+ type: ACTIVITY_METRIC_TYPES2.totalQuestions,
31837
32485
  value: data.totalQuestions
31838
32486
  }
31839
32487
  ] : [],
31840
32488
  ...data.correctQuestions !== undefined ? [
31841
32489
  {
31842
- type: ACTIVITY_METRIC_TYPES.correctQuestions,
32490
+ type: ACTIVITY_METRIC_TYPES2.correctQuestions,
31843
32491
  value: data.correctQuestions
31844
32492
  }
31845
32493
  ] : [],
31846
- ...data.xpEarned !== undefined ? [{ type: ACTIVITY_METRIC_TYPES.xpEarned, value: data.xpEarned }] : [],
32494
+ ...data.xpEarned !== undefined ? [{ type: ACTIVITY_METRIC_TYPES2.xpEarned, value: data.xpEarned }] : [],
31847
32495
  ...data.masteredUnits !== undefined ? [
31848
32496
  {
31849
- type: ACTIVITY_METRIC_TYPES.masteredUnits,
32497
+ type: ACTIVITY_METRIC_TYPES2.masteredUnits,
31850
32498
  value: data.masteredUnits
31851
32499
  }
31852
32500
  ] : []
@@ -31868,21 +32516,21 @@ function createCaliperNamespace(client) {
31868
32516
  gameId: data.gameId
31869
32517
  });
31870
32518
  const event = {
31871
- "@context": CALIPER_CONSTANTS.context,
32519
+ "@context": CALIPER_CONSTANTS2.context,
31872
32520
  id: `urn:uuid:${crypto.randomUUID()}`,
31873
- type: TIMEBACK_EVENT_TYPES.timeSpentEvent,
32521
+ type: TIMEBACK_EVENT_TYPES2.timeSpentEvent,
31874
32522
  eventTime: data.eventTime || new Date().toISOString(),
31875
- profile: CALIPER_CONSTANTS.profile,
32523
+ profile: CALIPER_CONSTANTS2.profile,
31876
32524
  actor: {
31877
32525
  id: urls.user(data.studentId),
31878
- type: TIMEBACK_TYPES.user,
32526
+ type: TIMEBACK_TYPES2.user,
31879
32527
  email: data.studentEmail
31880
32528
  },
31881
- action: TIMEBACK_ACTIONS.spentTime,
32529
+ action: TIMEBACK_ACTIONS2.spentTime,
31882
32530
  ...data.runId ? { session: `urn:uuid:${data.runId}` } : {},
31883
32531
  object: {
31884
32532
  id: caliper.buildActivityUrl(data),
31885
- type: TIMEBACK_TYPES.activityContext,
32533
+ type: TIMEBACK_TYPES2.activityContext,
31886
32534
  subject: data.subject,
31887
32535
  app: {
31888
32536
  name: data.appName
@@ -31895,16 +32543,16 @@ function createCaliperNamespace(client) {
31895
32543
  },
31896
32544
  generated: {
31897
32545
  id: `urn:timeback:metrics:time-spent-${crypto.randomUUID()}`,
31898
- type: TIMEBACK_TYPES.timeSpentMetricsCollection,
32546
+ type: TIMEBACK_TYPES2.timeSpentMetricsCollection,
31899
32547
  items: [
31900
- { type: TIME_METRIC_TYPES.active, value: data.activeTimeSeconds },
32548
+ { type: TIME_METRIC_TYPES2.active, value: data.activeTimeSeconds },
31901
32549
  ...data.inactiveTimeSeconds !== undefined ? [
31902
32550
  {
31903
- type: TIME_METRIC_TYPES.inactive,
32551
+ type: TIME_METRIC_TYPES2.inactive,
31904
32552
  value: data.inactiveTimeSeconds
31905
32553
  }
31906
32554
  ] : [],
31907
- ...data.wasteTimeSeconds !== undefined ? [{ type: TIME_METRIC_TYPES.waste, value: data.wasteTimeSeconds }] : []
32555
+ ...data.wasteTimeSeconds !== undefined ? [{ type: TIME_METRIC_TYPES2.waste, value: data.wasteTimeSeconds }] : []
31908
32556
  ],
31909
32557
  ...data.extensions ? { extensions: data.extensions } : {}
31910
32558
  },
@@ -31915,7 +32563,8 @@ function createCaliperNamespace(client) {
31915
32563
  buildActivityUrl: (data) => {
31916
32564
  const base = data.sensorUrl.replace(/\/$/, "");
31917
32565
  return `${base}/activities/${encodeURIComponent(data.courseId)}/${encodeURIComponent(data.activityId)}`;
31918
- }
32566
+ },
32567
+ buildCourseUrl: (courseId) => urls.course(courseId)
31919
32568
  };
31920
32569
  return caliper;
31921
32570
  }
@@ -32038,17 +32687,17 @@ async function listOneRosterCollection(client, endpoint, collectionKey, options)
32038
32687
  function createOneRosterNamespace(client) {
32039
32688
  return {
32040
32689
  classes: {
32041
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.classes, "POST", { class: data }),
32690
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.classes, "POST", { class: data }),
32042
32691
  get: async (sourcedId) => {
32043
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.classes}/${sourcedId}`, "GET");
32692
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.classes}/${sourcedId}`, "GET");
32044
32693
  return res.class;
32045
32694
  },
32046
32695
  update: async (sourcedId, data) => {
32047
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.classes}/${sourcedId}`, "PUT", { class: data });
32696
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.classes}/${sourcedId}`, "PUT", { class: data });
32048
32697
  return res.class;
32049
32698
  },
32050
32699
  listByCourse: async (courseSourcedId) => {
32051
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${courseSourcedId}/classes`, "GET");
32700
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${courseSourcedId}/classes`, "GET");
32052
32701
  return res.classes;
32053
32702
  },
32054
32703
  listByStudent: async (userSourcedId, options) => {
@@ -32059,7 +32708,7 @@ function createOneRosterNamespace(client) {
32059
32708
  if (options?.offset) {
32060
32709
  queryParams.set("offset", String(options.offset));
32061
32710
  }
32062
- const endpoint = `${ONEROSTER_ENDPOINTS.users}/${userSourcedId}/classes`;
32711
+ const endpoint = `${ONEROSTER_ENDPOINTS2.users}/${userSourcedId}/classes`;
32063
32712
  const url2 = queryParams.toString() ? `${endpoint}?${queryParams}` : endpoint;
32064
32713
  const res = await client["request"](url2, "GET");
32065
32714
  return res.classes || [];
@@ -32067,7 +32716,7 @@ function createOneRosterNamespace(client) {
32067
32716
  },
32068
32717
  enrollments: {
32069
32718
  get: async (sourcedId) => {
32070
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "GET");
32719
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "GET");
32071
32720
  return response.enrollment;
32072
32721
  },
32073
32722
  listByClass: async (classSourcedId, options) => {
@@ -32083,7 +32732,7 @@ function createOneRosterNamespace(client) {
32083
32732
  if (options?.offset) {
32084
32733
  queryParams.set("offset", String(options.offset));
32085
32734
  }
32086
- const url2 = `${ONEROSTER_ENDPOINTS.enrollments}?${queryParams}`;
32735
+ const url2 = `${ONEROSTER_ENDPOINTS2.enrollments}?${queryParams}`;
32087
32736
  try {
32088
32737
  const response = await client["request"](url2, "GET");
32089
32738
  return response.enrollments || [];
@@ -32116,7 +32765,7 @@ function createOneRosterNamespace(client) {
32116
32765
  }
32117
32766
  queryParams.set("filter", filters.join(" AND "));
32118
32767
  queryParams.set("limit", "3000");
32119
- const url2 = `${ONEROSTER_ENDPOINTS.enrollments}?${queryParams}`;
32768
+ const url2 = `${ONEROSTER_ENDPOINTS2.enrollments}?${queryParams}`;
32120
32769
  const response = await client["request"](url2, "GET");
32121
32770
  return response.enrollments || [];
32122
32771
  }));
@@ -32146,72 +32795,72 @@ function createOneRosterNamespace(client) {
32146
32795
  throw error;
32147
32796
  }
32148
32797
  },
32149
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.enrollments, "POST", { enrollment: data }),
32798
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.enrollments, "POST", { enrollment: data }),
32150
32799
  update: async (sourcedId, data) => {
32151
- await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "PUT", {
32800
+ await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "PUT", {
32152
32801
  enrollment: data
32153
32802
  });
32154
32803
  },
32155
32804
  delete: async (sourcedId) => {
32156
- await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "DELETE");
32805
+ await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "DELETE");
32157
32806
  }
32158
32807
  },
32159
32808
  organizations: {
32160
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.organizations, "POST", data),
32161
- get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS.organizations}/${sourcedId}`, "GET").then((res) => res.org),
32162
- update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS.organizations}/${sourcedId}`, "PUT", data)
32809
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.organizations, "POST", data),
32810
+ get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS2.organizations}/${sourcedId}`, "GET").then((res) => res.org),
32811
+ update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS2.organizations}/${sourcedId}`, "PUT", data)
32163
32812
  },
32164
32813
  courses: {
32165
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.courses, "POST", data),
32814
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.courses, "POST", data),
32166
32815
  get: async (sourcedId) => {
32167
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${sourcedId}`, "GET");
32816
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${sourcedId}`, "GET");
32168
32817
  return response.course;
32169
32818
  },
32170
32819
  update: async (sourcedId, data) => {
32171
- await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${sourcedId}`, "PUT", {
32820
+ await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${sourcedId}`, "PUT", {
32172
32821
  course: data
32173
32822
  });
32174
32823
  }
32175
32824
  },
32176
32825
  courseComponents: {
32177
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.courseComponents, "POST", data),
32826
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.courseComponents, "POST", data),
32178
32827
  get: async (sourcedId) => {
32179
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.courseComponents}/${sourcedId}`, "GET");
32828
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.courseComponents}/${sourcedId}`, "GET");
32180
32829
  return response.courseComponent;
32181
32830
  },
32182
32831
  update: async (sourcedId, data) => {
32183
- await client["request"](`${ONEROSTER_ENDPOINTS.courseComponents}/${sourcedId}`, "PUT", { courseComponent: data });
32832
+ await client["request"](`${ONEROSTER_ENDPOINTS2.courseComponents}/${sourcedId}`, "PUT", { courseComponent: data });
32184
32833
  }
32185
32834
  },
32186
32835
  resources: {
32187
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.resources, "POST", data),
32836
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.resources, "POST", data),
32188
32837
  get: async (sourcedId) => {
32189
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "GET");
32838
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "GET");
32190
32839
  return response.resource;
32191
32840
  },
32192
32841
  update: async (sourcedId, data) => {
32193
- await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "PUT", {
32842
+ await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "PUT", {
32194
32843
  resource: data
32195
32844
  });
32196
32845
  },
32197
32846
  delete: async (sourcedId) => {
32198
- await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "DELETE");
32847
+ await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "DELETE");
32199
32848
  }
32200
32849
  },
32201
32850
  componentResources: {
32202
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.componentResources, "POST", data),
32851
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.componentResources, "POST", data),
32203
32852
  get: async (sourcedId) => {
32204
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.componentResources}/${sourcedId}`, "GET");
32853
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.componentResources}/${sourcedId}`, "GET");
32205
32854
  return response.componentResource;
32206
32855
  },
32207
32856
  update: async (sourcedId, data) => {
32208
- await client["request"](`${ONEROSTER_ENDPOINTS.componentResources}/${sourcedId}`, "PUT", { componentResource: data });
32857
+ await client["request"](`${ONEROSTER_ENDPOINTS2.componentResources}/${sourcedId}`, "PUT", { componentResource: data });
32209
32858
  }
32210
32859
  },
32211
32860
  assessmentLineItems: {
32212
32861
  list: async (options) => {
32213
32862
  try {
32214
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentLineItems, "assessmentLineItems", options);
32863
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentLineItems, "assessmentLineItems", options);
32215
32864
  } catch (error) {
32216
32865
  logTimebackError("list assessment line items", error, {
32217
32866
  filter: options?.filter
@@ -32219,14 +32868,14 @@ function createOneRosterNamespace(client) {
32219
32868
  return [];
32220
32869
  }
32221
32870
  },
32222
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.assessmentLineItems, "POST", { assessmentLineItem: data }),
32871
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.assessmentLineItems, "POST", { assessmentLineItem: data }),
32223
32872
  get: async (sourcedId) => {
32224
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentLineItems}/${sourcedId}`, "GET");
32873
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentLineItems}/${sourcedId}`, "GET");
32225
32874
  return response.assessmentLineItem;
32226
32875
  },
32227
32876
  findOrCreate: async (sourcedId, data) => {
32228
32877
  try {
32229
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentLineItems}/${sourcedId}`, "GET");
32878
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentLineItems}/${sourcedId}`, "GET");
32230
32879
  return response.assessmentLineItem;
32231
32880
  } catch {
32232
32881
  const createData = {
@@ -32235,7 +32884,7 @@ function createOneRosterNamespace(client) {
32235
32884
  dateLastModified: new Date().toISOString()
32236
32885
  };
32237
32886
  try {
32238
- const response = await client["request"](ONEROSTER_ENDPOINTS.assessmentLineItems, "POST", { assessmentLineItem: createData });
32887
+ const response = await client["request"](ONEROSTER_ENDPOINTS2.assessmentLineItems, "POST", { assessmentLineItem: createData });
32239
32888
  if (!response.sourcedIdPairs?.allocatedSourcedId) {
32240
32889
  throw new Error("Invalid response from OneRoster API - missing allocatedSourcedId");
32241
32890
  }
@@ -32250,7 +32899,7 @@ function createOneRosterNamespace(client) {
32250
32899
  assessmentResults: {
32251
32900
  list: async (options) => {
32252
32901
  try {
32253
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentResults, "assessmentResults", options);
32902
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", options);
32254
32903
  } catch (error) {
32255
32904
  logTimebackError("list assessment results", error, {
32256
32905
  filter: options?.filter
@@ -32258,10 +32907,11 @@ function createOneRosterNamespace(client) {
32258
32907
  return [];
32259
32908
  }
32260
32909
  },
32261
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.assessmentResults, "POST", { assessmentResult: data }),
32910
+ listOrThrow: async (options) => await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", options),
32911
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.assessmentResults, "POST", { assessmentResult: data }),
32262
32912
  listByStudent: async (studentSourcedId, options) => {
32263
32913
  try {
32264
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentResults, "assessmentResults", {
32914
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", {
32265
32915
  limit: options?.limit,
32266
32916
  offset: options?.offset,
32267
32917
  fields: options?.fields,
@@ -32280,54 +32930,22 @@ function createOneRosterNamespace(client) {
32280
32930
  sourcedId,
32281
32931
  dateLastModified: new Date().toISOString()
32282
32932
  };
32283
- return client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "PUT", { assessmentResult });
32933
+ return client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "PUT", { assessmentResult });
32284
32934
  },
32285
32935
  get: async (sourcedId) => {
32286
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "GET");
32936
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "GET");
32287
32937
  return response.assessmentResult;
32288
32938
  },
32289
- update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "PUT", data),
32290
- getAttemptStats: async (studentId, lineItemId) => {
32291
- try {
32292
- const filter = `student.sourcedId='${studentId}' AND assessmentLineItem.sourcedId='${lineItemId}'`;
32293
- const url2 = `${ONEROSTER_ENDPOINTS.assessmentResults}?filter=${encodeURIComponent(filter)}`;
32294
- const response = await client["request"](url2, "GET");
32295
- const results = response.assessmentResults || [];
32296
- const firstResult = results[0];
32297
- if (!firstResult) {
32298
- return null;
32299
- }
32300
- let maxAttemptResult = firstResult;
32301
- let maxAttemptNumber = maxAttemptResult.metadata?.attemptNumber || 0;
32302
- let activeAttemptCount = 0;
32303
- for (const result of results) {
32304
- const attemptNumber = result.metadata?.attemptNumber || 0;
32305
- if (attemptNumber > maxAttemptNumber) {
32306
- maxAttemptNumber = attemptNumber;
32307
- maxAttemptResult = result;
32308
- }
32309
- if (result.status === "active") {
32310
- activeAttemptCount++;
32311
- }
32312
- }
32313
- return { maxAttemptNumber, activeAttemptCount, maxAttemptResult };
32314
- } catch (error) {
32315
- logTimebackError("query attempt stats", error, {
32316
- studentId,
32317
- lineItemId
32318
- });
32319
- return null;
32320
- }
32321
- }
32939
+ update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "PUT", data)
32322
32940
  },
32323
32941
  users: {
32324
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.users, "POST", {
32942
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.users, "POST", {
32325
32943
  user: data
32326
32944
  }),
32327
- get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS.users}/${sourcedId}`, "GET").then((res) => res.user),
32945
+ get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS2.users}/${sourcedId}`, "GET").then((res) => res.user),
32328
32946
  findByEmail: async (email) => {
32329
32947
  const params = new URLSearchParams({ filter: `email='${email}'` });
32330
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.users}?${params}`, "GET");
32948
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.users}?${params}`, "GET");
32331
32949
  if (!response || !response.users || !Array.isArray(response.users)) {
32332
32950
  throw new Error(`Invalid response format from OneRoster API when searching for user with email: ${email}. ` + `Expected { users: [...] } but received: ${JSON.stringify(response)}`);
32333
32951
  }
@@ -32346,7 +32964,7 @@ function createOneRosterNamespace(client) {
32346
32964
  const results = await Promise.all(batches.map(async (batch) => {
32347
32965
  const filter = batch.map((id) => `sourcedId='${escapeFilterValue(id)}'`).join(" OR ");
32348
32966
  const params = new URLSearchParams({ filter });
32349
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.users}?${params}`, "GET");
32967
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.users}?${params}`, "GET");
32350
32968
  return response.users || [];
32351
32969
  }));
32352
32970
  return results.flat();
@@ -32363,11 +32981,11 @@ function createOneRosterNamespace(client) {
32363
32981
  function createQtiNamespace(client) {
32364
32982
  return {
32365
32983
  items: {
32366
- create: async (data) => client["requestQti"](QTI_ENDPOINTS.assessmentItems, "POST", data),
32367
- get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "GET"),
32368
- update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "PUT", data),
32984
+ create: async (data) => client["requestQti"](QTI_ENDPOINTS2.assessmentItems, "POST", data),
32985
+ get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "GET"),
32986
+ update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "PUT", data),
32369
32987
  delete: async (identifier) => {
32370
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "DELETE");
32988
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "DELETE");
32371
32989
  }
32372
32990
  },
32373
32991
  tests: {
@@ -32389,25 +33007,25 @@ function createQtiNamespace(client) {
32389
33007
  params.set("order", options.order);
32390
33008
  }
32391
33009
  const query = params.toString();
32392
- return client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}${query ? `?${query}` : ""}`, "GET");
33010
+ return client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}${query ? `?${query}` : ""}`, "GET");
32393
33011
  },
32394
- create: async (data) => client["requestQti"](QTI_ENDPOINTS.assessmentTests, "POST", data),
32395
- get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "GET"),
32396
- getQuestions: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}/questions`, "GET"),
32397
- update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "PUT", data),
33012
+ create: async (data) => client["requestQti"](QTI_ENDPOINTS2.assessmentTests, "POST", data),
33013
+ get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "GET"),
33014
+ getQuestions: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}/questions`, "GET"),
33015
+ update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "PUT", data),
32398
33016
  delete: async (identifier) => {
32399
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "DELETE");
33017
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "DELETE");
32400
33018
  },
32401
- addItem: async (testId, partId, sectionId, itemIdentifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items`, "POST", { identifier: itemIdentifier }),
33019
+ addItem: async (testId, partId, sectionId, itemIdentifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items`, "POST", { identifier: itemIdentifier }),
32402
33020
  removeItem: async (testId, partId, sectionId, itemIdentifier) => {
32403
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/${itemIdentifier}`, "DELETE");
33021
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/${itemIdentifier}`, "DELETE");
32404
33022
  },
32405
- reorderItems: async (testId, partId, sectionId, items) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/order`, "PUT", { items })
33023
+ reorderItems: async (testId, partId, sectionId, items) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/order`, "PUT", { items })
32406
33024
  }
32407
33025
  };
32408
33026
  }
32409
33027
  function toCaliperSubject(subject) {
32410
- return isTimebackSubject2(subject) ? subject : "None";
33028
+ return isTimebackSubject3(subject) ? subject : "None";
32411
33029
  }
32412
33030
  function buildAdminEventMetadata({
32413
33031
  reason,
@@ -32471,7 +33089,7 @@ class AdminEventRecorder {
32471
33089
  defaultActivityId: "playcademy-admin-manual-xp",
32472
33090
  eventKind: "remediation-xp"
32473
33091
  });
32474
- const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS[this.environment]).course(data.courseId);
33092
+ const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS2[this.environment]).course(data.courseId);
32475
33093
  await this.caliper.emitActivityEvent({
32476
33094
  studentId: ctx.student.id,
32477
33095
  studentEmail: ctx.student.email,
@@ -32521,7 +33139,7 @@ class AdminEventRecorder {
32521
33139
  defaultActivityId: "playcademy-admin-mastery-adjustment",
32522
33140
  eventKind: "remediation-mastery"
32523
33141
  });
32524
- const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS[this.environment]).course(data.courseId);
33142
+ const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS2[this.environment]).course(data.courseId);
32525
33143
  await this.caliper.emitActivityEvent({
32526
33144
  studentId: ctx.student.id,
32527
33145
  studentEmail: ctx.student.email,
@@ -32555,9 +33173,9 @@ class TimebackCache {
32555
33173
  maxSize;
32556
33174
  name;
32557
33175
  constructor(options = {}) {
32558
- this.defaultTTL = options.defaultTTL || CACHE_DEFAULTS.defaultTTL;
32559
- this.maxSize = options.maxSize || CACHE_DEFAULTS.defaultMaxSize;
32560
- this.name = options.name || CACHE_DEFAULTS.defaultName;
33176
+ this.defaultTTL = options.defaultTTL || CACHE_DEFAULTS2.defaultTTL;
33177
+ this.maxSize = options.maxSize || CACHE_DEFAULTS2.defaultMaxSize;
33178
+ this.name = options.name || CACHE_DEFAULTS2.defaultName;
32561
33179
  }
32562
33180
  get(key) {
32563
33181
  const entry = this.cache.get(key);
@@ -32648,23 +33266,23 @@ class TimebackCacheManager {
32648
33266
  enrollmentCache;
32649
33267
  constructor() {
32650
33268
  this.studentCache = new TimebackCache({
32651
- defaultTTL: CACHE_DEFAULTS.studentTTL,
32652
- maxSize: CACHE_DEFAULTS.studentMaxSize,
33269
+ defaultTTL: CACHE_DEFAULTS2.studentTTL,
33270
+ maxSize: CACHE_DEFAULTS2.studentMaxSize,
32653
33271
  name: "StudentCache"
32654
33272
  });
32655
33273
  this.assessmentLineItemCache = new TimebackCache({
32656
- defaultTTL: CACHE_DEFAULTS.assessmentTTL,
32657
- maxSize: CACHE_DEFAULTS.assessmentMaxSize,
33274
+ defaultTTL: CACHE_DEFAULTS2.assessmentTTL,
33275
+ maxSize: CACHE_DEFAULTS2.assessmentMaxSize,
32658
33276
  name: "AssessmentLineItemCache"
32659
33277
  });
32660
33278
  this.resourceMasteryCache = new TimebackCache({
32661
- defaultTTL: CACHE_DEFAULTS.assessmentTTL,
32662
- maxSize: CACHE_DEFAULTS.assessmentMaxSize,
33279
+ defaultTTL: CACHE_DEFAULTS2.assessmentTTL,
33280
+ maxSize: CACHE_DEFAULTS2.assessmentMaxSize,
32663
33281
  name: "ResourceMasteryCache"
32664
33282
  });
32665
33283
  this.enrollmentCache = new TimebackCache({
32666
- defaultTTL: CACHE_DEFAULTS.enrollmentTTL,
32667
- maxSize: CACHE_DEFAULTS.enrollmentMaxSize,
33284
+ defaultTTL: CACHE_DEFAULTS2.enrollmentTTL,
33285
+ maxSize: CACHE_DEFAULTS2.enrollmentMaxSize,
32668
33286
  name: "EnrollmentCache"
32669
33287
  });
32670
33288
  }
@@ -32920,18 +33538,18 @@ class MasteryTracker {
32920
33538
  await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
32921
33539
  sourcedId: lineItemId,
32922
33540
  title: "Mastery Completion",
32923
- status: ONEROSTER_STATUS.active,
33541
+ status: ONEROSTER_STATUS2.active,
32924
33542
  ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } },
32925
33543
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
32926
33544
  });
32927
33545
  await this.onerosterNamespace.assessmentResults.upsert(resultId, {
32928
33546
  sourcedId: resultId,
32929
- status: ONEROSTER_STATUS.active,
33547
+ status: ONEROSTER_STATUS2.active,
32930
33548
  assessmentLineItem: { sourcedId: lineItemId },
32931
33549
  student: { sourcedId: studentId },
32932
33550
  score: 100,
32933
33551
  scoreDate: new Date().toISOString(),
32934
- scoreStatus: SCORE_STATUS.fullyGraded,
33552
+ scoreStatus: SCORE_STATUS2.fullyGraded,
32935
33553
  inProgress: "false",
32936
33554
  metadata: {
32937
33555
  isMasteryCompletion: true,
@@ -32943,6 +33561,7 @@ class MasteryTracker {
32943
33561
  "app.timeback.line_item_id": lineItemId,
32944
33562
  "app.timeback.result_id": resultId
32945
33563
  });
33564
+ return true;
32946
33565
  } catch (error) {
32947
33566
  addEvent("timeback.mastery_completion_failed", {
32948
33567
  "app.timeback.student_id": studentId,
@@ -32950,6 +33569,7 @@ class MasteryTracker {
32950
33569
  "exception.type": errorType(error),
32951
33570
  "app.error.message": errorMessage(error)
32952
33571
  });
33572
+ return false;
32953
33573
  }
32954
33574
  }
32955
33575
  async revokeCompletionEntry(studentId, courseId, classId, appName) {
@@ -32960,18 +33580,18 @@ class MasteryTracker {
32960
33580
  await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
32961
33581
  sourcedId: lineItemId,
32962
33582
  title: "Mastery Completion",
32963
- status: ONEROSTER_STATUS.active,
33583
+ status: ONEROSTER_STATUS2.active,
32964
33584
  ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } },
32965
33585
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
32966
33586
  });
32967
33587
  await this.onerosterNamespace.assessmentResults.upsert(resultId, {
32968
33588
  sourcedId: resultId,
32969
- status: ONEROSTER_STATUS.active,
33589
+ status: ONEROSTER_STATUS2.active,
32970
33590
  assessmentLineItem: { sourcedId: lineItemId },
32971
33591
  student: { sourcedId: studentId },
32972
33592
  score: 0,
32973
33593
  scoreDate: new Date().toISOString(),
32974
- scoreStatus: SCORE_STATUS.notSubmitted,
33594
+ scoreStatus: SCORE_STATUS2.notSubmitted,
32975
33595
  inProgress: "true",
32976
33596
  metadata: {
32977
33597
  isMasteryCompletion: true,
@@ -33006,7 +33626,7 @@ class MasteryTracker {
33006
33626
  if (!playcademyMetadata) {
33007
33627
  return;
33008
33628
  }
33009
- const masterableUnits = isPlaycademyResourceMetadata(playcademyMetadata) ? playcademyMetadata.mastery?.masterableUnits : undefined;
33629
+ const masterableUnits = isPlaycademyResourceMetadata2(playcademyMetadata) ? playcademyMetadata.mastery?.masterableUnits : undefined;
33010
33630
  this.cacheManager.setResourceMasterableUnits(resourceId, masterableUnits ?? null);
33011
33631
  return masterableUnits;
33012
33632
  } catch (error) {
@@ -33086,13 +33706,11 @@ function validateSessionData(sessionData) {
33086
33706
 
33087
33707
  class ProgressRecorder {
33088
33708
  studentResolver;
33089
- cacheManager;
33090
33709
  onerosterNamespace;
33091
33710
  caliperNamespace;
33092
33711
  masteryTracker;
33093
- constructor(studentResolver, cacheManager, onerosterNamespace, caliperNamespace, masteryTracker) {
33712
+ constructor(studentResolver, onerosterNamespace, caliperNamespace, masteryTracker) {
33094
33713
  this.studentResolver = studentResolver;
33095
- this.cacheManager = cacheManager;
33096
33714
  this.onerosterNamespace = onerosterNamespace;
33097
33715
  this.caliperNamespace = caliperNamespace;
33098
33716
  this.masteryTracker = masteryTracker;
@@ -33101,26 +33719,37 @@ class ProgressRecorder {
33101
33719
  validateProgressData(progressData);
33102
33720
  const { ids, activityId, activityName, courseName, student } = await this.resolveContext(courseId, studentIdentifier, progressData);
33103
33721
  const { id: studentId, email: studentEmail } = student;
33104
- const {
33105
- score,
33106
- totalQuestions,
33107
- correctQuestions,
33108
- xpEarned = 0,
33109
- attemptNumber
33110
- } = progressData;
33111
- let extensions = progressData.extensions;
33112
- const masteryProgress = await this.masteryTracker.checkProgress({
33113
- studentId,
33114
- courseId,
33115
- resourceId: ids.resource,
33116
- masteredUnits: progressData.masteredUnits ?? 0,
33117
- masteredUnitsAbsolute: progressData.masteredUnitsAbsolute
33722
+ const { totalQuestions, correctQuestions, xpEarned = 0, attemptNumber } = progressData;
33723
+ const activityUrl = this.caliperNamespace.buildActivityUrl({
33724
+ courseId: ids.course,
33725
+ activityId,
33726
+ sensorUrl: progressData.sensorUrl
33118
33727
  });
33728
+ const courseUrl = this.caliperNamespace.buildCourseUrl(ids.course);
33729
+ let caliperLineItemId;
33730
+ try {
33731
+ caliperLineItemId = computeCaliperLineItemId(activityUrl, ids.course, courseUrl);
33732
+ } catch (error) {
33733
+ setAttributes({ "app.timeback.course_id_not_url_safe": true });
33734
+ throw error;
33735
+ }
33736
+ const legacyLineItemId = `${ids.course}-${activityId}-assessment`;
33737
+ const [currentAttemptNumber, masteryProgress] = await Promise.all([
33738
+ this.resolveAttemptNumber(attemptNumber, studentId, caliperLineItemId, legacyLineItemId),
33739
+ this.masteryTracker.checkProgress({
33740
+ studentId,
33741
+ courseId,
33742
+ resourceId: ids.resource,
33743
+ masteredUnits: progressData.masteredUnits ?? 0,
33744
+ masteredUnitsAbsolute: progressData.masteredUnitsAbsolute
33745
+ })
33746
+ ]);
33747
+ setAttributes({ "app.timeback.attempt_number": currentAttemptNumber });
33748
+ let extensions = progressData.extensions;
33119
33749
  const effectiveMasteredUnits = masteryProgress ? masteryProgress.effectiveDelta : progressData.masteredUnits ?? 0;
33120
33750
  let pctCompleteApp;
33121
33751
  let masteryAchieved = false;
33122
- let scoreStatus = SCORE_STATUS.fullyGraded;
33123
- const inProgress = "false";
33752
+ let completionEntryWritten = false;
33124
33753
  const warnings = masteryProgress?.writeWarning ? [masteryProgress.writeWarning] : undefined;
33125
33754
  if (masteryProgress) {
33126
33755
  masteryAchieved = masteryProgress.masteryAchieved;
@@ -33129,32 +33758,12 @@ class ProgressRecorder {
33129
33758
  ...extensions,
33130
33759
  ...pctCompleteApp !== undefined ? { pctCompleteApp } : {}
33131
33760
  };
33132
- if (masteryAchieved) {
33133
- scoreStatus = SCORE_STATUS.fullyGraded;
33134
- }
33135
33761
  }
33136
- const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
33137
- const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
33138
- if (score !== undefined) {
33139
- await this.createGradebookEntry({
33140
- lineItemId: actualLineItemId,
33141
- studentId,
33142
- attemptNumber: currentAttemptNumber,
33143
- score,
33144
- xp: xpEarned,
33145
- scoreStatus,
33146
- inProgress,
33147
- appName: progressData.appName,
33148
- totalQuestions,
33149
- correctQuestions,
33150
- masteredUnits: effectiveMasteredUnits || undefined,
33151
- pctCompleteApp
33152
- });
33153
- } else {
33154
- setAttribute("app.timeback.score_provided", false);
33762
+ if (masteryAchieved) {
33763
+ setAttributes({ "app.timeback.mastery_achieved": true });
33155
33764
  }
33156
33765
  if (masteryAchieved) {
33157
- await this.masteryTracker.createCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33766
+ completionEntryWritten = await this.masteryTracker.createCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33158
33767
  await this.emitCourseCompletionHistoryEvent({
33159
33768
  studentId,
33160
33769
  studentEmail,
@@ -33170,30 +33779,36 @@ class ProgressRecorder {
33170
33779
  if (masteryProgress?.masteryRevoked) {
33171
33780
  await this.masteryTracker.revokeCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33172
33781
  }
33173
- await this.emitCaliperEvent({
33174
- studentId,
33175
- studentEmail,
33176
- gameId: progressData.gameId,
33177
- activityId,
33178
- activityName,
33179
- courseId: ids.course,
33180
- courseName,
33181
- totalQuestions,
33182
- correctQuestions,
33183
- xpEarned,
33184
- masteredUnits: effectiveMasteredUnits || undefined,
33185
- attemptNumber: currentAttemptNumber,
33186
- progressData,
33187
- extensions,
33188
- runId: progressData.runId
33189
- });
33782
+ try {
33783
+ await this.emitCaliperEvent({
33784
+ studentId,
33785
+ studentEmail,
33786
+ gameId: progressData.gameId,
33787
+ activityId,
33788
+ activityName,
33789
+ courseId: ids.course,
33790
+ courseName,
33791
+ totalQuestions,
33792
+ correctQuestions,
33793
+ xpEarned,
33794
+ masteredUnits: effectiveMasteredUnits || undefined,
33795
+ attemptNumber: currentAttemptNumber,
33796
+ objectId: activityUrl,
33797
+ progressData,
33798
+ extensions,
33799
+ runId: progressData.runId
33800
+ });
33801
+ } catch (error) {
33802
+ if (completionEntryWritten) {
33803
+ setAttributes({ "app.timeback.completion_orphaned": true });
33804
+ }
33805
+ throw error;
33806
+ }
33190
33807
  return {
33191
33808
  xpAwarded: xpEarned,
33192
33809
  attemptNumber: currentAttemptNumber,
33193
33810
  masteredUnitsApplied: effectiveMasteredUnits,
33194
33811
  pctCompleteApp,
33195
- scoreStatus,
33196
- inProgress,
33197
33812
  ...warnings ? { warnings } : {}
33198
33813
  };
33199
33814
  }
@@ -33205,89 +33820,48 @@ class ProgressRecorder {
33205
33820
  const student = await this.studentResolver.resolve(studentIdentifier, progressData.studentEmail);
33206
33821
  return { ids, activityId, activityName, courseName, student };
33207
33822
  }
33208
- async resolveAssessmentLineItem(activityId, activityName, classId, ids) {
33209
- const lineItemId = `${ids.course}-${activityId}-assessment`;
33210
- let actualLineItemId = this.cacheManager.getAssessmentLineItem(lineItemId);
33211
- if (!actualLineItemId) {
33212
- actualLineItemId = await this.getOrCreateLineItem(lineItemId, activityName, classId, ids);
33213
- this.cacheManager.setAssessmentLineItem(lineItemId, actualLineItemId);
33214
- }
33215
- return actualLineItemId;
33216
- }
33217
- async resolveAttemptNumber(providedAttemptNumber, score, studentId, lineItemId) {
33823
+ async resolveAttemptNumber(providedAttemptNumber, studentId, caliperLineItemId, legacyLineItemId) {
33218
33824
  if (providedAttemptNumber) {
33825
+ setAttributes({ "app.timeback.attempt_source": "provided" });
33219
33826
  return providedAttemptNumber;
33220
33827
  }
33221
- if (score !== undefined) {
33222
- return this.determineAttemptNumber(studentId, lineItemId);
33223
- }
33224
- return 1;
33225
- }
33226
- async getOrCreateLineItem(lineItemId, activityName, classId, ids) {
33227
- try {
33228
- const lineItem = await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
33229
- sourcedId: lineItemId,
33230
- title: activityName,
33231
- status: ONEROSTER_STATUS.active,
33232
- ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } }
33828
+ const caliperAttempt = await this.getLatestActivityAttempt(studentId, caliperLineItemId, "attempt");
33829
+ if (caliperAttempt !== null) {
33830
+ const next = caliperAttempt + 1;
33831
+ setAttributes({
33832
+ "app.timeback.attempt_source": caliperAttempt > 0 ? "caliper" : "caliper_unreadable"
33233
33833
  });
33234
- if (!lineItem.sourcedId) {
33235
- throw new TimebackError(`Assessment line item created but has no sourcedId. ` + `This should not happen and indicates an upstream API issue.`);
33236
- }
33237
- return lineItem.sourcedId;
33238
- } catch (error) {
33239
- if (error instanceof TimebackApiError && error.status === 404) {
33240
- const errorDetails = error.details;
33241
- const description = errorDetails?.imsx_description || error.message;
33242
- if (description.includes("course") && description.includes("not found") || description.includes("component") && description.includes("not found") || description.includes("resource") && description.includes("not found") || description.includes("componentResource") && description.includes("not found")) {
33243
- throw new ResourceNotFoundError("TimeBack resources", "setup-not-run");
33244
- }
33834
+ if (caliperAttempt === 0) {
33835
+ setAttributes({
33836
+ "app.timeback.attempt_regressed": true,
33837
+ "app.timeback.attempt_emitted": next
33838
+ });
33245
33839
  }
33246
- throw error;
33840
+ return next;
33247
33841
  }
33248
- }
33249
- async determineAttemptNumber(studentId, lineItemId) {
33250
- const stats = await this.onerosterNamespace.assessmentResults.getAttemptStats(studentId, lineItemId);
33251
- if (stats) {
33252
- return stats.activeAttemptCount + 1;
33842
+ const legacyAttempt = await this.getLatestActivityAttempt(studentId, legacyLineItemId, "attemptNumber");
33843
+ if (legacyAttempt !== null) {
33844
+ setAttributes({
33845
+ "app.timeback.attempt_source": "legacy_seed",
33846
+ "app.timeback.legacy_seed_attempt": legacyAttempt
33847
+ });
33848
+ return legacyAttempt + 1;
33253
33849
  }
33850
+ setAttributes({ "app.timeback.attempt_source": "first" });
33254
33851
  return 1;
33255
33852
  }
33256
- async createGradebookEntry({
33257
- lineItemId,
33258
- studentId,
33259
- attemptNumber,
33260
- score,
33261
- xp,
33262
- scoreStatus,
33263
- inProgress,
33264
- appName,
33265
- totalQuestions,
33266
- correctQuestions,
33267
- masteredUnits,
33268
- pctCompleteApp
33269
- }) {
33270
- const timestamp3 = Date.now().toString(36);
33271
- const resultId = `${lineItemId}:${studentId}:${timestamp3}`;
33272
- await this.onerosterNamespace.assessmentResults.upsert(resultId, {
33273
- sourcedId: resultId,
33274
- status: ONEROSTER_STATUS.active,
33275
- assessmentLineItem: { sourcedId: lineItemId },
33276
- student: { sourcedId: studentId },
33277
- score,
33278
- scoreDate: new Date().toISOString(),
33279
- scoreStatus,
33280
- inProgress,
33281
- metadata: {
33282
- xp,
33283
- attemptNumber,
33284
- appName,
33285
- ...totalQuestions !== undefined ? { totalQuestions } : {},
33286
- ...correctQuestions !== undefined ? { correctQuestions } : {},
33287
- ...masteredUnits !== undefined ? { masteredUnits } : {},
33288
- ...pctCompleteApp !== undefined ? { pctCompleteApp } : {}
33289
- }
33853
+ async getLatestActivityAttempt(studentId, lineItemId, metadataField) {
33854
+ const results = await this.onerosterNamespace.assessmentResults.listOrThrow({
33855
+ filter: `student.sourcedId='${escapeFilterValue(studentId)}' AND assessmentLineItem.sourcedId='${escapeFilterValue(lineItemId)}' AND status='active'`,
33856
+ sort: "dateLastModified",
33857
+ orderBy: "desc",
33858
+ limit: 1
33290
33859
  });
33860
+ const latest = results[0];
33861
+ if (!latest) {
33862
+ return null;
33863
+ }
33864
+ return latest.metadata?.[metadataField] || 0;
33291
33865
  }
33292
33866
  async emitCaliperEvent({
33293
33867
  studentId,
@@ -33302,6 +33876,7 @@ class ProgressRecorder {
33302
33876
  xpEarned,
33303
33877
  masteredUnits,
33304
33878
  attemptNumber,
33879
+ objectId,
33305
33880
  progressData,
33306
33881
  extensions,
33307
33882
  runId
@@ -33319,12 +33894,18 @@ class ProgressRecorder {
33319
33894
  xpEarned,
33320
33895
  masteredUnits,
33321
33896
  attemptNumber,
33897
+ objectId,
33898
+ process: true,
33322
33899
  subject: progressData.subject,
33323
33900
  appName: progressData.appName,
33324
33901
  sensorUrl: progressData.sensorUrl,
33325
33902
  extensions: extensions || progressData.extensions,
33326
33903
  ...runId ? { runId } : {}
33327
- }).catch(catchEvent("timeback.caliper_event_failed"));
33904
+ }).catch((error) => {
33905
+ setAttributes({ "app.timeback.caliper_emit_failed": true });
33906
+ catchEvent("timeback.caliper_event_failed")(error);
33907
+ throw error;
33908
+ });
33328
33909
  }
33329
33910
  async emitCourseCompletionHistoryEvent(data) {
33330
33911
  await this.caliperNamespace.emitActivityEvent({
@@ -33502,15 +34083,15 @@ class TimebackClient {
33502
34083
  masteryTracker;
33503
34084
  constructor(config2) {
33504
34085
  this.baseUrl = TimebackClient.resolveBaseUrl(config2?.baseUrl);
33505
- this.environment = process.env[ENV_VARS.environment] === "staging" ? "staging" : "production";
34086
+ this.environment = process.env[ENV_VARS2.environment] === "staging" ? "staging" : "production";
33506
34087
  this.caliperUrl = TimebackClient.resolveCaliperUrl(config2?.caliperUrl, this.environment);
33507
34088
  this.authUrl = config2?.credentials?.authUrl;
33508
34089
  this.credentials = config2?.credentials;
33509
34090
  this.qtiCredentials = config2?.qtiCredentials;
33510
34091
  this.options = {
33511
- retries: config2?.options?.retries ?? HTTP_DEFAULTS.retries,
33512
- cacheDuration: config2?.options?.cacheDuration ?? AUTH_DEFAULTS.tokenCacheDuration,
33513
- timeout: config2?.options?.timeout ?? HTTP_DEFAULTS.timeout,
34092
+ retries: config2?.options?.retries ?? HTTP_DEFAULTS2.retries,
34093
+ cacheDuration: config2?.options?.cacheDuration ?? AUTH_DEFAULTS2.tokenCacheDuration,
34094
+ timeout: config2?.options?.timeout ?? HTTP_DEFAULTS2.timeout,
33514
34095
  sensorUrl: config2?.options?.sensorUrl
33515
34096
  };
33516
34097
  this.oneroster = createOneRosterNamespace(this);
@@ -33520,7 +34101,7 @@ class TimebackClient {
33520
34101
  this.cacheManager = new TimebackCacheManager;
33521
34102
  this.studentResolver = new StudentResolver(this.cacheManager, this.oneroster);
33522
34103
  this.masteryTracker = new MasteryTracker(this.cacheManager, this.oneroster, this.edubridge);
33523
- this.progressRecorder = new ProgressRecorder(this.studentResolver, this.cacheManager, this.oneroster, this.caliper, this.masteryTracker);
34104
+ this.progressRecorder = new ProgressRecorder(this.studentResolver, this.oneroster, this.caliper, this.masteryTracker);
33524
34105
  this.sessionRecorder = new SessionRecorder(this.studentResolver, this.caliper);
33525
34106
  this.adminEventRecorder = new AdminEventRecorder(this.studentResolver, this.oneroster, this.caliper, this.environment);
33526
34107
  if (this.credentials) {
@@ -33529,16 +34110,16 @@ class TimebackClient {
33529
34110
  }
33530
34111
  static async init(config2) {
33531
34112
  let credentials = config2?.credentials;
33532
- if (!credentials && process.env[ENV_VARS.clientId] && process.env[ENV_VARS.clientSecret]) {
34113
+ if (!credentials && process.env[ENV_VARS2.clientId] && process.env[ENV_VARS2.clientSecret]) {
33533
34114
  credentials = {
33534
- clientId: process.env[ENV_VARS.clientId],
33535
- clientSecret: process.env[ENV_VARS.clientSecret]
34115
+ clientId: process.env[ENV_VARS2.clientId],
34116
+ clientSecret: process.env[ENV_VARS2.clientSecret]
33536
34117
  };
33537
34118
  }
33538
- const qtiCredentials = config2?.qtiCredentials ?? (process.env[ENV_VARS.qtiClientId] && process.env[ENV_VARS.qtiClientSecret] && process.env[ENV_VARS.qtiAuthUrl] ? {
33539
- clientId: process.env[ENV_VARS.qtiClientId],
33540
- clientSecret: process.env[ENV_VARS.qtiClientSecret],
33541
- authUrl: process.env[ENV_VARS.qtiAuthUrl]
34119
+ const qtiCredentials = config2?.qtiCredentials ?? (process.env[ENV_VARS2.qtiClientId] && process.env[ENV_VARS2.qtiClientSecret] && process.env[ENV_VARS2.qtiAuthUrl] ? {
34120
+ clientId: process.env[ENV_VARS2.qtiClientId],
34121
+ clientSecret: process.env[ENV_VARS2.qtiClientSecret],
34122
+ authUrl: process.env[ENV_VARS2.qtiAuthUrl]
33542
34123
  } : undefined);
33543
34124
  return new TimebackClient({
33544
34125
  ...config2,
@@ -33551,15 +34132,15 @@ class TimebackClient {
33551
34132
  if (explicit) {
33552
34133
  return explicit;
33553
34134
  }
33554
- const envName = process.env[ENV_VARS.environment] === "staging" ? "staging" : "production";
33555
- return TIMEBACK_API_URLS[envName];
34135
+ const envName = process.env[ENV_VARS2.environment] === "staging" ? "staging" : "production";
34136
+ return TIMEBACK_API_URLS2[envName];
33556
34137
  }
33557
34138
  static resolveCaliperUrl(input, environment = "production") {
33558
34139
  const explicit = (input || "").trim();
33559
34140
  if (explicit) {
33560
34141
  return explicit;
33561
34142
  }
33562
- return CALIPER_API_URLS[environment];
34143
+ return CALIPER_API_URLS2[environment];
33563
34144
  }
33564
34145
  getBaseUrl() {
33565
34146
  return this.baseUrl;
@@ -33680,14 +34261,14 @@ class TimebackClient {
33680
34261
  await this._ensureAuthenticated();
33681
34262
  return this.token;
33682
34263
  }
33683
- throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl}.`);
34264
+ throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl}.`);
33684
34265
  }
33685
34266
  async ensureQtiAuthenticated() {
33686
34267
  if (this.isQtiAuthenticated()) {
33687
34268
  return;
33688
34269
  }
33689
34270
  if (!this.qtiCredentials) {
33690
- throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl}.`);
34271
+ throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl}.`);
33691
34272
  }
33692
34273
  try {
33693
34274
  const tokenData = await getTimebackTokenResponse({
@@ -33699,11 +34280,11 @@ class TimebackClient {
33699
34280
  this.setQtiToken(tokenData.access_token, tokenData.expires_in);
33700
34281
  } catch (error) {
33701
34282
  const errMsg = errorMessage(error);
33702
- throw new TimebackAuthenticationError(`QTI authentication failed: ${errMsg}. ` + `Verify that ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl} are correct.`);
34283
+ throw new TimebackAuthenticationError(`QTI authentication failed: ${errMsg}. ` + `Verify that ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl} are correct.`);
33703
34284
  }
33704
34285
  }
33705
34286
  canUseCoreCredentialsForQti() {
33706
- return this.baseUrl.replace(/\/$/, "") === TIMEBACK_API_URLS.production;
34287
+ return this.baseUrl.replace(/\/$/, "") === TIMEBACK_API_URLS2.production;
33707
34288
  }
33708
34289
  async resolveStudent(studentIdentifier, providedEmail) {
33709
34290
  return this.studentResolver.resolve(studentIdentifier, providedEmail);
@@ -33724,8 +34305,8 @@ class TimebackClient {
33724
34305
  await this._ensureAuthenticated();
33725
34306
  const edubridgeEnrollments = await this.edubridge.enrollments.listByUser(studentId);
33726
34307
  const enrollments = edubridgeEnrollments.map((enrollment) => {
33727
- const grades = enrollment.course.grades ? enrollment.course.grades.map((g) => parseInt(g, 10)).filter(isTimebackGrade2) : null;
33728
- const subjects = enrollment.course.subjects ? enrollment.course.subjects.filter(isTimebackSubject2) : null;
34308
+ const grades = enrollment.course.grades ? enrollment.course.grades.map((g) => parseInt(g, 10)).filter(isTimebackGrade3) : null;
34309
+ const subjects = enrollment.course.subjects ? enrollment.course.subjects.filter(isTimebackSubject3) : null;
33729
34310
  return {
33730
34311
  sourcedId: enrollment.id,
33731
34312
  title: enrollment.course.title,
@@ -33791,9 +34372,9 @@ class TimebackClient {
33791
34372
  if (options?.include?.perCourse) {
33792
34373
  const gradeStr = enrollment.course.grades?.[0];
33793
34374
  const parsedGrade = gradeStr ? parseInt(gradeStr, 10) : 0;
33794
- const grade = isTimebackGrade2(parsedGrade) ? parsedGrade : 0;
34375
+ const grade = isTimebackGrade3(parsedGrade) ? parsedGrade : 0;
33795
34376
  const subjectStr = enrollment.course.subjects?.[0];
33796
- const subject = subjectStr && isTimebackSubject2(subjectStr) ? subjectStr : "None";
34377
+ const subject = subjectStr && isTimebackSubject3(subjectStr) ? subjectStr : "None";
33797
34378
  courses.push({
33798
34379
  grade,
33799
34380
  subject,
@@ -33867,9 +34448,9 @@ class TimebackClient {
33867
34448
  if (options?.include?.perCourse) {
33868
34449
  const gradeStr = enrollment.course.grades?.[0];
33869
34450
  const parsedGrade = gradeStr ? parseInt(gradeStr, 10) : 0;
33870
- const grade = isTimebackGrade2(parsedGrade) ? parsedGrade : 0;
34451
+ const grade = isTimebackGrade3(parsedGrade) ? parsedGrade : 0;
33871
34452
  const subjectStr = enrollment.course.subjects?.[0];
33872
- const subject = subjectStr && isTimebackSubject2(subjectStr) ? subjectStr : "None";
34453
+ const subject = subjectStr && isTimebackSubject3(subjectStr) ? subjectStr : "None";
33873
34454
  courses.push({
33874
34455
  grade,
33875
34456
  subject,
@@ -33925,6 +34506,12 @@ class TimebackClient {
33925
34506
  async cleanup(courseId) {
33926
34507
  return deleteTimebackResources(this, courseId);
33927
34508
  }
34509
+ async deactivateCourse(courseId) {
34510
+ return updateTimebackCourseStatus(this, courseId, "tobedeleted");
34511
+ }
34512
+ async reactivateCourse(courseId) {
34513
+ return updateTimebackCourseStatus(this, courseId, "active");
34514
+ }
33928
34515
  }
33929
34516
  var __defProp2, __export2 = (target, all) => {
33930
34517
  for (var name3 in all)
@@ -33934,7 +34521,7 @@ var __defProp2, __export2 = (target, all) => {
33934
34521
  configurable: true,
33935
34522
  set: (newValue) => all[name3] = () => newValue
33936
34523
  });
33937
- }, __esm2 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS, CALIPER_API_URLS, ONEROSTER_ENDPOINTS, QTI_ENDPOINTS, CALIPER_ENDPOINTS, CALIPER_CONSTANTS, TIMEBACK_EVENT_TYPES, TIMEBACK_ACTIONS, TIMEBACK_TYPES, ACTIVITY_METRIC_TYPES, TIME_METRIC_TYPES, TIMEBACK_SUBJECTS2, TIMEBACK_GRADE_LEVELS, TIMEBACK_GRADE_LEVEL_LABELS, CALIPER_SUBJECTS, ONEROSTER_STATUS, SCORE_STATUS, ENV_VARS, HTTP_DEFAULTS, AUTH_DEFAULTS, CACHE_DEFAULTS, CONFIG_DEFAULTS, PLAYCADEMY_DEFAULTS, RESOURCE_DEFAULTS, HTTP_STATUS, ERROR_NAMES, init_constants4, exports_verify, init_verify, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceNotFoundError, SUBJECT_VALUES, GRADE_VALUES, TimebackAuthError, UUID_PATTERN, storage, MASTERY_WRITE_CAPPED_WARNING_CODE = "MASTERY_WRITE_CAPPED", EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
34524
+ }, __esm3 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS2, QTI_API_URL = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS2, CALIPER_API_URLS2, ONEROSTER_ENDPOINTS2, QTI_ENDPOINTS2, CALIPER_ENDPOINTS2, CALIPER_CONSTANTS2, TIMEBACK_EVENT_TYPES2, TIMEBACK_ACTIONS2, TIMEBACK_TYPES2, ACTIVITY_METRIC_TYPES2, TIME_METRIC_TYPES2, TIMEBACK_SUBJECTS3, TIMEBACK_GRADE_LEVELS2, TIMEBACK_GRADE_LEVEL_LABELS2, CALIPER_SUBJECTS2, ONEROSTER_STATUS2, SCORE_STATUS2, ENV_VARS2, HTTP_DEFAULTS2, AUTH_DEFAULTS2, CACHE_DEFAULTS2, CONFIG_DEFAULTS2, PLAYCADEMY_DEFAULTS2, RESOURCE_DEFAULTS2, HTTP_STATUS2, ERROR_NAMES2, init_constants5, TimebackError, TimebackApiError, TimebackAuthenticationError, StudentNotFoundError, ConfigurationError, ResourceAlreadyExistsError, ResourceNotFoundError, init_errors4, UUID_REGEX2, init_ids, exports_verify, init_verify, SUBJECT_VALUES2, GRADE_VALUES2, TimebackAuthError, UUID_PATTERN, storage, MASTERY_WRITE_CAPPED_WARNING_CODE = "MASTERY_WRITE_CAPPED", EmailSchema, StudentSourcedIdSchema, StudentIdentifierSchema;
33938
34525
  var init_dist2 = __esm(() => {
33939
34526
  init_src();
33940
34527
  init_src();
@@ -33960,293 +34547,7 @@ var init_dist2 = __esm(() => {
33960
34547
  init_spans();
33961
34548
  init_esm();
33962
34549
  __defProp2 = Object.defineProperty;
33963
- init_constants4 = __esm2(() => {
33964
- TIMEBACK_API_URLS = {
33965
- production: "https://api.alpha-1edtech.ai",
33966
- staging: "https://api.staging.alpha-1edtech.com"
33967
- };
33968
- TIMEBACK_AUTH_URLS = {
33969
- production: "https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com",
33970
- staging: "https://alpha-auth-development-idp.auth.us-west-2.amazoncognito.com"
33971
- };
33972
- CALIPER_API_URLS = {
33973
- production: "https://caliper.alpha-1edtech.ai",
33974
- staging: "https://caliper-staging.alpha-1edtech.com"
33975
- };
33976
- ONEROSTER_ENDPOINTS = {
33977
- organizations: "/ims/oneroster/rostering/v1p2/orgs",
33978
- courses: "/ims/oneroster/rostering/v1p2/courses",
33979
- courseComponents: "/ims/oneroster/rostering/v1p2/courses/components",
33980
- resources: "/ims/oneroster/resources/v1p2/resources",
33981
- componentResources: "/ims/oneroster/rostering/v1p2/courses/component-resources",
33982
- classes: "/ims/oneroster/rostering/v1p2/classes",
33983
- enrollments: "/ims/oneroster/rostering/v1p2/enrollments",
33984
- assessmentLineItems: "/ims/oneroster/gradebook/v1p2/assessmentLineItems",
33985
- assessmentResults: "/ims/oneroster/gradebook/v1p2/assessmentResults",
33986
- users: "/ims/oneroster/rostering/v1p2/users"
33987
- };
33988
- QTI_ENDPOINTS = {
33989
- assessmentTests: "/assessment-tests",
33990
- assessmentItems: "/assessment-items"
33991
- };
33992
- CALIPER_ENDPOINTS = {
33993
- event: "/caliper/event",
33994
- events: "/caliper/events",
33995
- validate: "/caliper/event/validate"
33996
- };
33997
- CALIPER_CONSTANTS = {
33998
- context: "http://purl.imsglobal.org/ctx/caliper/v1p2",
33999
- profile: "TimebackProfile",
34000
- dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2"
34001
- };
34002
- TIMEBACK_EVENT_TYPES = {
34003
- activityEvent: "ActivityEvent",
34004
- timeSpentEvent: "TimeSpentEvent"
34005
- };
34006
- TIMEBACK_ACTIONS = {
34007
- completed: "Completed",
34008
- spentTime: "SpentTime"
34009
- };
34010
- TIMEBACK_TYPES = {
34011
- user: "TimebackUser",
34012
- activityContext: "TimebackActivityContext",
34013
- activityMetricsCollection: "TimebackActivityMetricsCollection",
34014
- timeSpentMetricsCollection: "TimebackTimeSpentMetricsCollection"
34015
- };
34016
- ACTIVITY_METRIC_TYPES = {
34017
- totalQuestions: "totalQuestions",
34018
- correctQuestions: "correctQuestions",
34019
- xpEarned: "xpEarned",
34020
- masteredUnits: "masteredUnits"
34021
- };
34022
- TIME_METRIC_TYPES = {
34023
- active: "active",
34024
- inactive: "inactive",
34025
- waste: "waste",
34026
- unknown: "unknown",
34027
- antiPattern: "anti-pattern"
34028
- };
34029
- TIMEBACK_SUBJECTS2 = [
34030
- "Math",
34031
- "FastMath",
34032
- "Science",
34033
- "Social Studies",
34034
- "Language",
34035
- "Reading",
34036
- "Vocabulary",
34037
- "Writing"
34038
- ];
34039
- TIMEBACK_GRADE_LEVELS = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
34040
- TIMEBACK_GRADE_LEVEL_LABELS = {
34041
- "-1": "pre-k",
34042
- "0": "kindergarten",
34043
- "1": "1st grade",
34044
- "2": "2nd grade",
34045
- "3": "3rd grade",
34046
- "4": "4th grade",
34047
- "5": "5th grade",
34048
- "6": "6th grade",
34049
- "7": "7th grade",
34050
- "8": "8th grade",
34051
- "9": "9th grade",
34052
- "10": "10th grade",
34053
- "11": "11th grade",
34054
- "12": "12th grade",
34055
- "13": "AP"
34056
- };
34057
- CALIPER_SUBJECTS = {
34058
- Reading: "Reading",
34059
- Language: "Language",
34060
- Vocabulary: "Vocabulary",
34061
- SocialStudies: "Social Studies",
34062
- Writing: "Writing",
34063
- Science: "Science",
34064
- FastMath: "FastMath",
34065
- Math: "Math",
34066
- None: "None"
34067
- };
34068
- ONEROSTER_STATUS = {
34069
- active: "active",
34070
- toBeDeleted: "tobedeleted"
34071
- };
34072
- SCORE_STATUS = {
34073
- exempt: "exempt",
34074
- fullyGraded: "fully graded",
34075
- notSubmitted: "not submitted",
34076
- partiallyGraded: "partially graded",
34077
- submitted: "submitted"
34078
- };
34079
- ENV_VARS = {
34080
- clientId: "TIMEBACK_CLIENT_ID",
34081
- clientSecret: "TIMEBACK_CLIENT_SECRET",
34082
- baseUrl: "TIMEBACK_BASE_URL",
34083
- environment: "TIMEBACK_ENVIRONMENT",
34084
- vendorResourceId: "TIMEBACK_VENDOR_RESOURCE_ID",
34085
- launchBaseUrl: "GAME_URL",
34086
- qtiClientId: "QTI_CLIENT_ID",
34087
- qtiClientSecret: "QTI_CLIENT_SECRET",
34088
- qtiAuthUrl: "QTI_AUTH_URL"
34089
- };
34090
- HTTP_DEFAULTS = {
34091
- timeout: 30000,
34092
- retries: 3,
34093
- retryBackoffBase: 2
34094
- };
34095
- AUTH_DEFAULTS = {
34096
- tokenCacheDuration: 50000
34097
- };
34098
- CACHE_DEFAULTS = {
34099
- defaultTTL: 10 * 60 * 1000,
34100
- defaultMaxSize: 500,
34101
- defaultName: "TimebackCache",
34102
- studentTTL: 10 * 60 * 1000,
34103
- studentMaxSize: 500,
34104
- assessmentTTL: 30 * 60 * 1000,
34105
- assessmentMaxSize: 200,
34106
- enrollmentTTL: 5 * 1000,
34107
- enrollmentMaxSize: 100
34108
- };
34109
- CONFIG_DEFAULTS = {
34110
- fileNames: ["timeback.config.js", "timeback.config.json"]
34111
- };
34112
- PLAYCADEMY_DEFAULTS = {
34113
- organization: TIMEBACK_ORG_SOURCED_ID,
34114
- launchBaseUrls: PLAYCADEMY_BASE_URLS
34115
- };
34116
- RESOURCE_DEFAULTS = {
34117
- organization: {
34118
- name: TIMEBACK_ORG_NAME,
34119
- type: TIMEBACK_ORG_TYPE
34120
- },
34121
- course: {
34122
- gradingScheme: TIMEBACK_COURSE_DEFAULTS.gradingScheme,
34123
- level: TIMEBACK_COURSE_DEFAULTS.level,
34124
- metadata: {
34125
- goals: TIMEBACK_COURSE_DEFAULTS.goals,
34126
- metrics: TIMEBACK_COURSE_DEFAULTS.metrics
34127
- }
34128
- },
34129
- component: TIMEBACK_COMPONENT_DEFAULTS,
34130
- resource: TIMEBACK_RESOURCE_DEFAULTS,
34131
- componentResource: TIMEBACK_COMPONENT_RESOURCE_DEFAULTS
34132
- };
34133
- HTTP_STATUS = {
34134
- CLIENT_ERROR_MIN: 400,
34135
- CLIENT_ERROR_MAX: 500,
34136
- SERVER_ERROR_MIN: 500
34137
- };
34138
- ERROR_NAMES = {
34139
- timebackAuth: "TimebackAuthError",
34140
- timebackApi: "TimebackApiError",
34141
- timebackConfig: "TimebackConfigError",
34142
- timebackSdk: "TimebackSDKError"
34143
- };
34144
- });
34145
- exports_verify = {};
34146
- __export2(exports_verify, {
34147
- verifyTimebackResources: () => verifyTimebackResources,
34148
- fetchTimebackConfig: () => fetchTimebackConfig
34149
- });
34150
- init_verify = __esm2(() => {
34151
- init_constants4();
34152
- });
34153
- init_constants4();
34154
- TimebackError = class TimebackError extends Error {
34155
- constructor(message) {
34156
- super(message);
34157
- this.name = ERROR_NAMES.timebackSdk;
34158
- }
34159
- };
34160
- TimebackApiError = class TimebackApiError extends Error {
34161
- status;
34162
- details;
34163
- constructor(status, message, details) {
34164
- super(`${status} ${message}`);
34165
- this.name = ERROR_NAMES.timebackApi;
34166
- this.status = status;
34167
- this.details = details;
34168
- Object.setPrototypeOf(this, TimebackApiError.prototype);
34169
- }
34170
- };
34171
- TimebackAuthenticationError = class TimebackAuthenticationError extends TimebackError {
34172
- constructor(message) {
34173
- super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
34174
- this.name = "TimebackAuthenticationError";
34175
- Object.setPrototypeOf(this, TimebackAuthenticationError.prototype);
34176
- }
34177
- };
34178
- StudentNotFoundError = class StudentNotFoundError extends TimebackError {
34179
- identifier;
34180
- identifierType;
34181
- constructor(identifier, identifierType = "email") {
34182
- super(`Student not found with ${identifierType}: ${identifier}. ` + `Ensure the student exists in OneRoster. ` + `If this is a new student, they must be created in OneRoster first.`);
34183
- this.name = "StudentNotFoundError";
34184
- this.identifier = identifier;
34185
- this.identifierType = identifierType;
34186
- Object.setPrototypeOf(this, StudentNotFoundError.prototype);
34187
- }
34188
- };
34189
- ConfigurationError = class ConfigurationError extends TimebackError {
34190
- field;
34191
- constructor(field, message) {
34192
- super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
34193
- this.name = "ConfigurationError";
34194
- this.field = field;
34195
- Object.setPrototypeOf(this, ConfigurationError.prototype);
34196
- }
34197
- };
34198
- ResourceNotFoundError = class ResourceNotFoundError extends TimebackError {
34199
- resourceType;
34200
- sourcedId;
34201
- constructor(resourceType, sourcedId) {
34202
- const message = sourcedId === "setup-not-run" ? `TimeBack resources have not been created yet. ` + `Please run 'bunx @playcademy/timeback setup' to create the required resources ` + `(organization, course, components, etc.) before recording progress.` : `${resourceType} with ID '${sourcedId}' not found`;
34203
- super(message);
34204
- this.name = "ResourceNotFoundError";
34205
- this.resourceType = resourceType;
34206
- this.sourcedId = sourcedId;
34207
- Object.setPrototypeOf(this, ResourceNotFoundError.prototype);
34208
- }
34209
- };
34210
- init_constants4();
34211
- SUBJECT_VALUES = TIMEBACK_SUBJECTS2;
34212
- GRADE_VALUES = TIMEBACK_GRADE_LEVELS;
34213
- init_verify();
34214
- init_constants4();
34215
- init_constants4();
34216
- if (process.env.DEBUG === "true") {
34217
- process.env.TERM = "dumb";
34218
- }
34219
- TimebackAuthError = class TimebackAuthError extends Error {
34220
- statusCode;
34221
- constructor(message, statusCode) {
34222
- super(message);
34223
- this.name = ERROR_NAMES.timebackAuth;
34224
- this.statusCode = statusCode;
34225
- }
34226
- };
34227
- init_constants4();
34228
- UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
34229
- storage = new AsyncLocalStorage;
34230
- init_constants4();
34231
- init_constants4();
34232
- init_constants4();
34233
- init_constants4();
34234
- init_constants4();
34235
- init_constants4();
34236
- init_constants4();
34237
- init_constants4();
34238
- EmailSchema = exports_external.string().email();
34239
- StudentSourcedIdSchema = exports_external.string().min(1, {
34240
- message: "Student sourcedId must be a non-empty string"
34241
- });
34242
- StudentIdentifierSchema = exports_external.union([EmailSchema, StudentSourcedIdSchema]);
34243
- });
34244
-
34245
- // ../timeback/dist/constants.js
34246
- var __esm3 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS2, QTI_API_URL2 = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS2, CALIPER_API_URLS2, ONEROSTER_ENDPOINTS2, QTI_ENDPOINTS2, CALIPER_ENDPOINTS2, CALIPER_CONSTANTS2, TIMEBACK_EVENT_TYPES2, TIMEBACK_ACTIONS2, TIMEBACK_TYPES2, ACTIVITY_METRIC_TYPES2, TIME_METRIC_TYPES2, TIMEBACK_SUBJECTS3, TIMEBACK_GRADE_LEVELS2, TIMEBACK_GRADE_LEVEL_LABELS2, CALIPER_SUBJECTS2, ONEROSTER_STATUS2, SCORE_STATUS2, ENV_VARS2, HTTP_DEFAULTS2, AUTH_DEFAULTS2, CACHE_DEFAULTS2, CONFIG_DEFAULTS2, PLAYCADEMY_DEFAULTS2, RESOURCE_DEFAULTS2, HTTP_STATUS2, ERROR_NAMES2, init_constants6;
34247
- var init_constants5 = __esm(() => {
34248
- init_src();
34249
- init_constants6 = __esm3(() => {
34550
+ init_constants5 = __esm3(() => {
34250
34551
  TIMEBACK_API_URLS2 = {
34251
34552
  production: "https://api.alpha-1edtech.ai",
34252
34553
  staging: "https://api.staging.alpha-1edtech.com"
@@ -34428,36 +34729,153 @@ var init_constants5 = __esm(() => {
34428
34729
  timebackSdk: "TimebackSDKError"
34429
34730
  };
34430
34731
  });
34431
- init_constants6();
34732
+ init_errors4 = __esm3(() => {
34733
+ init_constants5();
34734
+ TimebackError = class TimebackError2 extends Error {
34735
+ constructor(message) {
34736
+ super(message);
34737
+ this.name = ERROR_NAMES2.timebackSdk;
34738
+ }
34739
+ };
34740
+ TimebackApiError = class TimebackApiError2 extends Error {
34741
+ status;
34742
+ details;
34743
+ constructor(status, message, details) {
34744
+ super(`${status} ${message}`);
34745
+ this.name = ERROR_NAMES2.timebackApi;
34746
+ this.status = status;
34747
+ this.details = details;
34748
+ Object.setPrototypeOf(this, TimebackApiError2.prototype);
34749
+ }
34750
+ };
34751
+ TimebackAuthenticationError = class TimebackAuthenticationError2 extends TimebackError {
34752
+ constructor(message) {
34753
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
34754
+ this.name = "TimebackAuthenticationError";
34755
+ Object.setPrototypeOf(this, TimebackAuthenticationError2.prototype);
34756
+ }
34757
+ };
34758
+ StudentNotFoundError = class StudentNotFoundError2 extends TimebackError {
34759
+ identifier;
34760
+ identifierType;
34761
+ constructor(identifier, identifierType = "email") {
34762
+ super(`Student not found with ${identifierType}: ${identifier}. ` + `Ensure the student exists in OneRoster. ` + `If this is a new student, they must be created in OneRoster first.`);
34763
+ this.name = "StudentNotFoundError";
34764
+ this.identifier = identifier;
34765
+ this.identifierType = identifierType;
34766
+ Object.setPrototypeOf(this, StudentNotFoundError2.prototype);
34767
+ }
34768
+ };
34769
+ ConfigurationError = class ConfigurationError2 extends TimebackError {
34770
+ field;
34771
+ constructor(field, message) {
34772
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
34773
+ this.name = "ConfigurationError";
34774
+ this.field = field;
34775
+ Object.setPrototypeOf(this, ConfigurationError2.prototype);
34776
+ }
34777
+ };
34778
+ ResourceAlreadyExistsError = class ResourceAlreadyExistsError2 extends TimebackError {
34779
+ resourceType;
34780
+ sourcedId;
34781
+ originalError;
34782
+ constructor(resourceType, sourcedId, originalError) {
34783
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
34784
+ this.name = "ResourceAlreadyExistsError";
34785
+ this.resourceType = resourceType;
34786
+ this.sourcedId = sourcedId;
34787
+ this.originalError = originalError;
34788
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError2.prototype);
34789
+ }
34790
+ };
34791
+ ResourceNotFoundError = class ResourceNotFoundError2 extends TimebackError {
34792
+ resourceType;
34793
+ sourcedId;
34794
+ constructor(resourceType, sourcedId) {
34795
+ const message = sourcedId === "setup-not-run" ? `TimeBack resources have not been created yet. ` + `Please run 'bunx @playcademy/timeback setup' to create the required resources ` + `(organization, course, components, etc.) before recording progress.` : `${resourceType} with ID '${sourcedId}' not found`;
34796
+ super(message);
34797
+ this.name = "ResourceNotFoundError";
34798
+ this.resourceType = resourceType;
34799
+ this.sourcedId = sourcedId;
34800
+ Object.setPrototypeOf(this, ResourceNotFoundError2.prototype);
34801
+ }
34802
+ };
34803
+ });
34804
+ init_ids = __esm3(() => {
34805
+ init_errors4();
34806
+ UUID_REGEX2 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
34807
+ });
34808
+ exports_verify = {};
34809
+ __export2(exports_verify, {
34810
+ verifyTimebackResources: () => verifyTimebackResources,
34811
+ fetchTimebackConfig: () => fetchTimebackConfig
34812
+ });
34813
+ init_verify = __esm3(() => {
34814
+ init_constants5();
34815
+ init_ids();
34816
+ });
34817
+ init_constants5();
34818
+ SUBJECT_VALUES2 = TIMEBACK_SUBJECTS3;
34819
+ GRADE_VALUES2 = TIMEBACK_GRADE_LEVELS2;
34820
+ init_ids();
34821
+ init_ids();
34822
+ init_verify();
34823
+ init_ids();
34824
+ init_constants5();
34825
+ init_errors4();
34826
+ init_constants5();
34827
+ if (process.env.DEBUG === "true") {
34828
+ process.env.TERM = "dumb";
34829
+ }
34830
+ TimebackAuthError = class TimebackAuthError extends Error {
34831
+ statusCode;
34832
+ constructor(message, statusCode) {
34833
+ super(message);
34834
+ this.name = ERROR_NAMES2.timebackAuth;
34835
+ this.statusCode = statusCode;
34836
+ }
34837
+ };
34838
+ init_ids();
34839
+ init_constants5();
34840
+ init_errors4();
34841
+ UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
34842
+ storage = new AsyncLocalStorage;
34843
+ init_constants5();
34844
+ init_constants5();
34845
+ init_errors4();
34846
+ init_constants5();
34847
+ init_constants5();
34848
+ init_constants5();
34849
+ init_constants5();
34850
+ init_constants5();
34851
+ init_ids();
34852
+ init_ids();
34853
+ init_errors4();
34854
+ init_ids();
34855
+ init_errors4();
34856
+ EmailSchema = exports_external.string().email();
34857
+ StudentSourcedIdSchema = exports_external.string().min(1, {
34858
+ message: "Student sourcedId must be a non-empty string"
34859
+ });
34860
+ StudentIdentifierSchema = exports_external.union([EmailSchema, StudentSourcedIdSchema]);
34861
+ init_ids();
34432
34862
  });
34433
34863
 
34434
- // ../timeback/dist/types.js
34435
- function isObject2(value) {
34436
- return typeof value === "object" && value !== null;
34437
- }
34438
- function isCourseMetadata(value) {
34439
- return isObject2(value);
34440
- }
34441
- function isResourceMetadata(value) {
34442
- return isObject2(value);
34443
- }
34444
- function isPlaycademyResourceMetadata2(value) {
34445
- if (!isObject2(value)) {
34446
- return false;
34864
+ // ../timeback/dist/constants.js
34865
+ function deriveTimebackCourseLevelFromGrade(grade) {
34866
+ if (grade === 13) {
34867
+ return TIMEBACK_COURSE_DEFAULTS.level.ap;
34447
34868
  }
34448
- if (!("mastery" in value) || value.mastery === undefined) {
34449
- return true;
34869
+ if (grade <= 5) {
34870
+ return TIMEBACK_COURSE_DEFAULTS.level.elementary;
34450
34871
  }
34451
- return isObject2(value.mastery);
34452
- }
34453
- function isTimebackSubject3(value) {
34454
- return typeof value === "string" && SUBJECT_VALUES2.includes(value);
34455
- }
34456
- function isTimebackGrade3(value) {
34457
- return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES2.includes(value);
34872
+ if (grade <= 8) {
34873
+ return TIMEBACK_COURSE_DEFAULTS.level.middle;
34874
+ }
34875
+ return TIMEBACK_COURSE_DEFAULTS.level.high;
34458
34876
  }
34459
- var __esm4 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS3, TIMEBACK_AUTH_URLS3, CALIPER_API_URLS3, ONEROSTER_ENDPOINTS3, QTI_ENDPOINTS3, CALIPER_ENDPOINTS3, CALIPER_CONSTANTS3, TIMEBACK_EVENT_TYPES3, TIMEBACK_ACTIONS3, TIMEBACK_TYPES3, ACTIVITY_METRIC_TYPES3, TIME_METRIC_TYPES3, TIMEBACK_SUBJECTS4, TIMEBACK_GRADE_LEVELS3, TIMEBACK_GRADE_LEVEL_LABELS3, CALIPER_SUBJECTS3, ONEROSTER_STATUS3, SCORE_STATUS3, ENV_VARS3, HTTP_DEFAULTS3, AUTH_DEFAULTS3, CACHE_DEFAULTS3, CONFIG_DEFAULTS3, PLAYCADEMY_DEFAULTS3, RESOURCE_DEFAULTS3, HTTP_STATUS3, ERROR_NAMES3, init_constants7, SUBJECT_VALUES2, GRADE_VALUES2;
34460
- var init_types3 = __esm(() => {
34877
+ var __esm4 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS3, QTI_API_URL2 = "https://qti.alpha-1edtech.ai/api", TIMEBACK_AUTH_URLS3, CALIPER_API_URLS3, ONEROSTER_ENDPOINTS3, QTI_ENDPOINTS3, CALIPER_ENDPOINTS3, CALIPER_CONSTANTS3, TIMEBACK_EVENT_TYPES3, TIMEBACK_ACTIONS3, TIMEBACK_TYPES3, ACTIVITY_METRIC_TYPES3, TIME_METRIC_TYPES3, TIMEBACK_SUBJECTS4, TIMEBACK_GRADE_LEVELS3, TIMEBACK_GRADE_LEVEL_LABELS3, CALIPER_SUBJECTS3, ONEROSTER_STATUS3, SCORE_STATUS3, ENV_VARS3, HTTP_DEFAULTS3, AUTH_DEFAULTS3, CACHE_DEFAULTS3, CONFIG_DEFAULTS3, PLAYCADEMY_DEFAULTS3, RESOURCE_DEFAULTS3, HTTP_STATUS3, ERROR_NAMES3, init_constants7;
34878
+ var init_constants6 = __esm(() => {
34461
34879
  init_src();
34462
34880
  init_constants7 = __esm4(() => {
34463
34881
  TIMEBACK_API_URLS3 = {
@@ -34642,8 +35060,6 @@ var init_types3 = __esm(() => {
34642
35060
  };
34643
35061
  });
34644
35062
  init_constants7();
34645
- SUBJECT_VALUES2 = TIMEBACK_SUBJECTS4;
34646
- GRADE_VALUES2 = TIMEBACK_GRADE_LEVELS3;
34647
35063
  });
34648
35064
 
34649
35065
  // ../timeback/dist/utils.js
@@ -34665,7 +35081,7 @@ function deriveAssessmentBankIds(courseId) {
34665
35081
  function escapeFilterValue2(value) {
34666
35082
  return value.replaceAll("'", String.raw`\'`);
34667
35083
  }
34668
- var __esm5 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS4, TIMEBACK_AUTH_URLS4, CALIPER_API_URLS4, ONEROSTER_ENDPOINTS4, QTI_ENDPOINTS4, CALIPER_ENDPOINTS4, CALIPER_CONSTANTS4, TIMEBACK_EVENT_TYPES4, TIMEBACK_ACTIONS4, TIMEBACK_TYPES4, ACTIVITY_METRIC_TYPES4, TIME_METRIC_TYPES4, TIMEBACK_SUBJECTS5, TIMEBACK_GRADE_LEVELS4, TIMEBACK_GRADE_LEVEL_LABELS4, CALIPER_SUBJECTS4, ONEROSTER_STATUS4, SCORE_STATUS4, ENV_VARS4, HTTP_DEFAULTS4, AUTH_DEFAULTS4, CACHE_DEFAULTS4, CONFIG_DEFAULTS4, PLAYCADEMY_DEFAULTS4, RESOURCE_DEFAULTS4, HTTP_STATUS4, ERROR_NAMES4, init_constants8;
35084
+ var __esm5 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS4, TIMEBACK_AUTH_URLS4, CALIPER_API_URLS4, ONEROSTER_ENDPOINTS4, QTI_ENDPOINTS4, CALIPER_ENDPOINTS4, CALIPER_CONSTANTS4, TIMEBACK_EVENT_TYPES4, TIMEBACK_ACTIONS4, TIMEBACK_TYPES4, ACTIVITY_METRIC_TYPES4, TIME_METRIC_TYPES4, TIMEBACK_SUBJECTS5, TIMEBACK_GRADE_LEVELS4, TIMEBACK_GRADE_LEVEL_LABELS4, CALIPER_SUBJECTS4, ONEROSTER_STATUS4, SCORE_STATUS4, ENV_VARS4, HTTP_DEFAULTS4, AUTH_DEFAULTS4, CACHE_DEFAULTS4, CONFIG_DEFAULTS4, PLAYCADEMY_DEFAULTS4, RESOURCE_DEFAULTS4, HTTP_STATUS4, ERROR_NAMES4, init_constants8, TimebackError2, TimebackApiError2, TimebackAuthenticationError2, StudentNotFoundError2, ConfigurationError2, ResourceAlreadyExistsError2, ResourceNotFoundError2, init_errors5, UUID_REGEX3, init_ids2;
34669
35085
  var init_utils6 = __esm(() => {
34670
35086
  init_src();
34671
35087
  init_constants8 = __esm5(() => {
@@ -34850,6 +35266,82 @@ var init_utils6 = __esm(() => {
34850
35266
  timebackSdk: "TimebackSDKError"
34851
35267
  };
34852
35268
  });
35269
+ init_errors5 = __esm5(() => {
35270
+ init_constants8();
35271
+ TimebackError2 = class TimebackError3 extends Error {
35272
+ constructor(message) {
35273
+ super(message);
35274
+ this.name = ERROR_NAMES4.timebackSdk;
35275
+ }
35276
+ };
35277
+ TimebackApiError2 = class TimebackApiError3 extends Error {
35278
+ status;
35279
+ details;
35280
+ constructor(status, message, details) {
35281
+ super(`${status} ${message}`);
35282
+ this.name = ERROR_NAMES4.timebackApi;
35283
+ this.status = status;
35284
+ this.details = details;
35285
+ Object.setPrototypeOf(this, TimebackApiError3.prototype);
35286
+ }
35287
+ };
35288
+ TimebackAuthenticationError2 = class TimebackAuthenticationError3 extends TimebackError2 {
35289
+ constructor(message) {
35290
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
35291
+ this.name = "TimebackAuthenticationError";
35292
+ Object.setPrototypeOf(this, TimebackAuthenticationError3.prototype);
35293
+ }
35294
+ };
35295
+ StudentNotFoundError2 = class StudentNotFoundError3 extends TimebackError2 {
35296
+ identifier;
35297
+ identifierType;
35298
+ constructor(identifier, identifierType = "email") {
35299
+ super(`Student not found with ${identifierType}: ${identifier}. ` + `Ensure the student exists in OneRoster. ` + `If this is a new student, they must be created in OneRoster first.`);
35300
+ this.name = "StudentNotFoundError";
35301
+ this.identifier = identifier;
35302
+ this.identifierType = identifierType;
35303
+ Object.setPrototypeOf(this, StudentNotFoundError3.prototype);
35304
+ }
35305
+ };
35306
+ ConfigurationError2 = class ConfigurationError3 extends TimebackError2 {
35307
+ field;
35308
+ constructor(field, message) {
35309
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
35310
+ this.name = "ConfigurationError";
35311
+ this.field = field;
35312
+ Object.setPrototypeOf(this, ConfigurationError3.prototype);
35313
+ }
35314
+ };
35315
+ ResourceAlreadyExistsError2 = class ResourceAlreadyExistsError3 extends TimebackError2 {
35316
+ resourceType;
35317
+ sourcedId;
35318
+ originalError;
35319
+ constructor(resourceType, sourcedId, originalError) {
35320
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
35321
+ this.name = "ResourceAlreadyExistsError";
35322
+ this.resourceType = resourceType;
35323
+ this.sourcedId = sourcedId;
35324
+ this.originalError = originalError;
35325
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError3.prototype);
35326
+ }
35327
+ };
35328
+ ResourceNotFoundError2 = class ResourceNotFoundError3 extends TimebackError2 {
35329
+ resourceType;
35330
+ sourcedId;
35331
+ constructor(resourceType, sourcedId) {
35332
+ const message = sourcedId === "setup-not-run" ? `TimeBack resources have not been created yet. ` + `Please run 'bunx @playcademy/timeback setup' to create the required resources ` + `(organization, course, components, etc.) before recording progress.` : `${resourceType} with ID '${sourcedId}' not found`;
35333
+ super(message);
35334
+ this.name = "ResourceNotFoundError";
35335
+ this.resourceType = resourceType;
35336
+ this.sourcedId = sourcedId;
35337
+ Object.setPrototypeOf(this, ResourceNotFoundError3.prototype);
35338
+ }
35339
+ };
35340
+ });
35341
+ init_ids2 = __esm5(() => {
35342
+ init_errors5();
35343
+ UUID_REGEX3 = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
35344
+ });
34853
35345
  init_constants8();
34854
35346
  init_constants8();
34855
35347
  if (process.env.DEBUG === "true") {
@@ -35012,333 +35504,6 @@ var init_timeback_admin_util = __esm(() => {
35012
35504
  init_errors();
35013
35505
  });
35014
35506
 
35015
- // ../api-core/src/utils/timeback.util.ts
35016
- function isRecord2(value) {
35017
- return typeof value === "object" && value !== null;
35018
- }
35019
- function filterEnrollmentsByGame(enrollments, gameId) {
35020
- return enrollments.filter((enrollment) => enrollment.gameId === gameId).map(({ gameId: _, ...enrollment }) => enrollment);
35021
- }
35022
- function mapEnrollmentsToUserEnrollments(enrollments, integrations) {
35023
- const enrollmentByCourse = new Map(enrollments.map((enrollment) => [enrollment.courseId, enrollment]));
35024
- const courseToSchool = new Map(enrollments.filter((enrollment) => enrollment.school?.id).map((enrollment) => [enrollment.courseId, enrollment.school.id]));
35025
- return integrations.map((integration) => {
35026
- const enrollment = enrollmentByCourse.get(integration.courseId);
35027
- return {
35028
- gameId: integration.gameId,
35029
- grade: integration.grade,
35030
- subject: integration.subject,
35031
- courseId: integration.courseId,
35032
- orgId: courseToSchool.get(integration.courseId),
35033
- ...enrollment ? { id: enrollment.sourcedId } : {}
35034
- };
35035
- });
35036
- }
35037
- function getStringValue(value) {
35038
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
35039
- }
35040
- function parseSourcedIdFromUrl(url2) {
35041
- if (!url2) {
35042
- return;
35043
- }
35044
- const trimmed = url2.trim().replace(/\/$/, "");
35045
- if (!trimmed) {
35046
- return;
35047
- }
35048
- const segments = trimmed.split("/");
35049
- const lastSegment = segments.at(-1);
35050
- return lastSegment ? decodeURIComponent(lastSegment) : undefined;
35051
- }
35052
- function getGeneratedMetricValue(event, type) {
35053
- const items = event.generated?.items;
35054
- if (!Array.isArray(items)) {
35055
- return;
35056
- }
35057
- const metric = items.find((item) => item?.type === type);
35058
- if (!metric) {
35059
- return;
35060
- }
35061
- const value = typeof metric.value === "number" ? metric.value : Number(metric.value);
35062
- return Number.isFinite(value) ? value : undefined;
35063
- }
35064
- function getMergedCaliperExtensions(event) {
35065
- const objectActivityExtensions = isRecord2(event.object.activity?.extensions) ? event.object.activity.extensions : undefined;
35066
- const generatedExtensions = isRecord2(event.generated?.extensions) ? event.generated.extensions : undefined;
35067
- const eventExtensions = isRecord2(event.extensions) ? event.extensions : undefined;
35068
- return {
35069
- ...objectActivityExtensions,
35070
- ...generatedExtensions,
35071
- ...eventExtensions
35072
- };
35073
- }
35074
- function getPlaycademyMetadata(event) {
35075
- const extensions = getMergedCaliperExtensions(event);
35076
- return isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
35077
- }
35078
- function getActivityId(event, playcademy) {
35079
- const metadataActivityId = getStringValue(playcademy?.activityId);
35080
- if (metadataActivityId) {
35081
- return metadataActivityId;
35082
- }
35083
- const activityId = getStringValue(event.object.activity?.id);
35084
- if (activityId) {
35085
- return activityId;
35086
- }
35087
- const objectId = getStringValue(event.object.id);
35088
- if (!objectId) {
35089
- return;
35090
- }
35091
- const trimmed = objectId.replace(/\/$/, "");
35092
- const segments = trimmed.split("/");
35093
- const activityIndex = segments.lastIndexOf("activities");
35094
- if (activityIndex !== -1 && segments.length >= activityIndex + 3) {
35095
- const candidate = segments[activityIndex + 2];
35096
- return candidate ? decodeURIComponent(candidate) : undefined;
35097
- }
35098
- return;
35099
- }
35100
- function buildResourceMetadata({
35101
- baseMetadata,
35102
- subject,
35103
- grade,
35104
- totalXp,
35105
- masterableUnits
35106
- }) {
35107
- const normalizedBaseMetadata = isResourceMetadata(baseMetadata) ? baseMetadata : undefined;
35108
- const metadata2 = {
35109
- ...normalizedBaseMetadata
35110
- };
35111
- metadata2.subject = subject;
35112
- metadata2.grades = [grade];
35113
- metadata2.xp = totalXp;
35114
- if (masterableUnits !== undefined && masterableUnits !== null) {
35115
- const existingPlaycademy = isPlaycademyResourceMetadata2(metadata2.playcademy) ? metadata2.playcademy : undefined;
35116
- metadata2.playcademy = {
35117
- ...existingPlaycademy,
35118
- mastery: {
35119
- ...existingPlaycademy?.mastery,
35120
- masterableUnits
35121
- }
35122
- };
35123
- }
35124
- return metadata2;
35125
- }
35126
- function getDurationSecondsFromExtensions(event) {
35127
- const extensions = getMergedCaliperExtensions(event);
35128
- const playcademy = isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
35129
- const rawValue = extensions.durationSeconds ?? playcademy?.durationSeconds;
35130
- const value = typeof rawValue === "number" ? rawValue : Number(rawValue);
35131
- return Number.isFinite(value) ? value : undefined;
35132
- }
35133
- function getCanonicalRunId(session2) {
35134
- const sessionId = getStringValue(session2?.id);
35135
- if (!sessionId) {
35136
- return;
35137
- }
35138
- return sessionId.replace(/^urn:uuid:/, "");
35139
- }
35140
- function getResumeId(event) {
35141
- const playcademy = getPlaycademyMetadata(event);
35142
- return getStringValue(playcademy?.resumeId);
35143
- }
35144
- function isCaliperRemediationOrCompletionEvent(event) {
35145
- const playcademy = getPlaycademyMetadata(event);
35146
- return REMEDIATION_OR_COMPLETION_EVENT_KINDS.has(getStringValue(playcademy?.eventKind) || "");
35147
- }
35148
- function groupCaliperEventsByRun(events) {
35149
- const groups = new Map;
35150
- for (const event of events) {
35151
- const objectId = getStringValue(event.object.id) || "unknown-activity";
35152
- const groupKey = `${objectId}::${getStringValue(event.session?.id) || event.externalId}`;
35153
- const existing = groups.get(groupKey);
35154
- if (existing) {
35155
- existing.push(event);
35156
- } else {
35157
- groups.set(groupKey, [event]);
35158
- }
35159
- }
35160
- return groups;
35161
- }
35162
- function findCaliperEventGroupContainingExternalId(events, externalId) {
35163
- const targetExternalId = externalId.trim();
35164
- if (!targetExternalId) {
35165
- return;
35166
- }
35167
- return [...groupCaliperEventsByRun(events).values()].find((group) => group.some((event) => event.externalId === targetExternalId));
35168
- }
35169
- function mapCaliperEventGroupToActivity(events, relevantCourseIds) {
35170
- if (events.length === 0) {
35171
- return null;
35172
- }
35173
- const sortedEvents = events.toSorted((a, b) => a.eventTime.localeCompare(b.eventTime));
35174
- const activityEvent = [...sortedEvents].toReversed().find((event) => event.type === "ActivityEvent");
35175
- const contextSource = activityEvent || sortedEvents.at(-1);
35176
- if (!contextSource) {
35177
- return null;
35178
- }
35179
- const ctx = parseCaliperEventContext(contextSource, relevantCourseIds);
35180
- if (!ctx) {
35181
- return null;
35182
- }
35183
- const score = activityEvent !== undefined ? (() => {
35184
- const totalQuestions = getGeneratedMetricValue(activityEvent, "totalQuestions");
35185
- const correctQuestions = getGeneratedMetricValue(activityEvent, "correctQuestions");
35186
- if (totalQuestions === undefined || correctQuestions === undefined || totalQuestions <= 0) {
35187
- return;
35188
- }
35189
- return correctQuestions / totalQuestions * 100;
35190
- })() : undefined;
35191
- const xpEarned = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "xpEarned") : undefined;
35192
- const masteredUnits = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "masteredUnits") : undefined;
35193
- const timeSpentEvents = sortedEvents.filter((event) => event.type === "TimeSpentEvent");
35194
- let totalActiveTimeSeconds;
35195
- if (timeSpentEvents.length > 0) {
35196
- totalActiveTimeSeconds = timeSpentEvents.reduce((sum, event) => sum + (getGeneratedMetricValue(event, "active") ?? 0), 0);
35197
- } else if (activityEvent !== undefined) {
35198
- totalActiveTimeSeconds = getDurationSecondsFromExtensions(activityEvent);
35199
- }
35200
- const fallbackActivityId = getActivityId(contextSource, getPlaycademyMetadata(contextSource));
35201
- const occurredAt = getStringValue(activityEvent?.eventTime) || getStringValue(sortedEvents.at(-1)?.eventTime);
35202
- const runId = getCanonicalRunId(contextSource.session);
35203
- const resumeIds = new Set(sortedEvents.map((event) => getResumeId(event)).filter((resumeId) => resumeId !== undefined));
35204
- const sessionCount = resumeIds.size > 0 ? resumeIds.size : 1;
35205
- const kind = activityEvent !== undefined ? "activity" : "activity-in-progress";
35206
- if (!occurredAt) {
35207
- return null;
35208
- }
35209
- return {
35210
- id: activityEvent?.externalId || sortedEvents.at(-1)?.externalId || events[0].externalId,
35211
- kind,
35212
- occurredAt,
35213
- courseId: ctx.courseId,
35214
- title: getStringValue(activityEvent?.object.activity?.name) || ctx.titleFromEvent || (fallbackActivityId ? kebabToTitleCase(fallbackActivityId) : "Activity completed"),
35215
- ...ctx.activityId ? { activityId: ctx.activityId } : {},
35216
- ...ctx.appName ? { appName: ctx.appName } : {},
35217
- ...score !== undefined ? { score } : {},
35218
- ...xpEarned !== undefined ? { xpDelta: xpEarned } : {},
35219
- ...masteredUnits !== undefined ? { masteredUnitsDelta: masteredUnits } : {},
35220
- ...totalActiveTimeSeconds !== undefined ? { timeDeltaSeconds: totalActiveTimeSeconds } : {},
35221
- ...runId ? { runId } : {},
35222
- ...sessionCount > 0 ? { sessionCount } : {}
35223
- };
35224
- }
35225
- function parseCaliperEventContext(event, relevantCourseIds) {
35226
- const playcademy = getPlaycademyMetadata(event);
35227
- const courseId = getStringValue(playcademy?.courseId) || parseSourcedIdFromUrl(event.object.course?.id);
35228
- if (!courseId || !relevantCourseIds.has(courseId)) {
35229
- return null;
35230
- }
35231
- const occurredAt = getStringValue(event.eventTime);
35232
- if (!occurredAt) {
35233
- return null;
35234
- }
35235
- return {
35236
- courseId,
35237
- occurredAt,
35238
- eventKind: getStringValue(playcademy?.eventKind),
35239
- source: getStringValue(playcademy?.source),
35240
- reason: getStringValue(playcademy?.reason),
35241
- titleFromEvent: getStringValue(event.object.activity?.name),
35242
- appName: getStringValue(event.object.app?.name),
35243
- activityId: getActivityId(event, playcademy)
35244
- };
35245
- }
35246
- function mapTimeSpentRemediation(event, ctx) {
35247
- if (ctx.eventKind !== "remediation-time") {
35248
- return null;
35249
- }
35250
- return {
35251
- id: event.externalId,
35252
- kind: "remediation-time",
35253
- occurredAt: ctx.occurredAt,
35254
- courseId: ctx.courseId,
35255
- title: "Time Adjustment",
35256
- activityId: ctx.activityId,
35257
- appName: ctx.appName,
35258
- reason: ctx.reason,
35259
- timeDeltaSeconds: getGeneratedMetricValue(event, "active")
35260
- };
35261
- }
35262
- function mapActivityRemediation(event, ctx) {
35263
- if (ctx.eventKind === "remediation-xp") {
35264
- return {
35265
- id: event.externalId,
35266
- kind: "remediation-xp",
35267
- occurredAt: ctx.occurredAt,
35268
- courseId: ctx.courseId,
35269
- title: "XP Adjustment",
35270
- activityId: ctx.activityId,
35271
- appName: ctx.appName,
35272
- reason: ctx.reason,
35273
- xpDelta: getGeneratedMetricValue(event, "xpEarned"),
35274
- masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
35275
- };
35276
- }
35277
- if (ctx.eventKind === "remediation-mastery") {
35278
- return {
35279
- id: event.externalId,
35280
- kind: "remediation-mastery",
35281
- occurredAt: ctx.occurredAt,
35282
- courseId: ctx.courseId,
35283
- title: "Mastery Adjustment",
35284
- activityId: ctx.activityId,
35285
- appName: ctx.appName,
35286
- reason: ctx.reason,
35287
- xpDelta: getGeneratedMetricValue(event, "xpEarned"),
35288
- masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
35289
- };
35290
- }
35291
- if (ctx.eventKind === "course-completed") {
35292
- return {
35293
- id: event.externalId,
35294
- kind: "course-completed",
35295
- occurredAt: ctx.occurredAt,
35296
- courseId: ctx.courseId,
35297
- title: ctx.source === "admin" ? "Course marked complete" : "Course completed",
35298
- activityId: ctx.activityId,
35299
- appName: ctx.appName,
35300
- reason: ctx.reason
35301
- };
35302
- }
35303
- if (ctx.eventKind === "course-resumed") {
35304
- return {
35305
- id: event.externalId,
35306
- kind: "course-resumed",
35307
- occurredAt: ctx.occurredAt,
35308
- courseId: ctx.courseId,
35309
- title: "Course resumed",
35310
- activityId: ctx.activityId,
35311
- appName: ctx.appName,
35312
- reason: ctx.reason
35313
- };
35314
- }
35315
- return null;
35316
- }
35317
- function mapCaliperEventToRemediationActivity(event, relevantCourseIds) {
35318
- const ctx = parseCaliperEventContext(event, relevantCourseIds);
35319
- if (!ctx) {
35320
- return null;
35321
- }
35322
- if (event.type === "TimeSpentEvent") {
35323
- return mapTimeSpentRemediation(event, ctx);
35324
- }
35325
- if (event.type === "ActivityEvent") {
35326
- return mapActivityRemediation(event, ctx);
35327
- }
35328
- return null;
35329
- }
35330
- var REMEDIATION_OR_COMPLETION_EVENT_KINDS;
35331
- var init_timeback_util = __esm(() => {
35332
- init_types3();
35333
- REMEDIATION_OR_COMPLETION_EVENT_KINDS = new Set([
35334
- "remediation-xp",
35335
- "remediation-time",
35336
- "remediation-mastery",
35337
- "course-completed",
35338
- "course-resumed"
35339
- ]);
35340
- });
35341
-
35342
35507
  // ../api-core/src/utils/timeback-discrepancy-queue.util.ts
35343
35508
  function parseDateInputParts(value) {
35344
35509
  const parts2 = value.split("-");
@@ -35712,7 +35877,7 @@ function isAllowedGradeLevelTestType(value) {
35712
35877
  }
35713
35878
  function isQualifyingGradeLevelTestResult(result, options) {
35714
35879
  const metadata2 = metadataOf(result);
35715
- return sourceIdFromRef(result.student) === options.studentId && normalizeText(result.status) === "active" && result.scoreStatus === SCORE_STATUS2.fullyGraded && normalizeText(metadata2.resultType) === "assessment" && stringField(metadata2.subject).trim() === options.subject && isAllowedGradeLevelTestType(metadata2.testType);
35880
+ return sourceIdFromRef(result.student) === options.studentId && normalizeText(result.status) === "active" && result.scoreStatus === SCORE_STATUS3.fullyGraded && normalizeText(metadata2.resultType) === "assessment" && stringField(metadata2.subject).trim() === options.subject && isAllowedGradeLevelTestType(metadata2.testType);
35716
35881
  }
35717
35882
  function mapGradeLevelTestSummary(result, options) {
35718
35883
  if (!isQualifyingGradeLevelTestResult(result, options)) {
@@ -35972,7 +36137,7 @@ function latestAssessmentResultsByLineItem(results) {
35972
36137
  const latestResultsByLineItem = new Map;
35973
36138
  for (const result of results) {
35974
36139
  const lineItemId = sourceIdFromRef(result.assessmentLineItem);
35975
- if (lineItemId && !latestResultsByLineItem.has(lineItemId) && result.scoreStatus === SCORE_STATUS2.fullyGraded) {
36140
+ if (lineItemId && !latestResultsByLineItem.has(lineItemId) && result.scoreStatus === SCORE_STATUS3.fullyGraded) {
35976
36141
  latestResultsByLineItem.set(lineItemId, result);
35977
36142
  }
35978
36143
  }
@@ -36072,7 +36237,7 @@ function qtiIdCandidates(parentLineItem, resource) {
36072
36237
  }
36073
36238
  var GRADE_LEVEL_TEST_TYPES, naturalTitleSort;
36074
36239
  var init_timeback_grade_level_results_util = __esm(() => {
36075
- init_constants5();
36240
+ init_constants6();
36076
36241
  init_utils6();
36077
36242
  GRADE_LEVEL_TEST_TYPES = [
36078
36243
  "placement",
@@ -36097,18 +36262,18 @@ async function upsertMasteryCompletionEntry(params) {
36097
36262
  await client.oneroster.assessmentLineItems.findOrCreate(lineItemId, {
36098
36263
  sourcedId: lineItemId,
36099
36264
  title: "Mastery Completion",
36100
- status: ONEROSTER_STATUS2.active,
36265
+ status: ONEROSTER_STATUS3.active,
36101
36266
  course: { sourcedId: ids.course },
36102
36267
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
36103
36268
  });
36104
36269
  await client.oneroster.assessmentResults.upsert(resultId, {
36105
36270
  sourcedId: resultId,
36106
- status: ONEROSTER_STATUS2.active,
36271
+ status: ONEROSTER_STATUS3.active,
36107
36272
  assessmentLineItem: { sourcedId: lineItemId },
36108
36273
  student: { sourcedId: studentId },
36109
36274
  score: 100,
36110
36275
  scoreDate: new Date().toISOString(),
36111
- scoreStatus: SCORE_STATUS2.fullyGraded,
36276
+ scoreStatus: SCORE_STATUS3.fullyGraded,
36112
36277
  inProgress: "false",
36113
36278
  metadata: {
36114
36279
  isMasteryCompletion: true,
@@ -36120,12 +36285,12 @@ async function upsertMasteryCompletionEntry(params) {
36120
36285
  try {
36121
36286
  await client.oneroster.assessmentResults.upsert(resultId, {
36122
36287
  sourcedId: resultId,
36123
- status: ONEROSTER_STATUS2.active,
36288
+ status: ONEROSTER_STATUS3.active,
36124
36289
  assessmentLineItem: { sourcedId: lineItemId },
36125
36290
  student: { sourcedId: studentId },
36126
36291
  score: 0,
36127
36292
  scoreDate: new Date().toISOString(),
36128
- scoreStatus: SCORE_STATUS2.notSubmitted,
36293
+ scoreStatus: SCORE_STATUS3.notSubmitted,
36129
36294
  inProgress: "true",
36130
36295
  metadata: {
36131
36296
  isMasteryCompletion: true,
@@ -36137,7 +36302,7 @@ async function upsertMasteryCompletionEntry(params) {
36137
36302
  }
36138
36303
  }
36139
36304
  var init_timeback_mastery_completion_util = __esm(() => {
36140
- init_constants5();
36305
+ init_constants6();
36141
36306
  init_utils6();
36142
36307
  });
36143
36308
 
@@ -36166,7 +36331,7 @@ class TimebackAdminService {
36166
36331
  this.deps = deps;
36167
36332
  }
36168
36333
  getGradeLevelTestCourseScope(integration) {
36169
- if (!isTimebackSubject(integration.subject) || !isTimebackGrade(integration.grade)) {
36334
+ if (!isTimebackSubject2(integration.subject) || !isTimebackGrade2(integration.grade)) {
36170
36335
  throw new ValidationError("Timeback integration has invalid grade or subject");
36171
36336
  }
36172
36337
  return {
@@ -36245,7 +36410,7 @@ class TimebackAdminService {
36245
36410
  await this.deps.validateDeveloperAccess(user, gameId);
36246
36411
  }
36247
36412
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
36248
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
36413
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
36249
36414
  });
36250
36415
  if (!integration) {
36251
36416
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -36343,7 +36508,7 @@ class TimebackAdminService {
36343
36508
  const ids = deriveSourcedIds2(courseId);
36344
36509
  const resource = await client.oneroster.resources.get(ids.resource);
36345
36510
  const playcademyMetadata = resource.metadata?.playcademy;
36346
- if (!isPlaycademyResourceMetadata2(playcademyMetadata)) {
36511
+ if (!isPlaycademyResourceMetadata(playcademyMetadata)) {
36347
36512
  return;
36348
36513
  }
36349
36514
  return playcademyMetadata?.mastery?.masterableUnits;
@@ -36747,7 +36912,7 @@ class TimebackAdminService {
36747
36912
  "app.timeback.include_inactive": options?.includeInactive ?? false
36748
36913
  });
36749
36914
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
36750
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
36915
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
36751
36916
  });
36752
36917
  if (!integration) {
36753
36918
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -36825,7 +36990,7 @@ class TimebackAdminService {
36825
36990
  columns: { id: true }
36826
36991
  }),
36827
36992
  this.deps.db.query.gameTimebackIntegrations.findMany({
36828
- where: eq(gameTimebackIntegrations.gameId, gameId)
36993
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
36829
36994
  }),
36830
36995
  this.deps.db.query.games.findFirst({
36831
36996
  where: eq(games.id, gameId),
@@ -36928,7 +37093,7 @@ class TimebackAdminService {
36928
37093
  "app.timeback.course_id": courseId
36929
37094
  });
36930
37095
  const integrations = await this.deps.db.query.gameTimebackIntegrations.findMany({
36931
- where: courseId ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId)) : eq(gameTimebackIntegrations.gameId, gameId)
37096
+ where: courseId ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus()) : and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
36932
37097
  });
36933
37098
  if (integrations.length === 0) {
36934
37099
  throw new NotFoundError("Timeback integration", gameId);
@@ -37018,7 +37183,7 @@ class TimebackAdminService {
37018
37183
  });
37019
37184
  const [integration, gameSource] = await Promise.all([
37020
37185
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37021
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37186
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37022
37187
  }),
37023
37188
  this.getGameActivitySource(gameId)
37024
37189
  ]);
@@ -37122,7 +37287,7 @@ class TimebackAdminService {
37122
37287
  "app.timeback.course_id": courseId
37123
37288
  });
37124
37289
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37125
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37290
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37126
37291
  });
37127
37292
  if (!integration) {
37128
37293
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37177,7 +37342,7 @@ class TimebackAdminService {
37177
37342
  "app.timeback.assessment_result_id": resultId
37178
37343
  });
37179
37344
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37180
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37345
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37181
37346
  });
37182
37347
  if (!integration) {
37183
37348
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37255,7 +37420,7 @@ class TimebackAdminService {
37255
37420
  });
37256
37421
  const [integration, gameSource, roster] = await Promise.all([
37257
37422
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37258
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37423
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37259
37424
  }),
37260
37425
  this.getGameActivitySource(gameId),
37261
37426
  client.oneroster.enrollments.listByCourse(courseId, {
@@ -37376,7 +37541,7 @@ class TimebackAdminService {
37376
37541
  });
37377
37542
  const [integration, gameSource] = await Promise.all([
37378
37543
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37379
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37544
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37380
37545
  }),
37381
37546
  this.getGameActivitySource(gameId)
37382
37547
  ]);
@@ -37460,7 +37625,7 @@ class TimebackAdminService {
37460
37625
  });
37461
37626
  const [integration, gameSource] = await Promise.all([
37462
37627
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37463
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37628
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37464
37629
  }),
37465
37630
  this.getGameActivitySource(gameId)
37466
37631
  ]);
@@ -37689,7 +37854,7 @@ class TimebackAdminService {
37689
37854
  "app.timeback.course_id": courseId
37690
37855
  });
37691
37856
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37692
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37857
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37693
37858
  });
37694
37859
  if (!integration) {
37695
37860
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37760,7 +37925,7 @@ class TimebackAdminService {
37760
37925
  "app.timeback.enrollment.operation": "enroll"
37761
37926
  });
37762
37927
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37763
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37928
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37764
37929
  });
37765
37930
  if (!integration) {
37766
37931
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37800,7 +37965,7 @@ class TimebackAdminService {
37800
37965
  "app.timeback.enrollment.operation": "unenroll"
37801
37966
  });
37802
37967
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37803
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37968
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37804
37969
  });
37805
37970
  if (!integration) {
37806
37971
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37821,7 +37986,7 @@ class TimebackAdminService {
37821
37986
  "app.timeback.enrollment.operation": "reactivate"
37822
37987
  });
37823
37988
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37824
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37989
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37825
37990
  });
37826
37991
  if (!integration) {
37827
37992
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37867,7 +38032,7 @@ class TimebackAdminService {
37867
38032
  const resultId = `${lineItemId}:${studentId}:completion`;
37868
38033
  try {
37869
38034
  const result = await client.oneroster.assessmentResults.get(resultId);
37870
- if (result.scoreStatus === SCORE_STATUS2.fullyGraded) {
38035
+ if (result.scoreStatus === SCORE_STATUS3.fullyGraded) {
37871
38036
  return "complete";
37872
38037
  }
37873
38038
  return "incomplete";
@@ -37903,12 +38068,13 @@ class TimebackAdminService {
37903
38068
  var init_timeback_admin_service = __esm(() => {
37904
38069
  init_drizzle_orm();
37905
38070
  init_src();
38071
+ init_helpers_index();
37906
38072
  init_schemas_index();
37907
38073
  init_tables_index();
37908
38074
  init_spans();
37909
38075
  init_dist2();
37910
- init_constants5();
37911
- init_types3();
38076
+ init_constants6();
38077
+ init_types2();
37912
38078
  init_utils6();
37913
38079
  init_src4();
37914
38080
  init_timeback3();
@@ -37923,8 +38089,8 @@ var init_timeback_admin_service = __esm(() => {
37923
38089
  });
37924
38090
 
37925
38091
  // ../timeback/dist/errors.js
37926
- var __esm6 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS5, TIMEBACK_AUTH_URLS5, CALIPER_API_URLS5, ONEROSTER_ENDPOINTS5, QTI_ENDPOINTS5, CALIPER_ENDPOINTS5, CALIPER_CONSTANTS5, TIMEBACK_EVENT_TYPES5, TIMEBACK_ACTIONS5, TIMEBACK_TYPES5, ACTIVITY_METRIC_TYPES5, TIME_METRIC_TYPES5, TIMEBACK_SUBJECTS6, TIMEBACK_GRADE_LEVELS5, TIMEBACK_GRADE_LEVEL_LABELS5, CALIPER_SUBJECTS5, ONEROSTER_STATUS5, SCORE_STATUS5, ENV_VARS5, HTTP_DEFAULTS5, AUTH_DEFAULTS5, CACHE_DEFAULTS5, CONFIG_DEFAULTS5, PLAYCADEMY_DEFAULTS5, RESOURCE_DEFAULTS5, HTTP_STATUS5, ERROR_NAMES5, init_constants9, TimebackApiError2;
37927
- var init_errors4 = __esm(() => {
38092
+ var __esm6 = (fn, res) => () => (fn && (res = fn(fn = 0)), res), TIMEBACK_API_URLS5, TIMEBACK_AUTH_URLS5, CALIPER_API_URLS5, ONEROSTER_ENDPOINTS5, QTI_ENDPOINTS5, CALIPER_ENDPOINTS5, CALIPER_CONSTANTS5, TIMEBACK_EVENT_TYPES5, TIMEBACK_ACTIONS5, TIMEBACK_TYPES5, ACTIVITY_METRIC_TYPES5, TIME_METRIC_TYPES5, TIMEBACK_SUBJECTS6, TIMEBACK_GRADE_LEVELS5, TIMEBACK_GRADE_LEVEL_LABELS5, CALIPER_SUBJECTS5, ONEROSTER_STATUS5, SCORE_STATUS5, ENV_VARS5, HTTP_DEFAULTS5, AUTH_DEFAULTS5, CACHE_DEFAULTS5, CONFIG_DEFAULTS5, PLAYCADEMY_DEFAULTS5, RESOURCE_DEFAULTS5, HTTP_STATUS5, ERROR_NAMES5, init_constants9, TimebackError3, TimebackApiError3, TimebackAuthenticationError3, StudentNotFoundError3, ConfigurationError3, ResourceAlreadyExistsError3, ResourceNotFoundError3, init_errors7;
38093
+ var init_errors6 = __esm(() => {
37928
38094
  init_src();
37929
38095
  init_constants9 = __esm6(() => {
37930
38096
  TIMEBACK_API_URLS5 = {
@@ -38108,18 +38274,79 @@ var init_errors4 = __esm(() => {
38108
38274
  timebackSdk: "TimebackSDKError"
38109
38275
  };
38110
38276
  });
38111
- init_constants9();
38112
- TimebackApiError2 = class TimebackApiError2 extends Error {
38113
- status;
38114
- details;
38115
- constructor(status, message, details) {
38116
- super(`${status} ${message}`);
38117
- this.name = ERROR_NAMES5.timebackApi;
38118
- this.status = status;
38119
- this.details = details;
38120
- Object.setPrototypeOf(this, TimebackApiError2.prototype);
38121
- }
38122
- };
38277
+ init_errors7 = __esm6(() => {
38278
+ init_constants9();
38279
+ TimebackError3 = class TimebackError4 extends Error {
38280
+ constructor(message) {
38281
+ super(message);
38282
+ this.name = ERROR_NAMES5.timebackSdk;
38283
+ }
38284
+ };
38285
+ TimebackApiError3 = class TimebackApiError4 extends Error {
38286
+ status;
38287
+ details;
38288
+ constructor(status, message, details) {
38289
+ super(`${status} ${message}`);
38290
+ this.name = ERROR_NAMES5.timebackApi;
38291
+ this.status = status;
38292
+ this.details = details;
38293
+ Object.setPrototypeOf(this, TimebackApiError4.prototype);
38294
+ }
38295
+ };
38296
+ TimebackAuthenticationError3 = class TimebackAuthenticationError4 extends TimebackError3 {
38297
+ constructor(message) {
38298
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
38299
+ this.name = "TimebackAuthenticationError";
38300
+ Object.setPrototypeOf(this, TimebackAuthenticationError4.prototype);
38301
+ }
38302
+ };
38303
+ StudentNotFoundError3 = class StudentNotFoundError4 extends TimebackError3 {
38304
+ identifier;
38305
+ identifierType;
38306
+ constructor(identifier, identifierType = "email") {
38307
+ super(`Student not found with ${identifierType}: ${identifier}. ` + `Ensure the student exists in OneRoster. ` + `If this is a new student, they must be created in OneRoster first.`);
38308
+ this.name = "StudentNotFoundError";
38309
+ this.identifier = identifier;
38310
+ this.identifierType = identifierType;
38311
+ Object.setPrototypeOf(this, StudentNotFoundError4.prototype);
38312
+ }
38313
+ };
38314
+ ConfigurationError3 = class ConfigurationError4 extends TimebackError3 {
38315
+ field;
38316
+ constructor(field, message) {
38317
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
38318
+ this.name = "ConfigurationError";
38319
+ this.field = field;
38320
+ Object.setPrototypeOf(this, ConfigurationError4.prototype);
38321
+ }
38322
+ };
38323
+ ResourceAlreadyExistsError3 = class ResourceAlreadyExistsError4 extends TimebackError3 {
38324
+ resourceType;
38325
+ sourcedId;
38326
+ originalError;
38327
+ constructor(resourceType, sourcedId, originalError) {
38328
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
38329
+ this.name = "ResourceAlreadyExistsError";
38330
+ this.resourceType = resourceType;
38331
+ this.sourcedId = sourcedId;
38332
+ this.originalError = originalError;
38333
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError4.prototype);
38334
+ }
38335
+ };
38336
+ ResourceNotFoundError3 = class ResourceNotFoundError4 extends TimebackError3 {
38337
+ resourceType;
38338
+ sourcedId;
38339
+ constructor(resourceType, sourcedId) {
38340
+ const message = sourcedId === "setup-not-run" ? `TimeBack resources have not been created yet. ` + `Please run 'bunx @playcademy/timeback setup' to create the required resources ` + `(organization, course, components, etc.) before recording progress.` : `${resourceType} with ID '${sourcedId}' not found`;
38341
+ super(message);
38342
+ this.name = "ResourceNotFoundError";
38343
+ this.resourceType = resourceType;
38344
+ this.sourcedId = sourcedId;
38345
+ Object.setPrototypeOf(this, ResourceNotFoundError4.prototype);
38346
+ }
38347
+ };
38348
+ });
38349
+ init_errors7();
38123
38350
  });
38124
38351
 
38125
38352
  // ../api-core/src/services/timeback-assessments.service.ts
@@ -38131,7 +38358,7 @@ class TimebackAssessmentsService {
38131
38358
  async resolveIntegrationId(gameId, courseId, user) {
38132
38359
  await this.deps.validateGameManagementAccess(user, gameId);
38133
38360
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
38134
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
38361
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
38135
38362
  });
38136
38363
  if (!integration) {
38137
38364
  throw new NotFoundError(`No Timeback integration found for game ${gameId} course ${courseId}`);
@@ -38224,7 +38451,7 @@ class TimebackAssessmentsService {
38224
38451
  ]
38225
38452
  });
38226
38453
  } catch (error) {
38227
- if (error instanceof TimebackApiError2 && error.status === 409) {} else {
38454
+ if (error instanceof TimebackApiError3 && error.status === 409) {} else {
38228
38455
  throw error;
38229
38456
  }
38230
38457
  }
@@ -38524,7 +38751,7 @@ class TimebackAssessmentsService {
38524
38751
  }
38525
38752
  async requireIntegration(integrationId) {
38526
38753
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
38527
- where: eq(gameTimebackIntegrations.id, integrationId)
38754
+ where: and(eq(gameTimebackIntegrations.id, integrationId), isActiveGameTimebackIntegrationStatus())
38528
38755
  });
38529
38756
  if (!integration) {
38530
38757
  throw new NotFoundError(`Integration not found: ${integrationId}`);
@@ -38555,7 +38782,7 @@ class TimebackAssessmentsService {
38555
38782
  }
38556
38783
  });
38557
38784
  } catch (error) {
38558
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38785
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38559
38786
  throw error;
38560
38787
  }
38561
38788
  }
@@ -38577,7 +38804,7 @@ class TimebackAssessmentsService {
38577
38804
  }
38578
38805
  });
38579
38806
  } catch (error) {
38580
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38807
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38581
38808
  throw error;
38582
38809
  }
38583
38810
  }
@@ -38595,7 +38822,7 @@ class TimebackAssessmentsService {
38595
38822
  }
38596
38823
  });
38597
38824
  } catch (error) {
38598
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38825
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38599
38826
  throw error;
38600
38827
  }
38601
38828
  }
@@ -38613,14 +38840,63 @@ class TimebackAssessmentsService {
38613
38840
  }
38614
38841
  var init_timeback_assessments_service = __esm(() => {
38615
38842
  init_drizzle_orm();
38843
+ init_helpers_index();
38616
38844
  init_tables_index();
38617
38845
  init_spans();
38618
- init_constants5();
38619
- init_errors4();
38846
+ init_constants6();
38847
+ init_errors6();
38620
38848
  init_utils6();
38621
38849
  init_errors();
38622
38850
  });
38623
38851
 
38852
+ // ../api-core/src/utils/timeback-create-integration.util.ts
38853
+ function buildTimebackBaseConfigFromExistingConfig(config2) {
38854
+ return {
38855
+ organization: config2.organization,
38856
+ component: {
38857
+ ...config2.component,
38858
+ title: ""
38859
+ },
38860
+ resource: {
38861
+ ...config2.resource,
38862
+ title: ""
38863
+ },
38864
+ componentResource: {
38865
+ ...config2.componentResource,
38866
+ title: ""
38867
+ }
38868
+ };
38869
+ }
38870
+ function getMasterableUnitsFromTimebackConfig(config2) {
38871
+ const playcademyMetadata = config2.resource.metadata?.playcademy;
38872
+ if (!isPlaycademyResourceMetadata(playcademyMetadata)) {
38873
+ return null;
38874
+ }
38875
+ return playcademyMetadata?.mastery?.masterableUnits ?? null;
38876
+ }
38877
+ function getTotalXpFromTimebackConfig(config2) {
38878
+ const courseMetadata = isCourseMetadata(config2.course.metadata) ? config2.course.metadata : undefined;
38879
+ if (typeof courseMetadata?.metrics?.totalXp === "number") {
38880
+ return courseMetadata.metrics.totalXp;
38881
+ }
38882
+ const resourceMetadata = config2.resource.metadata;
38883
+ if (isRecord2(resourceMetadata) && typeof resourceMetadata.xp === "number") {
38884
+ return resourceMetadata.xp;
38885
+ }
38886
+ return null;
38887
+ }
38888
+ function timebackConfigMatchesCreateIntegrationRequest(config2, request2) {
38889
+ const subject = config2.course.subjects[0];
38890
+ const grade = config2.course.grades[0];
38891
+ const requestedLevel = request2.level ?? deriveTimebackCourseLevelFromGrade(request2.grade);
38892
+ return subject === request2.subject && grade === request2.grade && config2.course.title === request2.title && config2.course.courseCode === request2.courseCode && config2.course.level === requestedLevel && (getTotalXpFromTimebackConfig(config2) ?? null) === request2.totalXp && (getMasterableUnitsFromTimebackConfig(config2) ?? null) === request2.masterableUnits;
38893
+ }
38894
+ var init_timeback_create_integration_util = __esm(() => {
38895
+ init_constants6();
38896
+ init_types2();
38897
+ init_timeback_util();
38898
+ });
38899
+
38624
38900
  // ../api-core/src/utils/timeback-promotion.util.ts
38625
38901
  async function promoteCompletedCourse({
38626
38902
  db: db2,
@@ -38630,7 +38906,7 @@ async function promoteCompletedCourse({
38630
38906
  enrollments: prefetchedEnrollments
38631
38907
  }) {
38632
38908
  const subjectIntegrations = await db2.query.gameTimebackIntegrations.findMany({
38633
- where: and(eq(gameTimebackIntegrations.gameId, currentIntegration.gameId), eq(gameTimebackIntegrations.subject, currentIntegration.subject))
38909
+ where: and(eq(gameTimebackIntegrations.gameId, currentIntegration.gameId), eq(gameTimebackIntegrations.subject, currentIntegration.subject), isActiveGameTimebackIntegrationStatus())
38634
38910
  });
38635
38911
  const nextIntegration = subjectIntegrations.filter((integration) => integration.grade > currentIntegration.grade).toSorted((left, right) => left.grade - right.grade)[0];
38636
38912
  if (!nextIntegration) {
@@ -38685,21 +38961,72 @@ async function promoteCompletedCourse({
38685
38961
  }
38686
38962
  var init_timeback_promotion_util = __esm(() => {
38687
38963
  init_drizzle_orm();
38964
+ init_helpers_index();
38688
38965
  init_tables_index();
38689
38966
  init_spans();
38690
38967
  });
38691
38968
 
38969
+ // ../api-core/src/utils/timeback-removed-integration.util.ts
38970
+ function toGameTimebackIntegration(integration) {
38971
+ return {
38972
+ id: integration.id,
38973
+ gameId: integration.gameId,
38974
+ courseId: integration.courseId,
38975
+ grade: integration.grade,
38976
+ subject: integration.subject,
38977
+ totalXp: integration.totalXp ?? null,
38978
+ status: integration.status ?? ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
38979
+ deactivatedAt: integration.deactivatedAt ?? null,
38980
+ reactivatedAt: integration.reactivatedAt ?? null,
38981
+ createdAt: integration.createdAt,
38982
+ updatedAt: integration.updatedAt,
38983
+ lastVerifiedAt: integration.lastVerifiedAt ?? null
38984
+ };
38985
+ }
38986
+ function buildFallbackRemovedGameTimebackIntegration(integration) {
38987
+ if (!isTimebackSubject(integration.subject)) {
38988
+ throw new ValidationError(`Invalid subject "${integration.subject}"`);
38989
+ }
38990
+ if (!isTimebackGrade(integration.grade)) {
38991
+ throw new ValidationError(`Invalid grade "${integration.grade}"`);
38992
+ }
38993
+ return {
38994
+ integration: toGameTimebackIntegration(integration),
38995
+ title: `${integration.subject} ${formatGradeLabel(integration.grade)}`,
38996
+ courseCode: integration.courseId,
38997
+ subject: integration.subject,
38998
+ grade: integration.grade,
38999
+ totalXp: integration.totalXp ?? null,
39000
+ masterableUnits: null,
39001
+ removedAt: integration.deactivatedAt ?? null,
39002
+ metadata: null
39003
+ };
39004
+ }
39005
+ var init_timeback_removed_integration_util = __esm(() => {
39006
+ init_helpers_index();
39007
+ init_types2();
39008
+ init_timeback3();
39009
+ init_errors();
39010
+ });
39011
+
38692
39012
  // ../api-core/src/services/timeback.service.ts
39013
+ async function findGameTimebackIntegrationForUpdate(db2, condition) {
39014
+ const [integration] = await db2.select().from(gameTimebackIntegrations).where(condition).limit(1).for("update");
39015
+ return integration;
39016
+ }
38693
39017
  var TimebackService;
38694
39018
  var init_timeback_service = __esm(() => {
38695
39019
  init_drizzle_orm();
38696
39020
  init_src();
39021
+ init_helpers_index();
38697
39022
  init_tables_index();
38698
39023
  init_spans();
38699
39024
  init_dist2();
38700
- init_types3();
39025
+ init_types2();
38701
39026
  init_errors();
39027
+ init_timeback_create_integration_util();
38702
39028
  init_timeback_promotion_util();
39029
+ init_timeback_removed_integration_util();
38703
39030
  init_timeback_util();
38704
39031
  TimebackService = class TimebackService {
38705
39032
  static HEARTBEAT_DEDUPE_TTL_MS = 5 * 60 * 1000;
@@ -38929,7 +39256,7 @@ var init_timeback_service = __esm(() => {
38929
39256
  return [];
38930
39257
  }
38931
39258
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
38932
- where: inArray(gameTimebackIntegrations.courseId, courseIds)
39259
+ where: and(inArray(gameTimebackIntegrations.courseId, courseIds), isActiveGameTimebackIntegrationStatus())
38933
39260
  });
38934
39261
  return mapEnrollmentsToUserEnrollments(enrollments, integrations);
38935
39262
  } catch (error) {
@@ -38954,6 +39281,7 @@ var init_timeback_service = __esm(() => {
38954
39281
  const verboseData = [];
38955
39282
  let integrationCreatedCount = 0;
38956
39283
  let integrationUpdatedCount = 0;
39284
+ let integrationReactivatedCount = 0;
38957
39285
  for (const courseConfig of courses) {
38958
39286
  let applySuffix = function(text3) {
38959
39287
  return suffix ? `${text3} ${suffix}` : text3;
@@ -38968,16 +39296,16 @@ var init_timeback_service = __esm(() => {
38968
39296
  totalXp: derivedTotalXp,
38969
39297
  masterableUnits: derivedMasterableUnits
38970
39298
  } = courseConfig;
38971
- if (!isTimebackSubject3(subjectInput)) {
39299
+ if (!isTimebackSubject(subjectInput)) {
38972
39300
  throw new ValidationError(`Invalid subject "${subjectInput}"`);
38973
39301
  }
38974
- if (!isTimebackGrade3(grade)) {
39302
+ if (!isTimebackGrade(grade)) {
38975
39303
  throw new ValidationError(`Invalid grade "${grade}"`);
38976
39304
  }
38977
39305
  const subject = subjectInput;
38978
39306
  const courseMetadata = isCourseMetadata(metadata2) ? metadata2 : undefined;
38979
39307
  const totalXp = derivedTotalXp ?? courseMetadata?.metrics?.totalXp;
38980
- const masterableUnits = derivedMasterableUnits ?? (isPlaycademyResourceMetadata2(courseMetadata?.playcademy) ? courseMetadata?.playcademy?.mastery?.masterableUnits : undefined);
39308
+ const masterableUnits = derivedMasterableUnits ?? (isPlaycademyResourceMetadata(courseMetadata?.playcademy) ? courseMetadata?.playcademy?.mastery?.masterableUnits : undefined);
38981
39309
  if (typeof totalXp !== "number") {
38982
39310
  throw new ValidationError(`Course "${title}" is missing totalXp`);
38983
39311
  }
@@ -39023,19 +39351,28 @@ var init_timeback_service = __esm(() => {
39023
39351
  title: applySuffix(baseConfig.componentResource.title || "")
39024
39352
  }
39025
39353
  };
39026
- const existingIntegration = existing.find((i2) => i2.grade === grade && i2.subject === subject);
39354
+ const matches = existing.filter((i2) => i2.grade === grade && i2.subject === subject);
39355
+ const existingIntegration = matches.find((i2) => i2.status !== DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS) ?? matches.toSorted((a, b) => (b.deactivatedAt?.getTime() ?? 0) - (a.deactivatedAt?.getTime() ?? 0))[0];
39027
39356
  if (existingIntegration) {
39028
- await client.update(existingIntegration.courseId, fullConfig);
39029
- const [updated] = await db2.update(gameTimebackIntegrations).set({ subject, totalXp, updatedAt: new Date }).where(eq(gameTimebackIntegrations.id, existingIntegration.id)).returning();
39357
+ const { updated, revived } = await this.updateSetupIntegration({
39358
+ client,
39359
+ existingIntegration,
39360
+ fullConfig,
39361
+ subject,
39362
+ totalXp
39363
+ });
39030
39364
  if (updated) {
39031
- integrations.push(this.toGameTimebackIntegration(updated));
39365
+ integrations.push(toGameTimebackIntegration(updated));
39032
39366
  integrationUpdatedCount++;
39367
+ if (revived) {
39368
+ integrationReactivatedCount++;
39369
+ }
39033
39370
  }
39034
39371
  } else {
39035
39372
  const result = await client.setup(fullConfig, { verbose });
39036
39373
  const [integration] = await db2.insert(gameTimebackIntegrations).values({ gameId, courseId: result.courseId, grade, subject, totalXp }).returning();
39037
39374
  if (integration) {
39038
- const dto = this.toGameTimebackIntegration(integration);
39375
+ const dto = toGameTimebackIntegration(integration);
39039
39376
  integrations.push(dto);
39040
39377
  integrationCreatedCount++;
39041
39378
  if (verbose && result.verboseData) {
@@ -39047,7 +39384,8 @@ var init_timeback_service = __esm(() => {
39047
39384
  setAttributes({
39048
39385
  "app.timeback.integration_count": integrations.length,
39049
39386
  "app.timeback.integration_created_count": integrationCreatedCount,
39050
- "app.timeback.integration_updated_count": integrationUpdatedCount
39387
+ "app.timeback.integration_updated_count": integrationUpdatedCount,
39388
+ "app.timeback.integration_reactivated_count": integrationReactivatedCount
39051
39389
  });
39052
39390
  return {
39053
39391
  integrations,
@@ -39055,19 +39393,221 @@ var init_timeback_service = __esm(() => {
39055
39393
  };
39056
39394
  });
39057
39395
  }
39396
+ async updateSetupIntegration(args2) {
39397
+ const { client, existingIntegration, fullConfig, subject, totalXp } = args2;
39398
+ const revived = existingIntegration.status === DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS;
39399
+ await client.update(existingIntegration.courseId, fullConfig);
39400
+ if (revived) {
39401
+ await client.reactivateCourse(existingIntegration.courseId);
39402
+ }
39403
+ const now2 = new Date;
39404
+ const [updated] = await this.deps.db.update(gameTimebackIntegrations).set({
39405
+ subject,
39406
+ totalXp,
39407
+ updatedAt: now2,
39408
+ ...revived && {
39409
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39410
+ deactivatedAt: null,
39411
+ reactivatedAt: now2
39412
+ }
39413
+ }).where(eq(gameTimebackIntegrations.id, existingIntegration.id)).returning();
39414
+ return { updated, revived };
39415
+ }
39416
+ async createIntegration(gameId, user, request2) {
39417
+ return this.withClientTelemetry(async () => {
39418
+ const client = this.requireClient();
39419
+ const db2 = this.deps.db;
39420
+ await this.deps.validateDeveloperAccess(user, gameId);
39421
+ setAttributes({
39422
+ "app.timeback.grade": request2.grade,
39423
+ "app.timeback.subject": request2.subject
39424
+ });
39425
+ const activeConflict = await db2.query.gameTimebackIntegrations.findFirst({
39426
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, request2.grade), eq(gameTimebackIntegrations.subject, request2.subject), isActiveGameTimebackIntegrationStatus())
39427
+ });
39428
+ if (activeConflict) {
39429
+ throw new ConflictError(`A TimeBack integration already exists for ${request2.subject} Grade ${request2.grade}`);
39430
+ }
39431
+ const removedCandidates = await db2.query.gameTimebackIntegrations.findMany({
39432
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, request2.grade), eq(gameTimebackIntegrations.subject, request2.subject), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))
39433
+ });
39434
+ for (const candidate of removedCandidates) {
39435
+ const config2 = await client.getConfig(candidate.courseId).catch((error) => {
39436
+ addEvent("timeback.removed_integration_config_fetch_failed", {
39437
+ "app.game.id": gameId,
39438
+ "app.timeback.course_id": candidate.courseId,
39439
+ "exception.type": errorType(error),
39440
+ "app.error.message": errorMessage(error)
39441
+ });
39442
+ return null;
39443
+ });
39444
+ if (config2 && timebackConfigMatchesCreateIntegrationRequest(config2, request2)) {
39445
+ const updated = await db2.transaction(async (tx) => {
39446
+ const database = tx;
39447
+ const lockedCandidate = await findGameTimebackIntegrationForUpdate(database, eq(gameTimebackIntegrations.id, candidate.id));
39448
+ if (lockedCandidate?.status !== DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS) {
39449
+ throw new ConflictError(`A TimeBack integration already exists for ${request2.subject} Grade ${request2.grade}`);
39450
+ }
39451
+ const now2 = new Date;
39452
+ const [integration2] = await database.update(gameTimebackIntegrations).set({
39453
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39454
+ totalXp: request2.totalXp,
39455
+ deactivatedAt: null,
39456
+ reactivatedAt: now2,
39457
+ updatedAt: now2
39458
+ }).where(and(eq(gameTimebackIntegrations.id, candidate.id), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))).returning();
39459
+ if (!integration2) {
39460
+ throw new NotFoundError("Timeback integration", candidate.id);
39461
+ }
39462
+ await client.reactivateCourse(candidate.courseId);
39463
+ return integration2;
39464
+ });
39465
+ setAttribute("app.timeback.course_create_mode", "reactivated-removed");
39466
+ return toGameTimebackIntegration(updated);
39467
+ }
39468
+ }
39469
+ const reference = await db2.query.gameTimebackIntegrations.findFirst({
39470
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus()),
39471
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.createdAt)]
39472
+ }) ?? await db2.query.gameTimebackIntegrations.findFirst({
39473
+ where: eq(gameTimebackIntegrations.gameId, gameId),
39474
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.createdAt)]
39475
+ });
39476
+ if (!reference) {
39477
+ throw new ValidationError("Run `playcademy timeback setup` before adding courses from the dashboard.");
39478
+ }
39479
+ const referenceConfig = await client.getConfig(reference.courseId);
39480
+ const result = await this.setupIntegration(gameId, {
39481
+ gameId,
39482
+ courses: [
39483
+ {
39484
+ title: request2.title,
39485
+ courseCode: request2.courseCode,
39486
+ subject: request2.subject,
39487
+ grade: request2.grade,
39488
+ level: request2.level ?? deriveTimebackCourseLevelFromGrade(request2.grade),
39489
+ totalXp: request2.totalXp,
39490
+ masterableUnits: request2.masterableUnits
39491
+ }
39492
+ ],
39493
+ baseConfig: buildTimebackBaseConfigFromExistingConfig(referenceConfig)
39494
+ }, user);
39495
+ const integration = result.integrations[0];
39496
+ if (!integration) {
39497
+ throw new InternalError("TimeBack course creation did not return an integration");
39498
+ }
39499
+ setAttribute("app.timeback.course_create_mode", "created-new");
39500
+ return integration;
39501
+ });
39502
+ }
39058
39503
  async getIntegrations(gameId, user) {
39059
39504
  await this.deps.validateGameManagementAccess(user, gameId);
39060
39505
  const rows = await this.deps.db.query.gameTimebackIntegrations.findMany({
39061
- where: eq(gameTimebackIntegrations.gameId, gameId)
39506
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39507
+ });
39508
+ return rows.map((row) => toGameTimebackIntegration(row));
39509
+ }
39510
+ async getRemovedIntegrations(gameId, user) {
39511
+ return this.withClientTelemetry(async () => {
39512
+ const client = this.requireClient();
39513
+ await this.deps.validateGameManagementAccess(user, gameId);
39514
+ const rows = await this.deps.db.query.gameTimebackIntegrations.findMany({
39515
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS)),
39516
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.subject), asc2(table8.grade)]
39517
+ });
39518
+ setAttribute("app.timeback.removed_integration_count", rows.length);
39519
+ return Promise.all(rows.map(async (row) => {
39520
+ try {
39521
+ const config2 = await client.getConfig(row.courseId);
39522
+ return this.toRemovedGameTimebackIntegration(row, config2);
39523
+ } catch (error) {
39524
+ addEvent("timeback.removed_integration_config_fetch_failed", {
39525
+ "app.game.id": gameId,
39526
+ "app.timeback.course_id": row.courseId,
39527
+ "exception.type": errorType(error),
39528
+ "app.error.message": errorMessage(error)
39529
+ });
39530
+ return buildFallbackRemovedGameTimebackIntegration(row);
39531
+ }
39532
+ }));
39533
+ });
39534
+ }
39535
+ async deactivateCourse(gameId, courseId, user) {
39536
+ return this.withClientTelemetry(async () => {
39537
+ const client = this.requireClient();
39538
+ const db2 = this.deps.db;
39539
+ await this.deps.validateDeveloperAccess(user, gameId);
39540
+ const updated = await db2.transaction(async (tx) => {
39541
+ const database = tx;
39542
+ const integration = await findGameTimebackIntegrationForUpdate(database, and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus()));
39543
+ if (!integration) {
39544
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39545
+ }
39546
+ const activeEnrollments = await client.oneroster.enrollments.listByCourse(courseId, {
39547
+ role: "student",
39548
+ includeUsers: false
39549
+ });
39550
+ setAttribute("app.timeback.active_enrollment_count", activeEnrollments.length);
39551
+ if (activeEnrollments.length > 0) {
39552
+ throw new ConflictError("Cannot remove course with active enrollments", {
39553
+ courseId,
39554
+ activeEnrollmentCount: activeEnrollments.length
39555
+ });
39556
+ }
39557
+ const now2 = new Date;
39558
+ const [updatedIntegration] = await database.update(gameTimebackIntegrations).set({
39559
+ status: DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS,
39560
+ deactivatedAt: now2,
39561
+ updatedAt: now2
39562
+ }).where(and(eq(gameTimebackIntegrations.id, integration.id), isActiveGameTimebackIntegrationStatus())).returning();
39563
+ if (!updatedIntegration) {
39564
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39565
+ }
39566
+ await client.deactivateCourse(courseId);
39567
+ return updatedIntegration;
39568
+ });
39569
+ return toGameTimebackIntegration(updated);
39570
+ });
39571
+ }
39572
+ async reactivateCourse(gameId, courseId, user) {
39573
+ return this.withClientTelemetry(async () => {
39574
+ const client = this.requireClient();
39575
+ const db2 = this.deps.db;
39576
+ await this.deps.validateDeveloperAccess(user, gameId);
39577
+ const updated = await db2.transaction(async (tx) => {
39578
+ const database = tx;
39579
+ const integration = await findGameTimebackIntegrationForUpdate(database, and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS)));
39580
+ if (!integration) {
39581
+ throw new NotFoundError("Removed Timeback course", `${gameId}:${courseId}`);
39582
+ }
39583
+ const activeConflict = await database.query.gameTimebackIntegrations.findFirst({
39584
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, integration.subject), isActiveGameTimebackIntegrationStatus())
39585
+ });
39586
+ if (activeConflict) {
39587
+ throw new ConflictError(`An active TimeBack course already exists for ${integration.subject} Grade ${integration.grade}`);
39588
+ }
39589
+ const now2 = new Date;
39590
+ const [updatedIntegration] = await database.update(gameTimebackIntegrations).set({
39591
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39592
+ deactivatedAt: null,
39593
+ reactivatedAt: now2,
39594
+ updatedAt: now2
39595
+ }).where(and(eq(gameTimebackIntegrations.id, integration.id), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))).returning();
39596
+ if (!updatedIntegration) {
39597
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39598
+ }
39599
+ await client.reactivateCourse(courseId);
39600
+ return updatedIntegration;
39601
+ });
39602
+ return toGameTimebackIntegration(updated);
39062
39603
  });
39063
- return rows.map((row) => this.toGameTimebackIntegration(row));
39064
39604
  }
39065
39605
  async getIntegrationConfig(gameId, courseId, user) {
39066
39606
  return this.withClientTelemetry(async () => {
39067
39607
  const client = this.requireClient();
39068
39608
  await this.deps.validateGameManagementAccess(user, gameId);
39069
39609
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39070
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
39610
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
39071
39611
  });
39072
39612
  if (!integration) {
39073
39613
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -39084,15 +39624,15 @@ var init_timeback_service = __esm(() => {
39084
39624
  "app.timeback.course_id": courseId
39085
39625
  });
39086
39626
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39087
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
39627
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
39088
39628
  });
39089
39629
  if (!integration) {
39090
39630
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
39091
39631
  }
39092
39632
  const timebackConfig = await client.getConfig(courseId);
39093
39633
  const liveSubject = timebackConfig.course.subjects[0];
39094
- const subject = patch.subject ?? (isTimebackSubject3(liveSubject) ? liveSubject : integration.subject);
39095
- if (!isTimebackSubject3(subject)) {
39634
+ const subject = patch.subject ?? (isTimebackSubject(liveSubject) ? liveSubject : integration.subject);
39635
+ if (!isTimebackSubject(subject)) {
39096
39636
  throw new ValidationError(`Invalid subject "${subject}"`);
39097
39637
  }
39098
39638
  setAttributes({
@@ -39102,14 +39642,14 @@ var init_timeback_service = __esm(() => {
39102
39642
  });
39103
39643
  if (subject !== integration.subject) {
39104
39644
  const subjectConflict = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39105
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, subject))
39645
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, subject), isActiveGameTimebackIntegrationStatus())
39106
39646
  });
39107
39647
  if (subjectConflict && subjectConflict.id !== integration.id) {
39108
39648
  throw new ValidationError(`A TimeBack integration already exists for ${subject} Grade ${integration.grade}`);
39109
39649
  }
39110
39650
  }
39111
- const totalXp = "totalXp" in patch ? patch.totalXp ?? null : TimebackService.getTotalXpFromConfig(timebackConfig) ?? integration.totalXp ?? null;
39112
- const masterableUnits = "masterableUnits" in patch ? patch.masterableUnits ?? null : TimebackService.getMasterableUnitsFromConfig(timebackConfig);
39651
+ const totalXp = "totalXp" in patch ? patch.totalXp ?? null : getTotalXpFromTimebackConfig(timebackConfig) ?? integration.totalXp ?? null;
39652
+ const masterableUnits = "masterableUnits" in patch ? patch.masterableUnits ?? null : getMasterableUnitsFromTimebackConfig(timebackConfig);
39113
39653
  setAttributes({
39114
39654
  "app.timeback.total_xp": totalXp,
39115
39655
  "app.timeback.masterable_units": masterableUnits
@@ -39129,7 +39669,7 @@ var init_timeback_service = __esm(() => {
39129
39669
  if (!updated) {
39130
39670
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
39131
39671
  }
39132
- return this.toGameTimebackIntegration(updated);
39672
+ return toGameTimebackIntegration(updated);
39133
39673
  });
39134
39674
  }
39135
39675
  async verifyIntegration(gameId, user) {
@@ -39139,7 +39679,7 @@ var init_timeback_service = __esm(() => {
39139
39679
  await this.deps.validateDeveloperAccess(user, gameId);
39140
39680
  TimebackService.recordIntegrationOperation("verify_integration");
39141
39681
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
39142
- where: eq(gameTimebackIntegrations.gameId, gameId)
39682
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39143
39683
  });
39144
39684
  if (integrations.length === 0) {
39145
39685
  throw new NotFoundError("Timeback integration", gameId);
@@ -39152,7 +39692,7 @@ var init_timeback_service = __esm(() => {
39152
39692
  const errors3 = Object.entries(resources).filter(([_, r]) => !r.found).map(([name3]) => `${name3} not found`);
39153
39693
  const status = allFound ? "success" : "error";
39154
39694
  return {
39155
- integration: this.toGameTimebackIntegration({
39695
+ integration: toGameTimebackIntegration({
39156
39696
  ...integration,
39157
39697
  lastVerifiedAt: now2
39158
39698
  }),
@@ -39161,7 +39701,7 @@ var init_timeback_service = __esm(() => {
39161
39701
  ...errors3.length > 0 && { errors: errors3 }
39162
39702
  };
39163
39703
  }));
39164
- await db2.update(gameTimebackIntegrations).set({ lastVerifiedAt: now2 }).where(eq(gameTimebackIntegrations.gameId, gameId));
39704
+ await db2.update(gameTimebackIntegrations).set({ lastVerifiedAt: now2 }).where(inArray(gameTimebackIntegrations.id, integrations.map((integration) => integration.id)));
39165
39705
  const overallStatus = results.every((r) => r.status === "success") ? "success" : "error";
39166
39706
  const missingResourceCount = results.reduce((count, result) => count + (result.errors?.length ?? 0), 0);
39167
39707
  setAttributes({
@@ -39177,7 +39717,7 @@ var init_timeback_service = __esm(() => {
39177
39717
  const client = this.requireClient();
39178
39718
  await this.deps.validateDeveloperAccess(user, gameId);
39179
39719
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39180
- where: eq(gameTimebackIntegrations.gameId, gameId)
39720
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39181
39721
  });
39182
39722
  if (!integration) {
39183
39723
  throw new NotFoundError("Timeback integration", gameId);
@@ -39204,24 +39744,6 @@ var init_timeback_service = __esm(() => {
39204
39744
  await db2.delete(gameTimebackIntegrations).where(eq(gameTimebackIntegrations.gameId, gameId));
39205
39745
  });
39206
39746
  }
39207
- static getMasterableUnitsFromConfig(config2) {
39208
- const playcademyMetadata = config2.resource.metadata?.playcademy;
39209
- if (!isPlaycademyResourceMetadata2(playcademyMetadata)) {
39210
- return null;
39211
- }
39212
- return playcademyMetadata?.mastery?.masterableUnits ?? null;
39213
- }
39214
- static getTotalXpFromConfig(config2) {
39215
- const courseMetadata = isCourseMetadata(config2.course.metadata) ? config2.course.metadata : undefined;
39216
- if (typeof courseMetadata?.metrics?.totalXp === "number") {
39217
- return courseMetadata.metrics.totalXp;
39218
- }
39219
- const resourceMetadata = config2.resource.metadata;
39220
- if (isRecord2(resourceMetadata) && typeof resourceMetadata.xp === "number") {
39221
- return resourceMetadata.xp;
39222
- }
39223
- return null;
39224
- }
39225
39747
  static patchCourseMetadata(metadata2, totalXp, options) {
39226
39748
  const nextMetadata = isRecord2(metadata2) ? { ...metadata2 } : {};
39227
39749
  const currentMetrics = isRecord2(nextMetadata.metrics) ? nextMetadata.metrics : {};
@@ -39344,31 +39866,29 @@ var init_timeback_service = __esm(() => {
39344
39866
  }
39345
39867
  };
39346
39868
  }
39347
- toGameTimebackIntegration(integration) {
39869
+ toRemovedGameTimebackIntegration(integration, config2) {
39870
+ const grade = config2.course.grades[0] ?? integration.grade;
39871
+ if (!isTimebackGrade(grade)) {
39872
+ throw new ValidationError(`Invalid grade "${grade}"`);
39873
+ }
39348
39874
  return {
39349
- id: integration.id,
39350
- gameId: integration.gameId,
39351
- courseId: integration.courseId,
39352
- grade: integration.grade,
39353
- subject: integration.subject,
39354
- totalXp: integration.totalXp ?? null,
39355
- createdAt: integration.createdAt,
39356
- updatedAt: integration.updatedAt,
39357
- lastVerifiedAt: integration.lastVerifiedAt ?? null
39875
+ ...this.toGameTimebackIntegrationConfig(integration, config2),
39876
+ grade,
39877
+ removedAt: integration.deactivatedAt ?? null
39358
39878
  };
39359
39879
  }
39360
39880
  toGameTimebackIntegrationConfig(integration, config2) {
39361
39881
  const subject = config2.course.subjects[0] ?? integration.subject;
39362
- if (!isTimebackSubject3(subject)) {
39882
+ if (!isTimebackSubject(subject)) {
39363
39883
  throw new ValidationError(`Invalid subject "${subject}"`);
39364
39884
  }
39365
39885
  return {
39366
- integration: this.toGameTimebackIntegration(integration),
39886
+ integration: toGameTimebackIntegration(integration),
39367
39887
  title: config2.course.title,
39368
39888
  courseCode: config2.course.courseCode,
39369
39889
  subject,
39370
- totalXp: TimebackService.getTotalXpFromConfig(config2) ?? integration.totalXp ?? null,
39371
- masterableUnits: TimebackService.getMasterableUnitsFromConfig(config2),
39890
+ totalXp: getTotalXpFromTimebackConfig(config2) ?? integration.totalXp ?? null,
39891
+ masterableUnits: getMasterableUnitsFromTimebackConfig(config2),
39372
39892
  metadata: isCourseMetadata(config2.course.metadata) ? config2.course.metadata : null
39373
39893
  };
39374
39894
  }
@@ -39400,7 +39920,7 @@ var init_timeback_service = __esm(() => {
39400
39920
  });
39401
39921
  await this.deps.validateDeveloperAccess(user, gameId);
39402
39922
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39403
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject))
39923
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject), isActiveGameTimebackIntegrationStatus())
39404
39924
  });
39405
39925
  if (!integration) {
39406
39926
  throw new NotFoundError(`Timeback integration for game (grade ${activityData.grade}, subject ${activityData.subject})`);
@@ -39461,9 +39981,7 @@ var init_timeback_service = __esm(() => {
39461
39981
  "app.timeback.xp_awarded": result.xpAwarded,
39462
39982
  "app.timeback.mastered_units_requested": masteredUnits,
39463
39983
  "app.timeback.mastered_units_absolute_requested": masteredUnitsAbsolute,
39464
- "app.timeback.mastered_units_applied": result.masteredUnitsApplied,
39465
- "app.timeback.score_status": result.scoreStatus,
39466
- "app.timeback.in_progress": result.inProgress
39984
+ "app.timeback.mastered_units_applied": result.masteredUnitsApplied
39467
39985
  });
39468
39986
  return {
39469
39987
  status: "ok",
@@ -39471,8 +39989,6 @@ var init_timeback_service = __esm(() => {
39471
39989
  xpAwarded: result.xpAwarded,
39472
39990
  masteredUnits: result.masteredUnitsApplied,
39473
39991
  pctCompleteApp: result.pctCompleteApp,
39474
- scoreStatus: result.scoreStatus,
39475
- inProgress: result.inProgress,
39476
39992
  ...result.warnings ? { warnings: result.warnings } : {}
39477
39993
  };
39478
39994
  }
@@ -39485,7 +40001,7 @@ var init_timeback_service = __esm(() => {
39485
40001
  const client = this.requireClient();
39486
40002
  const db2 = this.deps.db;
39487
40003
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
39488
- where: subject ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.subject, subject)) : eq(gameTimebackIntegrations.gameId, gameId)
40004
+ where: subject ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.subject, subject), isActiveGameTimebackIntegrationStatus()) : and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39489
40005
  });
39490
40006
  if (integrations.length === 0) {
39491
40007
  throw new NotFoundError(subject ? `Timeback integrations for game (subject ${subject})` : "Timeback integrations for game");
@@ -39667,7 +40183,7 @@ var init_timeback_service = __esm(() => {
39667
40183
  }
39668
40184
  const pendingHeartbeat = (async () => {
39669
40185
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39670
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject))
40186
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject), isActiveGameTimebackIntegrationStatus())
39671
40187
  });
39672
40188
  if (!integration) {
39673
40189
  throw new NotFoundError(`Timeback integration for game (grade ${activityData.grade}, subject ${activityData.subject})`);
@@ -39715,7 +40231,10 @@ var init_timeback_service = __esm(() => {
39715
40231
  let courseIds = [];
39716
40232
  if (options?.gameId) {
39717
40233
  await this.deps.validateDeveloperAccess(user, options.gameId);
39718
- const conditions2 = [eq(gameTimebackIntegrations.gameId, options.gameId)];
40234
+ const conditions2 = [
40235
+ eq(gameTimebackIntegrations.gameId, options.gameId),
40236
+ isActiveGameTimebackIntegrationStatus()
40237
+ ];
39719
40238
  if (options.grade !== undefined && options.subject) {
39720
40239
  conditions2.push(eq(gameTimebackIntegrations.grade, options.grade));
39721
40240
  conditions2.push(eq(gameTimebackIntegrations.subject, options.subject));
@@ -39742,7 +40261,10 @@ var init_timeback_service = __esm(() => {
39742
40261
  const client = this.requireClient();
39743
40262
  const db2 = this.deps.db;
39744
40263
  await this.deps.validateDeveloperAccess(user, options.gameId);
39745
- const conditions2 = [eq(gameTimebackIntegrations.gameId, options.gameId)];
40264
+ const conditions2 = [
40265
+ eq(gameTimebackIntegrations.gameId, options.gameId),
40266
+ isActiveGameTimebackIntegrationStatus()
40267
+ ];
39746
40268
  if (options.grade !== undefined && options.subject) {
39747
40269
  conditions2.push(eq(gameTimebackIntegrations.grade, options.grade));
39748
40270
  conditions2.push(eq(gameTimebackIntegrations.subject, options.subject));
@@ -39769,7 +40291,7 @@ var init_timeback_service = __esm(() => {
39769
40291
  const db2 = this.deps.db;
39770
40292
  await this.deps.validateDeveloperAccess(user, options.gameId);
39771
40293
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39772
- where: and(eq(gameTimebackIntegrations.gameId, options.gameId), eq(gameTimebackIntegrations.subject, options.subject))
40294
+ where: and(eq(gameTimebackIntegrations.gameId, options.gameId), eq(gameTimebackIntegrations.subject, options.subject), isActiveGameTimebackIntegrationStatus())
39773
40295
  });
39774
40296
  if (!integration) {
39775
40297
  throw new ValidationError(`Subject "${options.subject}" is not configured for game ${options.gameId}`);
@@ -40656,7 +41178,7 @@ class UserService {
40656
41178
  return [];
40657
41179
  }
40658
41180
  const integrations = await this.deps.db.query.gameTimebackIntegrations.findMany({
40659
- where: inArray(gameTimebackIntegrations.courseId, courseIds)
41181
+ where: and(inArray(gameTimebackIntegrations.courseId, courseIds), isActiveGameTimebackIntegrationStatus())
40660
41182
  });
40661
41183
  return mapEnrollmentsToUserEnrollments(enrollments, integrations);
40662
41184
  } catch (error) {
@@ -40678,6 +41200,7 @@ class UserService {
40678
41200
  var init_user_service = __esm(() => {
40679
41201
  init_drizzle_orm();
40680
41202
  init_src();
41203
+ init_helpers_index();
40681
41204
  init_tables_index();
40682
41205
  init_spans();
40683
41206
  init_errors();
@@ -56875,7 +57398,7 @@ function extractTablesRelationalConfig2(schema5, configHelpers) {
56875
57398
  return { tables: tablesConfig, tableNamesMap };
56876
57399
  }
56877
57400
  function relations3(table62, relations22) {
56878
- return new Relations2(table62, (helpers) => Object.fromEntries(Object.entries(relations22(helpers)).map(([key, value]) => [
57401
+ return new Relations2(table62, (helpers3) => Object.fromEntries(Object.entries(relations22(helpers3)).map(([key, value]) => [
56879
57402
  key,
56880
57403
  value.withFieldName(key)
56881
57404
  ])));
@@ -58049,7 +58572,7 @@ var __create2, __defProp3, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
58049
58572
  __defProp3(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
58050
58573
  }
58051
58574
  return to;
58052
- }, __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp3(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType2, init_util2, ZodIssueCode2, ZodError3, init_ZodError2, errorMap2, en_default2, init_en2, overrideErrorMap2, init_errors5, makeIssue2, ParseStatus2, INVALID2, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType2, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString2, ZodNumber2, ZodBigInt2, ZodBoolean2, ZodDate2, ZodSymbol2, ZodUndefined2, ZodNull2, ZodAny2, ZodUnknown2, ZodNever2, ZodVoid2, ZodArray2, ZodObject2, ZodUnion2, getDiscriminator2, ZodDiscriminatedUnion2, ZodIntersection2, ZodTuple2, ZodRecord2, ZodMap2, ZodSet2, ZodFunction2, ZodLazy2, ZodLiteral2, ZodEnum2, ZodNativeEnum2, ZodPromise2, ZodEffects2, ZodOptional2, ZodNullable2, ZodDefault2, ZodCatch2, ZodNaN2, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly2, late2, ZodFirstPartyTypeKind2, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external2, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a, Column2, init_column2, _a2, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a3, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version2, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a22, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a32, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist6, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks2, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union2, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union3, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks3, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a322, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
58575
+ }, __toESM2 = (mod, isNodeMode, target) => (target = mod != null ? __create2(__getProtoOf2(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp3(target, "default", { value: mod, enumerable: true }) : target, mod)), __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value), ANSI_BACKGROUND_OFFSET, wrapAnsi16, wrapAnsi256, wrapAnsi16m, styles2, modifierNames, foregroundColorNames, backgroundColorNames, colorNames, ansiStyles, ansi_styles_default, init_ansi_styles, env, flagForceColor, supportsColor, supports_color_default, init_supports_color, init_utilities, stdoutColor, stderrColor, GENERATOR, STYLER, IS_EMPTY, levelMapping, styles22, applyOptions, chalkFactory, getModelAnsi, usedModels, proto, createStyler, createBuilder, applyStyle, chalk, chalkStderr, source_default, init_source, require_old, require_fs, require_path, require_balanced_match, require_brace_expansion, require_minimatch, require_inherits_browser2, require_inherits2, require_common3, require_sync, require_wrappy, require_once, require_inflight, require_glob, require_readline, require_src3, require_utils4, require_lodash, require_hanji, originUUID, snapshotVersion, mapValues, mapKeys, mapEntries, customMapEntries, init_global2, util3, objectUtil2, ZodParsedType2, getParsedType2, init_util2, ZodIssueCode2, ZodError3, init_ZodError2, errorMap2, en_default2, init_en2, overrideErrorMap2, init_errors8, makeIssue2, ParseStatus2, INVALID2, DIRTY2, OK2, isAborted2, isDirty2, isValid2, isAsync2, init_parseUtil2, init_typeAliases2, errorUtil2, init_errorUtil2, ParseInputLazyPath2, handleResult2, ZodType2, cuidRegex2, cuid2Regex2, ulidRegex2, uuidRegex2, nanoidRegex2, jwtRegex2, durationRegex2, emailRegex2, _emojiRegex2, emojiRegex2, ipv4Regex2, ipv4CidrRegex2, ipv6Regex2, ipv6CidrRegex2, base64Regex2, base64urlRegex2, dateRegexSource2, dateRegex2, ZodString2, ZodNumber2, ZodBigInt2, ZodBoolean2, ZodDate2, ZodSymbol2, ZodUndefined2, ZodNull2, ZodAny2, ZodUnknown2, ZodNever2, ZodVoid2, ZodArray2, ZodObject2, ZodUnion2, getDiscriminator2, ZodDiscriminatedUnion2, ZodIntersection2, ZodTuple2, ZodRecord2, ZodMap2, ZodSet2, ZodFunction2, ZodLazy2, ZodLiteral2, ZodEnum2, ZodNativeEnum2, ZodPromise2, ZodEffects2, ZodOptional2, ZodNullable2, ZodDefault2, ZodCatch2, ZodNaN2, BRAND2, ZodBranded2, ZodPipeline2, ZodReadonly2, late2, ZodFirstPartyTypeKind2, stringType2, numberType2, nanType2, bigIntType2, booleanType2, dateType2, symbolType2, undefinedType2, nullType2, anyType2, unknownType2, neverType2, voidType2, arrayType2, objectType2, strictObjectType2, unionType2, discriminatedUnionType2, intersectionType2, tupleType2, recordType2, mapType2, setType2, functionType2, lazyType2, literalType2, enumType2, nativeEnumType2, promiseType2, effectsType2, optionalType2, nullableType2, preprocessType2, pipelineType2, coerce2, init_types5, init_external2, init_v32, init_esm2, enumSchema, enumSchemaV1, indexColumn, index2, fk, sequenceSchema, roleSchema, sequenceSquashed, column2, checkConstraint, columnSquashed, compositePK, uniqueConstraint, policy, policySquashed, viewWithOption, matViewWithOption, mergedViewWithOption, view2, table8, schemaHash, kitInternals, gelSchemaExternal, gelSchemaInternal, tableSquashed, gelSchemaSquashed, gelSchema, dryGel, init_gelSchema, index22, fk2, column22, tableV3, compositePK2, uniqueConstraint2, checkConstraint2, tableV4, table22, viewMeta, view22, kitInternals2, dialect2, schemaHash2, schemaInternalV3, schemaInternalV4, schemaInternalV5, schemaInternal, schemaV3, schemaV4, schemaV5, schema2, tableSquashedV4, tableSquashed2, viewSquashed, schemaSquashed, schemaSquashedV4, MySqlSquasher, squashMysqlScheme, mysqlSchema, mysqlSchemaV5, mysqlSchemaSquashed, backwardCompatibleMysqlSchema, dryMySql, init_mysqlSchema, indexV2, columnV2, tableV2, enumSchemaV12, enumSchema2, pgSchemaV2, references, columnV1, tableV1, pgSchemaV1, indexColumn2, index3, indexV4, indexV5, indexV6, fk3, sequenceSchema2, roleSchema2, sequenceSquashed2, columnV7, column3, checkConstraint3, columnSquashed2, tableV32, compositePK3, uniqueConstraint3, policy2, policySquashed2, viewWithOption2, matViewWithOption2, mergedViewWithOption2, view3, tableV42, tableV5, tableV6, tableV7, table32, schemaHash3, kitInternals3, pgSchemaInternalV3, pgSchemaInternalV4, pgSchemaInternalV5, pgSchemaInternalV6, pgSchemaExternal, pgSchemaInternalV7, pgSchemaInternal, tableSquashed3, tableSquashedV42, pgSchemaSquashedV4, pgSchemaSquashedV6, pgSchemaSquashed, pgSchemaV3, pgSchemaV4, pgSchemaV5, pgSchemaV6, pgSchemaV7, pgSchema, backwardCompatiblePgSchema, PgSquasher, squashPgScheme, dryPg, init_pgSchema, index4, column4, compositePK4, uniqueConstraint4, table42, viewMeta2, kitInternals4, dialect22, schemaHash4, schemaInternal2, schema22, tableSquashed4, schemaSquashed2, SingleStoreSquasher, squashSingleStoreScheme, singlestoreSchema, singlestoreSchemaSquashed, backwardCompatibleSingleStoreSchema, drySingleStore, init_singlestoreSchema, index5, fk4, compositePK5, column5, tableV33, uniqueConstraint5, checkConstraint4, table52, view4, dialect3, schemaHash5, schemaInternalV32, schemaInternalV42, schemaInternalV52, kitInternals5, latestVersion, schemaInternal3, schemaV32, schemaV42, schemaV52, schema3, tableSquashed5, schemaSquashed3, SQLiteSquasher, squashSqliteScheme, drySQLite, sqliteSchemaV5, sqliteSchema, SQLiteSchemaSquashed, backwardCompatibleSqliteSchema, init_sqliteSchema, copy, prepareMigrationMeta, schemaRenameKey, tableRenameKey, columnRenameKey, init_utils7, import_hanji, warning, error, isRenamePromptItem, ResolveColumnSelect, tableKey, ResolveSelectNamed, ResolveSelect, ResolveSchemasSelect, Spinner2, ProgressView, init_views, glob, init_serializer, fillPgSnapshot, init_migrationPreparator, require_heap, require_heap2, require_difflib, require_difflib2, require_util2, require_styles, require_has_flag2, require_supports_colors, require_trap, require_zalgo, require_america, require_zebra, require_rainbow, require_random, require_colors, require_safe, require_colorize, require_lib4, import_json_diff, mapArraysDiff, findAlternationsInTable, alternationsInColumn, init_jsonDiffer, parseType, Convertor, PgCreateRoleConvertor, PgDropRoleConvertor, PgRenameRoleConvertor, PgAlterRoleConvertor, PgCreatePolicyConvertor, PgDropPolicyConvertor, PgRenamePolicyConvertor, PgAlterPolicyConvertor, PgCreateIndPolicyConvertor, PgDropIndPolicyConvertor, PgRenameIndPolicyConvertor, PgAlterIndPolicyConvertor, PgEnableRlsConvertor, PgDisableRlsConvertor, PgCreateTableConvertor, MySqlCreateTableConvertor, SingleStoreCreateTableConvertor, SQLiteCreateTableConvertor, PgCreateViewConvertor, MySqlCreateViewConvertor, SqliteCreateViewConvertor, PgDropViewConvertor, MySqlDropViewConvertor, SqliteDropViewConvertor, MySqlAlterViewConvertor, PgRenameViewConvertor, MySqlRenameViewConvertor, PgAlterViewSchemaConvertor, PgAlterViewAddWithOptionConvertor, PgAlterViewDropWithOptionConvertor, PgAlterViewAlterTablespaceConvertor, PgAlterViewAlterUsingConvertor, PgAlterTableAlterColumnSetGenerated, PgAlterTableAlterColumnDropGenerated, PgAlterTableAlterColumnAlterGenerated, PgAlterTableAddUniqueConstraintConvertor, PgAlterTableDropUniqueConstraintConvertor, PgAlterTableAddCheckConstraintConvertor, PgAlterTableDeleteCheckConstraintConvertor, MySQLAlterTableAddUniqueConstraintConvertor, MySQLAlterTableDropUniqueConstraintConvertor, MySqlAlterTableAddCheckConstraintConvertor, SingleStoreAlterTableAddUniqueConstraintConvertor, SingleStoreAlterTableDropUniqueConstraintConvertor, MySqlAlterTableDeleteCheckConstraintConvertor, CreatePgSequenceConvertor, DropPgSequenceConvertor, RenamePgSequenceConvertor, MovePgSequenceConvertor, AlterPgSequenceConvertor, CreateTypeEnumConvertor, DropTypeEnumConvertor, AlterTypeAddValueConvertor, AlterTypeSetSchemaConvertor, AlterRenameTypeConvertor, AlterTypeDropValueConvertor, PgDropTableConvertor, MySQLDropTableConvertor, SingleStoreDropTableConvertor, SQLiteDropTableConvertor, PgRenameTableConvertor, SqliteRenameTableConvertor, MySqlRenameTableConvertor, SingleStoreRenameTableConvertor, PgAlterTableRenameColumnConvertor, MySqlAlterTableRenameColumnConvertor, SingleStoreAlterTableRenameColumnConvertor, SQLiteAlterTableRenameColumnConvertor, PgAlterTableDropColumnConvertor, MySqlAlterTableDropColumnConvertor, SingleStoreAlterTableDropColumnConvertor, SQLiteAlterTableDropColumnConvertor, PgAlterTableAddColumnConvertor, MySqlAlterTableAddColumnConvertor, SingleStoreAlterTableAddColumnConvertor, SQLiteAlterTableAddColumnConvertor, PgAlterTableAlterColumnSetTypeConvertor, PgAlterTableAlterColumnSetDefaultConvertor, PgAlterTableAlterColumnDropDefaultConvertor, PgAlterTableAlterColumnDropGeneratedConvertor, PgAlterTableAlterColumnSetExpressionConvertor, PgAlterTableAlterColumnAlterrGeneratedConvertor, SqliteAlterTableAlterColumnDropGeneratedConvertor, SqliteAlterTableAlterColumnSetExpressionConvertor, SqliteAlterTableAlterColumnAlterGeneratedConvertor, MySqlAlterTableAlterColumnAlterrGeneratedConvertor, MySqlAlterTableAddPk, MySqlAlterTableDropPk, LibSQLModifyColumn, MySqlModifyColumn, SingleStoreAlterTableAlterColumnAlterrGeneratedConvertor, SingleStoreAlterTableAddPk, SingleStoreAlterTableDropPk, SingleStoreModifyColumn, PgAlterTableCreateCompositePrimaryKeyConvertor, PgAlterTableDeleteCompositePrimaryKeyConvertor, PgAlterTableAlterCompositePrimaryKeyConvertor, MySqlAlterTableCreateCompositePrimaryKeyConvertor, MySqlAlterTableDeleteCompositePrimaryKeyConvertor, MySqlAlterTableAlterCompositePrimaryKeyConvertor, PgAlterTableAlterColumnSetPrimaryKeyConvertor, PgAlterTableAlterColumnDropPrimaryKeyConvertor, PgAlterTableAlterColumnSetNotNullConvertor, PgAlterTableAlterColumnDropNotNullConvertor, PgCreateForeignKeyConvertor, LibSQLCreateForeignKeyConvertor, MySqlCreateForeignKeyConvertor, PgAlterForeignKeyConvertor, PgDeleteForeignKeyConvertor, MySqlDeleteForeignKeyConvertor, CreatePgIndexConvertor, CreateMySqlIndexConvertor, CreateSingleStoreIndexConvertor, CreateSqliteIndexConvertor, PgDropIndexConvertor, PgCreateSchemaConvertor, PgRenameSchemaConvertor, PgDropSchemaConvertor, PgAlterTableSetSchemaConvertor, PgAlterTableSetNewSchemaConvertor, PgAlterTableRemoveFromSchemaConvertor, SqliteDropIndexConvertor, MySqlDropIndexConvertor, SingleStoreDropIndexConvertor, SQLiteRecreateTableConvertor, LibSQLRecreateTableConvertor, SingleStoreRecreateTableConvertor, convertors, init_sqlgenerator, _moveDataStatements, getOldTableName, getNewTableName, logSuggestionsAndReturn, init_sqlitePushUtils, preparePgCreateTableJson, prepareMySqlCreateTableJson, prepareSingleStoreCreateTableJson, prepareSQLiteCreateTable, prepareDropTableJson, prepareRenameTableJson, prepareCreateEnumJson, prepareAddValuesToEnumJson, prepareDropEnumValues, prepareDropEnumJson, prepareMoveEnumJson, prepareRenameEnumJson, prepareCreateSequenceJson, prepareAlterSequenceJson, prepareDropSequenceJson, prepareMoveSequenceJson, prepareRenameSequenceJson, prepareCreateRoleJson, prepareAlterRoleJson, prepareDropRoleJson, prepareRenameRoleJson, prepareCreateSchemasJson, prepareRenameSchemasJson, prepareDeleteSchemasJson, prepareRenameColumns, _prepareDropColumns, _prepareAddColumns, _prepareSqliteAddColumns, prepareAlterColumnsMysql, preparePgAlterColumns, prepareSqliteAlterColumns, prepareRenamePolicyJsons, prepareRenameIndPolicyJsons, prepareCreatePolicyJsons, prepareCreateIndPolicyJsons, prepareDropPolicyJsons, prepareDropIndPolicyJsons, prepareAlterPolicyJson, prepareAlterIndPolicyJson, preparePgCreateIndexesJson, prepareCreateIndexesJson, prepareCreateReferencesJson, prepareLibSQLCreateReferencesJson, prepareDropReferencesJson, prepareLibSQLDropReferencesJson, prepareAlterReferencesJson, prepareDropIndexesJson, prepareAddCompositePrimaryKeySqlite, prepareDeleteCompositePrimaryKeySqlite, prepareAlterCompositePrimaryKeySqlite, prepareAddCompositePrimaryKeyPg, prepareDeleteCompositePrimaryKeyPg, prepareAlterCompositePrimaryKeyPg, prepareAddUniqueConstraintPg, prepareDeleteUniqueConstraintPg, prepareAddCheckConstraint, prepareDeleteCheckConstraint, prepareAddCompositePrimaryKeyMySql, prepareDeleteCompositePrimaryKeyMySql, prepareAlterCompositePrimaryKeyMySql, preparePgCreateViewJson, prepareMySqlCreateViewJson, prepareSqliteCreateViewJson, prepareDropViewJson, prepareRenameViewJson, preparePgAlterViewAlterSchemaJson, preparePgAlterViewAddWithOptionJson, preparePgAlterViewDropWithOptionJson, preparePgAlterViewAlterTablespaceJson, preparePgAlterViewAlterUsingJson, prepareMySqlAlterView, init_jsonStatements, prepareLibSQLRecreateTable, prepareSQLiteRecreateTable, libSQLCombineStatements, sqliteCombineStatements, prepareSingleStoreRecreateTable, singleStoreCombineStatements, init_statementCombiner, snapshotsDiffer_exports, makeChanged, makeSelfOrChanged, makePatched, makeSelfOrPatched, columnSchema, alteredColumnSchema, enumSchema3, changedEnumSchema, tableScheme, alteredTableScheme, alteredViewCommon, alteredPgViewSchema, alteredMySqlViewSchema, diffResultScheme, diffResultSchemeMysql, diffResultSchemeSingleStore, diffResultSchemeSQLite, schemaChangeFor, nameChangeFor, nameSchemaChangeFor, columnChangeFor, applyPgSnapshotsDiff, applyMysqlSnapshotsDiff, applySingleStoreSnapshotsDiff, applySqliteSnapshotsDiff, applyLibSQLSnapshotsDiff, init_snapshotsDiffer, init_words, dialects, dialect4, commonSquashedSchema, commonSchema, init_schemaValidator, sqliteDriversLiterals, postgresqlDriversLiterals, prefixes, prefix, casingTypes, casingType, sqliteDriver, postgresDriver, driver2, configMigrations, configCommonSchema, casing, introspectParams, configIntrospectCliSchema, configGenerateSchema, configPushSchema, init_common2, withStyle, init_outputs, import_hanji2, schemasResolver, tablesResolver, viewsResolver, mySqlViewsResolver, sqliteViewsResolver, sequencesResolver, roleResolver, policyResolver, indPolicyResolver, enumsResolver, columnsResolver, promptColumnsConflicts, promptNamedConflict, promptNamedWithSchemasConflict, promptSchemasConflict, BREAKPOINT, init_migrate, posixClasses, braceEscape, regexpEscape, rangesToString, parseClass, init_brace_expressions, escape, init_escape, unescape, init_unescape, import_brace_expansion, minimatch, starDotExtRE, starDotExtTest, starDotExtTestDot, starDotExtTestNocase, starDotExtTestNocaseDot, starDotStarRE, starDotStarTest, starDotStarTestDot, dotStarRE, dotStarTest, starRE, starTest, starTestDot, qmarksRE, qmarksTestNocase, qmarksTestNocaseDot, qmarksTestDot, qmarksTest, qmarksTestNoExt, qmarksTestNoExtDot, defaultPlatform, path, sep, GLOBSTAR, plTypes, qmark, star, twoStarDot, twoStarNoDot, charSet, reSpecials, addPatternStartSet, filter, ext, defaults, braceExpand, MAX_PATTERN_LENGTH, assertValidPattern, makeRe, match2, globUnescape, globMagic, regExpEscape, Minimatch, init_mjs, entityKind2, hasOwnEntityKind2, init_entity2, _a, Column2, init_column2, _a2, ColumnBuilder2, init_column_builder2, TableName2, init_table_utils2, _a3, ForeignKeyBuilder2, _a4, ForeignKey2, init_foreign_keys2, init_tracing_utils2, _a5, UniqueConstraintBuilder, _a6, UniqueOnConstraintBuilder, _a7, UniqueConstraint, init_unique_constraint2, init_array2, _a8, _b, PgColumnBuilder2, _a9, _b2, PgColumn2, _a10, _b3, ExtraConfigColumn2, _a11, IndexedColumn2, _a12, _b4, PgArrayBuilder2, _a13, _b5, _PgArray, PgArray2, init_common22, _a14, _b6, PgEnumObjectColumnBuilder2, _a15, _b7, PgEnumObjectColumn2, isPgEnumSym2, _a16, _b8, PgEnumColumnBuilder2, _a17, _b9, PgEnumColumn2, init_enum2, _a18, Subquery2, _a19, _b10, WithSubquery2, init_subquery2, version2, init_version2, otel2, rawTracer2, tracer2, init_tracing2, ViewBaseConfig2, init_view_common3, Schema2, Columns2, ExtraConfigColumns2, OriginalName2, BaseName2, IsAlias2, ExtraConfigBuilder2, IsDrizzleTable2, _a20, _b11, _c, _d, _e3, _f, _g, _h, _i, _j, Table2, init_table8, _a21, FakePrimitiveParam, _a22, StringChunk2, _a23, _SQL, SQL2, _a24, Name2, noopDecoder2, noopEncoder2, noopMapper2, _a25, Param2, _a26, Placeholder2, IsDrizzleView2, _a27, _b12, _c2, View3, init_sql3, _a28, ColumnAliasProxyHandler2, _a29, TableAliasProxyHandler2, _a30, RelationTableAliasProxyHandler, init_alias3, _a31, _b13, DrizzleError2, DrizzleQueryError, _a32, _b14, TransactionRollbackError2, init_errors22, _a33, ConsoleLogWriter2, _a34, DefaultLogger2, _a35, NoopLogger2, init_logger3, init_operations, _a36, _b15, QueryPromise2, init_query_promise2, textDecoder, init_utils22, _a37, _b16, PgIntColumnBaseBuilder2, init_int_common2, _a38, _b17, PgBigInt53Builder2, _a39, _b18, PgBigInt532, _a40, _b19, PgBigInt64Builder2, _a41, _b20, PgBigInt642, init_bigint2, _a42, _b21, PgBigSerial53Builder2, _a43, _b22, PgBigSerial532, _a44, _b23, PgBigSerial64Builder2, _a45, _b24, PgBigSerial642, init_bigserial2, _a46, _b25, PgBooleanBuilder2, _a47, _b26, PgBoolean2, init_boolean2, _a48, _b27, PgCharBuilder2, _a49, _b28, PgChar2, init_char2, _a50, _b29, PgCidrBuilder2, _a51, _b30, PgCidr2, init_cidr2, _a52, _b31, PgCustomColumnBuilder2, _a53, _b32, PgCustomColumn2, init_custom2, _a54, _b33, PgDateColumnBaseBuilder2, init_date_common2, _a55, _b34, PgDateBuilder2, _a56, _b35, PgDate2, _a57, _b36, PgDateStringBuilder2, _a58, _b37, PgDateString2, init_date2, _a59, _b38, PgDoublePrecisionBuilder2, _a60, _b39, PgDoublePrecision2, init_double_precision2, _a61, _b40, PgInetBuilder2, _a62, _b41, PgInet2, init_inet2, _a63, _b42, PgIntegerBuilder2, _a64, _b43, PgInteger2, init_integer2, _a65, _b44, PgIntervalBuilder2, _a66, _b45, PgInterval2, init_interval2, _a67, _b46, PgJsonBuilder2, _a68, _b47, PgJson2, init_json2, _a69, _b48, PgJsonbBuilder2, _a70, _b49, PgJsonb2, init_jsonb2, _a71, _b50, PgLineBuilder2, _a72, _b51, PgLineTuple2, _a73, _b52, PgLineABCBuilder2, _a74, _b53, PgLineABC2, init_line2, _a75, _b54, PgMacaddrBuilder2, _a76, _b55, PgMacaddr2, init_macaddr2, _a77, _b56, PgMacaddr8Builder2, _a78, _b57, PgMacaddr82, init_macaddr82, _a79, _b58, PgNumericBuilder2, _a80, _b59, PgNumeric2, _a81, _b60, PgNumericNumberBuilder2, _a82, _b61, PgNumericNumber2, _a83, _b62, PgNumericBigIntBuilder2, _a84, _b63, PgNumericBigInt2, init_numeric2, _a85, _b64, PgPointTupleBuilder2, _a86, _b65, PgPointTuple2, _a87, _b66, PgPointObjectBuilder2, _a88, _b67, PgPointObject2, init_point2, init_utils32, _a89, _b68, PgGeometryBuilder2, _a90, _b69, PgGeometry2, _a91, _b70, PgGeometryObjectBuilder2, _a92, _b71, PgGeometryObject2, init_geometry2, _a93, _b72, PgRealBuilder2, _a94, _b73, PgReal2, init_real2, _a95, _b74, PgSerialBuilder2, _a96, _b75, PgSerial2, init_serial2, _a97, _b76, PgSmallIntBuilder2, _a98, _b77, PgSmallInt2, init_smallint2, _a99, _b78, PgSmallSerialBuilder2, _a100, _b79, PgSmallSerial2, init_smallserial2, _a101, _b80, PgTextBuilder2, _a102, _b81, PgText2, init_text2, _a103, _b82, PgTimeBuilder2, _a104, _b83, PgTime2, init_time2, _a105, _b84, PgTimestampBuilder2, _a106, _b85, PgTimestamp2, _a107, _b86, PgTimestampStringBuilder2, _a108, _b87, PgTimestampString2, init_timestamp2, _a109, _b88, PgUUIDBuilder2, _a110, _b89, PgUUID2, init_uuid3, _a111, _b90, PgVarcharBuilder2, _a112, _b91, PgVarchar2, init_varchar2, _a113, _b92, PgBinaryVectorBuilder2, _a114, _b93, PgBinaryVector2, init_bit2, _a115, _b94, PgHalfVectorBuilder2, _a116, _b95, PgHalfVector2, init_halfvec2, _a117, _b96, PgSparseVectorBuilder2, _a118, _b97, PgSparseVector2, init_sparsevec2, _a119, _b98, PgVectorBuilder2, _a120, _b99, PgVector2, init_vector3, init_all2, InlineForeignKeys2, EnableRLS2, _a121, _b100, _c3, _d2, _e22, _f2, PgTable2, pgTable2, init_table22, _a122, PrimaryKeyBuilder2, _a123, PrimaryKey2, init_primary_keys2, eq2, ne4, gt3, gte2, lt4, lte2, init_conditions2, init_select3, init_expressions2, _a124, Relation2, _a125, Relations2, _a126, _b101, _One, One2, _a127, _b102, _Many, Many2, init_relations2, init_aggregate2, init_vector22, init_functions2, init_sql22, dist_exports, init_dist6, init_alias22, _a128, CheckBuilder, _a129, Check, init_checks2, init_columns2, _a130, _SelectionProxyHandler, SelectionProxyHandler2, init_selection_proxy2, _a131, IndexBuilderOn2, _a132, IndexBuilder2, _a133, Index2, init_indexes2, _a134, PgPolicy, init_policies2, PgViewConfig2, init_view_common22, _a135, CasingCache2, init_casing2, _a136, _b103, PgViewBase2, init_view_base2, _a137, PgDialect2, init_dialect2, _a138, TypedQueryBuilder2, init_query_builder3, _a139, PgSelectBuilder2, _a140, _b104, PgSelectQueryBuilderBase2, _a141, _b105, PgSelectBase2, getPgSetOperators2, union2, unionAll2, intersect2, intersectAll2, except2, exceptAll2, init_select22, _a142, QueryBuilder2, init_query_builder22, _a143, DefaultViewBuilderCore, _a144, _b106, ViewBuilder, _a145, _b107, ManualViewBuilder, _a146, MaterializedViewBuilderCore, _a147, _b108, MaterializedViewBuilder, _a148, _b109, ManualMaterializedViewBuilder, _a149, _b110, _c4, PgView2, PgMaterializedViewConfig2, _a150, _b111, _c5, PgMaterializedView, init_view2, init_utils42, _a151, _b112, PgDeleteBase2, init_delete2, _a152, PgInsertBuilder2, _a153, _b113, PgInsertBase2, init_insert2, _a154, _b114, PgRefreshMaterializedView2, init_refresh_materialized_view2, init_select_types, _a155, PgUpdateBuilder2, _a156, _b115, PgUpdateBase2, init_update2, init_query_builders2, _a157, _b116, _c6, _PgCountBuilder, PgCountBuilder2, init_count2, _a158, RelationalQueryBuilder2, _a159, _b117, PgRelationalQuery2, init_query2, _a160, _b118, PgRaw2, init_raw2, _a161, PgDatabase2, init_db2, _a162, PgRole, init_roles2, _a163, PgSequence, init_sequence2, _a164, PgSchema5, init_schema3, _a165, Cache, _a166, _b119, NoopCache, init_cache, _a167, PgPreparedQuery2, _a168, PgSession2, _a169, _b120, PgTransaction2, init_session3, init_subquery22, init_utils52, init_pg_core2, vectorOps, init_vector32, sqlToStr, init_utils62, indexName, generatePgSnapshot, trimChar, fromDatabase, defaultForColumn, getColumnsInfoQuery, init_pgSerializer, import_hanji4, Select, init_selector_ui, init_alias32, _a170, CheckBuilder2, _a171, Check2, init_checks22, _a172, ForeignKeyBuilder22, _a173, ForeignKey22, init_foreign_keys22, _a174, UniqueConstraintBuilder2, _a175, UniqueOnConstraintBuilder2, _a176, UniqueConstraint2, init_unique_constraint22, _a177, _b121, SQLiteColumnBuilder, _a178, _b122, SQLiteColumn, init_common3, _a179, _b123, SQLiteBigIntBuilder, _a180, _b124, SQLiteBigInt, _a181, _b125, SQLiteBlobJsonBuilder, _a182, _b126, SQLiteBlobJson, _a183, _b127, SQLiteBlobBufferBuilder, _a184, _b128, SQLiteBlobBuffer, init_blob, _a185, _b129, SQLiteCustomColumnBuilder, _a186, _b130, SQLiteCustomColumn, init_custom22, _a187, _b131, SQLiteBaseIntegerBuilder, _a188, _b132, SQLiteBaseInteger, _a189, _b133, SQLiteIntegerBuilder, _a190, _b134, SQLiteInteger, _a191, _b135, SQLiteTimestampBuilder, _a192, _b136, SQLiteTimestamp, _a193, _b137, SQLiteBooleanBuilder, _a194, _b138, SQLiteBoolean, init_integer22, _a195, _b139, SQLiteNumericBuilder, _a196, _b140, SQLiteNumeric, _a197, _b141, SQLiteNumericNumberBuilder, _a198, _b142, SQLiteNumericNumber, _a199, _b143, SQLiteNumericBigIntBuilder, _a200, _b144, SQLiteNumericBigInt, init_numeric22, _a201, _b145, SQLiteRealBuilder, _a202, _b146, SQLiteReal, init_real22, _a203, _b147, SQLiteTextBuilder, _a204, _b148, SQLiteText, _a205, _b149, SQLiteTextJsonBuilder, _a206, _b150, SQLiteTextJson, init_text22, init_columns22, init_all22, InlineForeignKeys22, _a207, _b151, _c7, _d3, _e32, SQLiteTable, sqliteTable, init_table32, _a208, IndexBuilderOn22, _a209, IndexBuilder22, _a210, Index4, init_indexes22, _a211, PrimaryKeyBuilder22, _a212, PrimaryKey22, init_primary_keys22, init_utils72, _a213, _b152, SQLiteDeleteBase, init_delete22, _a214, _b153, SQLiteViewBase, init_view_base22, _a215, SQLiteDialect, _a216, _b154, SQLiteSyncDialect, _a217, _b155, SQLiteAsyncDialect, init_dialect22, _a218, SQLiteSelectBuilder, _a219, _b156, SQLiteSelectQueryBuilderBase, _a220, _b157, SQLiteSelectBase, getSQLiteSetOperators, union3, unionAll22, intersect22, except22, init_select32, _a221, QueryBuilder22, init_query_builder32, _a222, SQLiteInsertBuilder, _a223, _b158, SQLiteInsertBase, init_insert22, init_select_types2, _a224, SQLiteUpdateBuilder, _a225, _b159, SQLiteUpdateBase, init_update22, init_query_builders22, _a226, _b160, _c8, _SQLiteCountBuilder, SQLiteCountBuilder, init_count22, _a227, RelationalQueryBuilder22, _a228, _b161, SQLiteRelationalQuery, _a229, _b162, SQLiteSyncRelationalQuery, init_query22, _a230, _b163, SQLiteRaw, init_raw22, _a231, BaseSQLiteDatabase, init_db22, _a232, _b164, ExecuteResultSync, _a233, SQLitePreparedQuery, _a234, SQLiteSession, _a235, _b165, SQLiteTransaction, init_session22, init_subquery3, _a236, ViewBuilderCore, _a237, _b166, ViewBuilder2, _a238, _b167, ManualViewBuilder2, _a239, _b168, SQLiteView2, init_view22, init_sqlite_core, generateSqliteSnapshot, fromDatabase2, init_sqliteSerializer, getTablesFilterByExtensions, init_getTablesFilterByExtensions, init_alias4, _a240, CheckBuilder3, _a241, Check3, init_checks3, _a242, ForeignKeyBuilder3, _a243, ForeignKey3, init_foreign_keys3, _a244, UniqueConstraintBuilder3, _a245, UniqueOnConstraintBuilder3, _a246, UniqueConstraint3, init_unique_constraint3, _a247, _b169, MySqlColumnBuilder, _a248, _b170, MySqlColumn, _a249, _b171, MySqlColumnBuilderWithAutoIncrement, _a250, _b172, MySqlColumnWithAutoIncrement, init_common4, _a251, _b173, MySqlBigInt53Builder, _a252, _b174, MySqlBigInt53, _a253, _b175, MySqlBigInt64Builder, _a254, _b176, MySqlBigInt64, init_bigint22, _a255, _b177, MySqlBinaryBuilder, _a256, _b178, MySqlBinary, init_binary, _a257, _b179, MySqlBooleanBuilder, _a258, _b180, MySqlBoolean, init_boolean22, _a259, _b181, MySqlCharBuilder, _a260, _b182, MySqlChar, init_char22, _a261, _b183, MySqlCustomColumnBuilder, _a262, _b184, MySqlCustomColumn, init_custom3, _a263, _b185, MySqlDateBuilder, _a264, _b186, MySqlDate, _a265, _b187, MySqlDateStringBuilder, _a266, _b188, MySqlDateString, init_date22, _a267, _b189, MySqlDateTimeBuilder, _a268, _b190, MySqlDateTime, _a269, _b191, MySqlDateTimeStringBuilder, _a270, _b192, MySqlDateTimeString, init_datetime, _a271, _b193, MySqlDecimalBuilder, _a272, _b194, MySqlDecimal, _a273, _b195, MySqlDecimalNumberBuilder, _a274, _b196, MySqlDecimalNumber, _a275, _b197, MySqlDecimalBigIntBuilder, _a276, _b198, MySqlDecimalBigInt, init_decimal, _a277, _b199, MySqlDoubleBuilder, _a278, _b200, MySqlDouble, init_double, _a279, _b201, MySqlEnumColumnBuilder, _a280, _b202, MySqlEnumColumn, _a281, _b203, MySqlEnumObjectColumnBuilder, _a282, _b204, MySqlEnumObjectColumn, init_enum22, _a283, _b205, MySqlFloatBuilder, _a284, _b206, MySqlFloat, init_float, _a285, _b207, MySqlIntBuilder, _a286, _b208, MySqlInt, init_int, _a287, _b209, MySqlJsonBuilder, _a288, _b210, MySqlJson, init_json22, _a289, _b211, MySqlMediumIntBuilder, _a290, _b212, MySqlMediumInt, init_mediumint, _a291, _b213, MySqlRealBuilder, _a292, _b214, MySqlReal, init_real3, _a293, _b215, MySqlSerialBuilder, _a294, _b216, MySqlSerial, init_serial22, _a295, _b217, MySqlSmallIntBuilder, _a296, _b218, MySqlSmallInt, init_smallint22, _a297, _b219, MySqlTextBuilder, _a298, _b220, MySqlText, init_text3, _a299, _b221, MySqlTimeBuilder, _a300, _b222, MySqlTime, init_time22, _a301, _b223, MySqlDateColumnBaseBuilder, _a302, _b224, MySqlDateBaseColumn, init_date_common22, _a303, _b225, MySqlTimestampBuilder, _a304, _b226, MySqlTimestamp, _a305, _b227, MySqlTimestampStringBuilder, _a306, _b228, MySqlTimestampString, init_timestamp22, _a307, _b229, MySqlTinyIntBuilder, _a308, _b230, MySqlTinyInt, init_tinyint, _a309, _b231, MySqlVarBinaryBuilder, _a310, _b232, MySqlVarBinary, init_varbinary, _a311, _b233, MySqlVarCharBuilder, _a312, _b234, MySqlVarChar, init_varchar22, _a313, _b235, MySqlYearBuilder, _a314, _b236, MySqlYear, init_year, init_columns3, _a315, _b237, _c9, _MySqlCountBuilder, MySqlCountBuilder, init_count3, _a316, IndexBuilderOn3, _a317, IndexBuilder3, _a318, Index5, init_indexes3, init_all3, InlineForeignKeys3, _a319, _b238, _c10, _d4, _e4, MySqlTable, mysqlTable, init_table42, _a320, PrimaryKeyBuilder3, _a321, PrimaryKey3, init_primary_keys3, MySqlViewConfig, init_view_common32, init_utils8, _a322, _b239, MySqlDeleteBase, init_delete3, _a323, _b240, MySqlViewBase, init_view_base3, _a324, MySqlDialect, init_dialect3, _a325, MySqlSelectBuilder, _a326, _b241, MySqlSelectQueryBuilderBase, _a327, _b242, MySqlSelectBase, getMySqlSetOperators, union4, unionAll3, intersect3, intersectAll22, except3, exceptAll22, init_select4, _a328, QueryBuilder3, init_query_builder4, _a329, MySqlInsertBuilder, _a330, _b243, MySqlInsertBase, init_insert3, init_select_types3, _a331, MySqlUpdateBuilder, _a332, _b244, MySqlUpdateBase, init_update3, init_query_builders3, _a333, RelationalQueryBuilder3, _a334, _b245, MySqlRelationalQuery, init_query3, _a335, MySqlDatabase, init_db3, _a336, ViewBuilderCore2, _a337, _b246, ViewBuilder3, _a338, _b247, ManualViewBuilder3, _a339, _b248, _c11, MySqlView2, init_view3, _a340, MySqlSchema5, init_schema22, _a341, MySqlPreparedQuery, _a342, MySqlSession, _a343, _b249, MySqlTransaction, init_session32, init_subquery4, init_mysql_core, handleEnumType, generateMySqlSnapshot, fromDatabase3, init_mysqlSerializer, cliConfigGenerate, pushParams, pullParams, configCheck, cliConfigCheck, init_cli, gelCredentials, init_gel, libSQLCredentials, init_libsql, mysqlCredentials, init_mysql, postgresCredentials, init_postgres, singlestoreCredentials, init_singlestore, sqliteCredentials, init_sqlite, credentials, studioCliParams, studioConfig, init_studio, es5_exports, _3, es5_default, init_es5, import_hanji7, assertES5, safeRegister, migrateConfig, init_utils9, prepareFromExports, init_pgImports, init_alias5, _a344, UniqueConstraintBuilder4, _a345, UniqueOnConstraintBuilder4, _a346, UniqueConstraint4, init_unique_constraint4, _a347, _b250, SingleStoreColumnBuilder, _a348, _b251, SingleStoreColumn, _a349, _b252, SingleStoreColumnBuilderWithAutoIncrement, _a350, _b253, SingleStoreColumnWithAutoIncrement, init_common5, _a351, _b254, SingleStoreBigInt53Builder, _a352, _b255, SingleStoreBigInt53, _a353, _b256, SingleStoreBigInt64Builder, _a354, _b257, SingleStoreBigInt64, init_bigint3, _a355, _b258, SingleStoreBinaryBuilder, _a356, _b259, SingleStoreBinary, init_binary2, _a357, _b260, SingleStoreBooleanBuilder, _a358, _b261, SingleStoreBoolean, init_boolean3, _a359, _b262, SingleStoreCharBuilder, _a360, _b263, SingleStoreChar, init_char3, _a361, _b264, SingleStoreCustomColumnBuilder, _a362, _b265, SingleStoreCustomColumn, init_custom4, _a363, _b266, SingleStoreDateBuilder, _a364, _b267, SingleStoreDate, _a365, _b268, SingleStoreDateStringBuilder, _a366, _b269, SingleStoreDateString, init_date3, _a367, _b270, SingleStoreDateTimeBuilder, _a368, _b271, SingleStoreDateTime, _a369, _b272, SingleStoreDateTimeStringBuilder, _a370, _b273, SingleStoreDateTimeString, init_datetime2, _a371, _b274, SingleStoreDecimalBuilder, _a372, _b275, SingleStoreDecimal, _a373, _b276, SingleStoreDecimalNumberBuilder, _a374, _b277, SingleStoreDecimalNumber, _a375, _b278, SingleStoreDecimalBigIntBuilder, _a376, _b279, SingleStoreDecimalBigInt, init_decimal2, _a377, _b280, SingleStoreDoubleBuilder, _a378, _b281, SingleStoreDouble, init_double2, _a379, _b282, SingleStoreEnumColumnBuilder, _a380, _b283, SingleStoreEnumColumn, init_enum3, _a381, _b284, SingleStoreFloatBuilder, _a382, _b285, SingleStoreFloat, init_float2, _a383, _b286, SingleStoreIntBuilder, _a384, _b287, SingleStoreInt, init_int2, _a385, _b288, SingleStoreJsonBuilder, _a386, _b289, SingleStoreJson, init_json3, _a387, _b290, SingleStoreMediumIntBuilder, _a388, _b291, SingleStoreMediumInt, init_mediumint2, _a389, _b292, SingleStoreRealBuilder, _a390, _b293, SingleStoreReal, init_real4, _a391, _b294, SingleStoreSerialBuilder, _a392, _b295, SingleStoreSerial, init_serial3, _a393, _b296, SingleStoreSmallIntBuilder, _a394, _b297, SingleStoreSmallInt, init_smallint3, _a395, _b298, SingleStoreTextBuilder, _a396, _b299, SingleStoreText, init_text4, _a397, _b300, SingleStoreTimeBuilder, _a398, _b301, SingleStoreTime, init_time3, _a399, _b302, SingleStoreDateColumnBaseBuilder, _a400, _b303, SingleStoreDateBaseColumn, init_date_common3, _a401, _b304, SingleStoreTimestampBuilder, _a402, _b305, SingleStoreTimestamp, _a403, _b306, SingleStoreTimestampStringBuilder, _a404, _b307, SingleStoreTimestampString, init_timestamp3, _a405, _b308, SingleStoreTinyIntBuilder, _a406, _b309, SingleStoreTinyInt, init_tinyint2, _a407, _b310, SingleStoreVarBinaryBuilder, _a408, _b311, SingleStoreVarBinary, init_varbinary2, _a409, _b312, SingleStoreVarCharBuilder, _a410, _b313, SingleStoreVarChar, init_varchar3, _a411, _b314, SingleStoreVectorBuilder, _a412, _b315, SingleStoreVector, init_vector4, _a413, _b316, SingleStoreYearBuilder, _a414, _b317, SingleStoreYear, init_year2, init_columns4, _a415, _b318, _c12, _SingleStoreCountBuilder, SingleStoreCountBuilder, init_count4, _a416, IndexBuilderOn4, _a417, IndexBuilder4, _a418, Index6, init_indexes4, init_all4, _a419, _b319, _c13, _d5, SingleStoreTable, init_table52, _a420, PrimaryKeyBuilder4, _a421, PrimaryKey4, init_primary_keys4, init_utils10, _a422, _b320, SingleStoreDeleteBase, init_delete4, _a423, SingleStoreInsertBuilder, _a424, _b321, SingleStoreInsertBase, init_insert4, _a425, SingleStoreDialect, init_dialect4, _a426, SingleStoreSelectBuilder, _a427, _b322, SingleStoreSelectQueryBuilderBase, _a428, _b323, SingleStoreSelectBase, getSingleStoreSetOperators, union5, unionAll4, intersect4, except4, minus, init_select5, _a429, QueryBuilder4, init_query_builder5, init_select_types4, _a430, SingleStoreUpdateBuilder, _a431, _b324, SingleStoreUpdateBase, init_update4, init_query_builders4, _a432, SingleStoreDatabase, init_db4, _a433, SingleStoreSchema5, init_schema32, _a434, SingleStorePreparedQuery, _a435, SingleStoreSession, _a436, _b325, SingleStoreTransaction, init_session4, init_subquery5, init_singlestore_core, dialect5, generateSingleStoreSnapshot, fromDatabase4, init_singlestoreSerializer, sqliteImports_exports, prepareFromExports2, prepareFromSqliteImports, init_sqliteImports, mysqlImports_exports, prepareFromExports3, prepareFromMySqlImports, init_mysqlImports, mysqlPushUtils_exports, import_hanji8, filterStatements, logSuggestionsAndReturn2, init_mysqlPushUtils, mysqlIntrospect_exports, import_hanji9, mysqlPushIntrospect, init_mysqlIntrospect, singlestoreImports_exports, prepareFromExports4, prepareFromSingleStoreImports, init_singlestoreImports, singlestorePushUtils_exports, import_hanji10, filterStatements2, logSuggestionsAndReturn3, init_singlestorePushUtils, singlestoreIntrospect_exports, import_hanji11, singlestorePushIntrospect, init_singlestoreIntrospect, import_hanji3, pgPushIntrospect = async (db2, filters, schemaFilters, entities, tsSchema) => {
58053
58576
  const matchers = filters.map((it3) => {
58054
58577
  return new Minimatch(it3);
58055
58578
  });
@@ -61948,7 +62471,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
61948
62471
  en_default2 = errorMap2;
61949
62472
  }
61950
62473
  });
61951
- init_errors5 = __esm7({
62474
+ init_errors8 = __esm7({
61952
62475
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/errors.js"() {
61953
62476
  init_en2();
61954
62477
  overrideErrorMap2 = en_default2;
@@ -61956,7 +62479,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
61956
62479
  });
61957
62480
  init_parseUtil2 = __esm7({
61958
62481
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/helpers/parseUtil.js"() {
61959
- init_errors5();
62482
+ init_errors8();
61960
62483
  init_en2();
61961
62484
  makeIssue2 = (params) => {
61962
62485
  const { data, path: path2, errorMaps, issueData } = params;
@@ -62062,7 +62585,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
62062
62585
  init_types5 = __esm7({
62063
62586
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/types.js"() {
62064
62587
  init_ZodError2();
62065
- init_errors5();
62588
+ init_errors8();
62066
62589
  init_errorUtil2();
62067
62590
  init_parseUtil2();
62068
62591
  init_util2();
@@ -65220,7 +65743,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
65220
65743
  });
65221
65744
  init_external2 = __esm7({
65222
65745
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/external.js"() {
65223
- init_errors5();
65746
+ init_errors8();
65224
65747
  init_parseUtil2();
65225
65748
  init_typeAliases2();
65226
65749
  init_util2();
@@ -95882,7 +96405,7 @@ async function seedTimebackIntegrations(db2, gameId, courses) {
95882
96405
  const courseId = course.courseId || `mock-${course.subject.toLowerCase()}-g${course.grade}`;
95883
96406
  try {
95884
96407
  const existing = await db2.query.gameTimebackIntegrations.findFirst({
95885
- where: (table9, { and: and3, eq: eq3 }) => and3(eq3(table9.gameId, gameId), eq3(table9.grade, course.grade), eq3(table9.subject, course.subject))
96408
+ where: (table9, { and: and3, eq: eq3 }) => and3(eq3(table9.gameId, gameId), eq3(table9.grade, course.grade), eq3(table9.subject, course.subject), isActiveGameTimebackIntegrationStatus(table9.status))
95886
96409
  });
95887
96410
  if (!existing) {
95888
96411
  await db2.insert(gameTimebackIntegrations).values({
@@ -95902,6 +96425,7 @@ async function seedTimebackIntegrations(db2, gameId, courses) {
95902
96425
  return seededCount;
95903
96426
  }
95904
96427
  var init_timeback5 = __esm(() => {
96428
+ init_helpers_index();
95905
96429
  init_tables_index();
95906
96430
  init_config();
95907
96431
  });
@@ -97136,7 +97660,7 @@ var init_game_member_controller = __esm(() => {
97136
97660
  });
97137
97661
 
97138
97662
  // ../api-core/src/controllers/game.controller.ts
97139
- var list2, listAccessible, getSubjects, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove2, games2;
97663
+ var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove2, games2;
97140
97664
  var init_game_controller = __esm(() => {
97141
97665
  init_esm();
97142
97666
  init_schemas_index();
@@ -97145,6 +97669,7 @@ var init_game_controller = __esm(() => {
97145
97669
  list2 = requireNonAnonymous(async (ctx) => ctx.services.game.list(ctx.user));
97146
97670
  listAccessible = requireNonAnonymous(async (ctx) => ctx.services.game.listAccessible(ctx.user));
97147
97671
  getSubjects = requireNonAnonymous(async (ctx) => ctx.services.game.getSubjects());
97672
+ getTimebackSummaries = requireGameManagementAccess(async (ctx) => ctx.services.game.getTimebackSummaries(ctx.user));
97148
97673
  getById = requireNonAnonymous(async (ctx) => {
97149
97674
  const gameId = requireGameId(ctx.params.gameId);
97150
97675
  return ctx.services.game.getById(gameId, ctx.user);
@@ -97192,6 +97717,7 @@ var init_game_controller = __esm(() => {
97192
97717
  list: list2,
97193
97718
  listAccessible,
97194
97719
  getSubjects,
97720
+ getTimebackSummaries,
97195
97721
  getById,
97196
97722
  getManifest,
97197
97723
  getBySlug,
@@ -97583,7 +98109,7 @@ var init_session_controller = __esm(() => {
97583
98109
  });
97584
98110
 
97585
98111
  // ../api-core/src/controllers/timeback.controller.ts
97586
- var populateStudent, getUser, getUserEnrollments, getUserById, setupIntegration, getIntegrations, updateIntegration, getIntegrationConfig, verifyIntegration, getConfig, deleteIntegrations, endActivity, heartbeat, advanceCourse, unenrollCourse, getStudentXp, getStudentMastery, getStudentHighestGradeMastered, getRoster, getStudentOverview, getGameMetrics, getStudentActivity, getGradeLevelTestResults, getGradeLevelTestReview, getActivityDetail, listMetricDiscrepancies, verifyMetricDiscrepancy, grantXp, adjustTime, adjustMastery, reconcileMasteryForConfigChange, searchStudents, enrollStudent, unenrollStudent, reactivateEnrollment, listAssessments, createAssessment, deleteAssessment, reorderAssessments, reorderQuestions, activateAssessment, deactivateAssessment, listQuestions, createQuestion, updateQuestion, deleteQuestion, getAssessmentBankStatus, destroyAssessmentBank, timeback2;
98112
+ var populateStudent, getUser, getUserEnrollments, getUserById, setupIntegration, getIntegrations, getRemovedIntegrations, createIntegration, updateIntegration, deactivateCourse, reactivateCourse, getIntegrationConfig, verifyIntegration, getConfig, deleteIntegrations, endActivity, heartbeat, advanceCourse, unenrollCourse, getStudentXp, getStudentMastery, getStudentHighestGradeMastered, getRoster, getStudentOverview, getGameMetrics, getStudentActivity, getGradeLevelTestResults, getGradeLevelTestReview, getActivityDetail, listMetricDiscrepancies, verifyMetricDiscrepancy, grantXp, adjustTime, adjustMastery, reconcileMasteryForConfigChange, searchStudents, enrollStudent, unenrollStudent, reactivateEnrollment, listAssessments, createAssessment, deleteAssessment, reorderAssessments, reorderQuestions, activateAssessment, deactivateAssessment, listQuestions, createQuestion, updateQuestion, deleteQuestion, getAssessmentBankStatus, destroyAssessmentBank, timeback2;
97587
98113
  var init_timeback_controller = __esm(() => {
97588
98114
  init_esm();
97589
98115
  init_schemas_index();
@@ -97639,6 +98165,27 @@ var init_timeback_controller = __esm(() => {
97639
98165
  }
97640
98166
  return ctx.services.timeback.getIntegrations(gameId, ctx.user);
97641
98167
  });
98168
+ getRemovedIntegrations = requireGameManagementAccess(async (ctx) => {
98169
+ const gameId = ctx.params.gameId;
98170
+ if (!gameId) {
98171
+ throw ApiError.badRequest("Missing gameId");
98172
+ }
98173
+ if (!isValidUUID(gameId)) {
98174
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98175
+ }
98176
+ return ctx.services.timeback.getRemovedIntegrations(gameId, ctx.user);
98177
+ });
98178
+ createIntegration = requireDeveloper(async (ctx) => {
98179
+ const gameId = ctx.params.gameId;
98180
+ if (!gameId) {
98181
+ throw ApiError.badRequest("Missing gameId");
98182
+ }
98183
+ if (!isValidUUID(gameId)) {
98184
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98185
+ }
98186
+ const body2 = await parseRequestBody(ctx.request, CreateGameTimebackIntegrationRequestSchema);
98187
+ return ctx.services.timeback.createIntegration(gameId, ctx.user, body2);
98188
+ });
97642
98189
  updateIntegration = requireDeveloper(async (ctx) => {
97643
98190
  const { gameId, courseId } = ctx.params;
97644
98191
  if (!gameId || !courseId) {
@@ -97650,6 +98197,26 @@ var init_timeback_controller = __esm(() => {
97650
98197
  const body2 = await parseRequestBody(ctx.request, UpdateGameTimebackIntegrationRequestSchema);
97651
98198
  return ctx.services.timeback.updateIntegration(gameId, courseId, ctx.user, body2);
97652
98199
  });
98200
+ deactivateCourse = requireDeveloper(async (ctx) => {
98201
+ const { gameId, courseId } = ctx.params;
98202
+ if (!gameId || !courseId) {
98203
+ throw ApiError.badRequest("Missing gameId or courseId parameter");
98204
+ }
98205
+ if (!isValidUUID(gameId)) {
98206
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98207
+ }
98208
+ return ctx.services.timeback.deactivateCourse(gameId, courseId, ctx.user);
98209
+ });
98210
+ reactivateCourse = requireDeveloper(async (ctx) => {
98211
+ const { gameId, courseId } = ctx.params;
98212
+ if (!gameId || !courseId) {
98213
+ throw ApiError.badRequest("Missing gameId or courseId parameter");
98214
+ }
98215
+ if (!isValidUUID(gameId)) {
98216
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98217
+ }
98218
+ return ctx.services.timeback.reactivateCourse(gameId, courseId, ctx.user);
98219
+ });
97653
98220
  getIntegrationConfig = requireGameManagementAccess(async (ctx) => {
97654
98221
  const { gameId, courseId } = ctx.params;
97655
98222
  if (!gameId || !courseId) {
@@ -97799,11 +98366,11 @@ var init_timeback_controller = __esm(() => {
97799
98366
  let subject;
97800
98367
  if (gradeParam !== null && subjectParam !== null) {
97801
98368
  const parsedGrade = parseInt(gradeParam, 10);
97802
- if (!isTimebackGrade(parsedGrade)) {
98369
+ if (!isTimebackGrade2(parsedGrade)) {
97803
98370
  throw ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
97804
98371
  }
97805
- if (!isTimebackSubject(subjectParam)) {
97806
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98372
+ if (!isTimebackSubject2(subjectParam)) {
98373
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97807
98374
  }
97808
98375
  grade = parsedGrade;
97809
98376
  subject = subjectParam;
@@ -97839,11 +98406,11 @@ var init_timeback_controller = __esm(() => {
97839
98406
  let subject;
97840
98407
  if (gradeParam !== null && subjectParam !== null) {
97841
98408
  const parsedGrade = parseInt(gradeParam, 10);
97842
- if (!isTimebackGrade(parsedGrade)) {
98409
+ if (!isTimebackGrade2(parsedGrade)) {
97843
98410
  throw ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
97844
98411
  }
97845
- if (!isTimebackSubject(subjectParam)) {
97846
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98412
+ if (!isTimebackSubject2(subjectParam)) {
98413
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97847
98414
  }
97848
98415
  grade = parsedGrade;
97849
98416
  subject = subjectParam;
@@ -97873,8 +98440,8 @@ var init_timeback_controller = __esm(() => {
97873
98440
  if (!subjectParam) {
97874
98441
  throw ApiError.badRequest("Missing required subject query parameter");
97875
98442
  }
97876
- if (!isTimebackSubject(subjectParam)) {
97877
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98443
+ if (!isTimebackSubject2(subjectParam)) {
98444
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97878
98445
  }
97879
98446
  return ctx.services.timeback.getStudentHighestGradeMastered(timebackId, ctx.user, {
97880
98447
  gameId,
@@ -98185,7 +98752,11 @@ var init_timeback_controller = __esm(() => {
98185
98752
  getUserById,
98186
98753
  setupIntegration,
98187
98754
  getIntegrations,
98755
+ getRemovedIntegrations,
98756
+ createIntegration,
98188
98757
  updateIntegration,
98758
+ deactivateCourse,
98759
+ reactivateCourse,
98189
98760
  getIntegrationConfig,
98190
98761
  verifyIntegration,
98191
98762
  getConfig,
@@ -99182,12 +99753,12 @@ var init_timeback7 = __esm(() => {
99182
99753
  }
99183
99754
  if (gradeParam !== null && subjectParam !== null) {
99184
99755
  const grade = parseInt(gradeParam, 10);
99185
- if (!Number.isFinite(grade) || !isTimebackGrade(grade)) {
99756
+ if (!Number.isFinite(grade) || !isTimebackGrade2(grade)) {
99186
99757
  const error2 = ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
99187
99758
  return c2.json(createErrorResponse(error2), error2.status);
99188
99759
  }
99189
- if (!isTimebackSubject(subjectParam)) {
99190
- const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99760
+ if (!isTimebackSubject2(subjectParam)) {
99761
+ const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99191
99762
  return c2.json(createErrorResponse(error2), error2.status);
99192
99763
  }
99193
99764
  enrollments = enrollments.filter((e) => e.grade === grade && e.subject === subjectParam);
@@ -99240,12 +99811,12 @@ var init_timeback7 = __esm(() => {
99240
99811
  }
99241
99812
  if (gradeParam !== null && subjectParam !== null) {
99242
99813
  const grade = parseInt(gradeParam, 10);
99243
- if (!Number.isFinite(grade) || !isTimebackGrade(grade)) {
99814
+ if (!Number.isFinite(grade) || !isTimebackGrade2(grade)) {
99244
99815
  const error2 = ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
99245
99816
  return c2.json(createErrorResponse(error2), error2.status);
99246
99817
  }
99247
- if (!isTimebackSubject(subjectParam)) {
99248
- const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99818
+ if (!isTimebackSubject2(subjectParam)) {
99819
+ const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99249
99820
  return c2.json(createErrorResponse(error2), error2.status);
99250
99821
  }
99251
99822
  enrollments = enrollments.filter((e) => e.grade === grade && e.subject === subjectParam);
@@ -99294,8 +99865,8 @@ var init_timeback7 = __esm(() => {
99294
99865
  const error2 = ApiError.badRequest("Missing required gameId query parameter");
99295
99866
  return c2.json(createErrorResponse(error2), error2.status);
99296
99867
  }
99297
- if (!isTimebackSubject(subject)) {
99298
- const error2 = ApiError.badRequest(`Invalid subject: ${subject}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99868
+ if (!isTimebackSubject2(subject)) {
99869
+ const error2 = ApiError.badRequest(`Invalid subject: ${subject}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99299
99870
  return c2.json(createErrorResponse(error2), error2.status);
99300
99871
  }
99301
99872
  const db2 = c2.get("db");