@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/server.js CHANGED
@@ -197,7 +197,8 @@ var AUTH_PROVIDER_IDS, DEMO_DISPLAY_NAME_PLACEHOLDER = "Demo Player";
197
197
  var init_auth = __esm(() => {
198
198
  AUTH_PROVIDER_IDS = {
199
199
  TIMEBACK: "timeback",
200
- TIMEBACK_LTI: "timeback-lti"
200
+ TIMEBACK_LTI: "timeback-lti",
201
+ PLAYCADEMY: "playcademy"
201
202
  };
202
203
  });
203
204
 
@@ -1077,7 +1078,7 @@ var package_default;
1077
1078
  var init_package = __esm(() => {
1078
1079
  package_default = {
1079
1080
  name: "@playcademy/sandbox",
1080
- version: "0.5.2-beta.2",
1081
+ version: "0.5.2-beta.4",
1081
1082
  description: "Local development server for Playcademy game development",
1082
1083
  type: "module",
1083
1084
  exports: {
@@ -11322,23 +11323,31 @@ var init_table6 = __esm(() => {
11322
11323
  });
11323
11324
 
11324
11325
  // ../data/src/domains/timeback/table.ts
11325
- var gameTimebackIntegrations, gameTimebackAssessmentTests, gameTimebackMetricDiscrepancyVerifications;
11326
+ var gameTimebackIntegrationStatusEnum, gameTimebackIntegrations, gameTimebackAssessmentTests, gameTimebackMetricDiscrepancyVerifications;
11326
11327
  var init_table7 = __esm(() => {
11328
+ init_drizzle_orm();
11327
11329
  init_pg_core();
11328
11330
  init_table5();
11329
11331
  init_table3();
11332
+ gameTimebackIntegrationStatusEnum = pgEnum("game_timeback_integration_status", [
11333
+ "active",
11334
+ "deactivated"
11335
+ ]);
11330
11336
  gameTimebackIntegrations = pgTable("game_timeback_integrations", {
11331
11337
  id: uuid("id").primaryKey().defaultRandom(),
11332
11338
  gameId: uuid("game_id").notNull().references(() => games.id, { onDelete: "cascade" }),
11333
11339
  courseId: text("course_id").notNull(),
11334
11340
  grade: integer("grade").notNull(),
11335
11341
  subject: text("subject").notNull(),
11342
+ status: gameTimebackIntegrationStatusEnum("status"),
11336
11343
  totalXp: integer("total_xp"),
11337
11344
  lastVerifiedAt: timestamp("last_verified_at", { withTimezone: true }),
11345
+ deactivatedAt: timestamp("deactivated_at", { withTimezone: true }),
11346
+ reactivatedAt: timestamp("reactivated_at", { withTimezone: true }),
11338
11347
  createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
11339
11348
  updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow()
11340
11349
  }, (table3) => [
11341
- uniqueIndex("game_timeback_integrations_game_grade_subject_idx").on(table3.gameId, table3.grade, table3.subject)
11350
+ uniqueIndex("game_timeback_integrations_game_grade_subject_idx").on(table3.gameId, table3.grade, table3.subject).where(sql`${table3.status} IS DISTINCT FROM 'deactivated'`)
11342
11351
  ]);
11343
11352
  gameTimebackAssessmentTests = pgTable("game_timeback_assessment_tests", {
11344
11353
  id: uuid("id").primaryKey().defaultRandom(),
@@ -11381,6 +11390,7 @@ __export(exports_tables_index, {
11381
11390
  gameTypeEnum: () => gameTypeEnum,
11382
11391
  gameTimebackMetricDiscrepancyVerifications: () => gameTimebackMetricDiscrepancyVerifications,
11383
11392
  gameTimebackIntegrations: () => gameTimebackIntegrations,
11393
+ gameTimebackIntegrationStatusEnum: () => gameTimebackIntegrationStatusEnum,
11384
11394
  gameTimebackAssessmentTests: () => gameTimebackAssessmentTests,
11385
11395
  gameScoresRelations: () => gameScoresRelations,
11386
11396
  gameScores: () => gameScores,
@@ -24672,6 +24682,7 @@ var init_helpers = __esm(() => {
24672
24682
 
24673
24683
  // ../cloudflare/src/playcademy/provider/provider.ts
24674
24684
  var init_provider = __esm(() => {
24685
+ init_src();
24675
24686
  init_src();
24676
24687
  init_core();
24677
24688
  init_constants2();
@@ -27767,6 +27778,20 @@ var init_game_member_service = __esm(() => {
27767
27778
  init_spans();
27768
27779
  init_errors();
27769
27780
  });
27781
+ // ../data/src/domains/timeback/helpers.ts
27782
+ function isActiveGameTimebackIntegrationStatus(statusColumn = gameTimebackIntegrations.status) {
27783
+ return sql`${statusColumn} IS DISTINCT FROM ${DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS}`;
27784
+ }
27785
+ var ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS = "active", DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS = "deactivated";
27786
+ var init_helpers2 = __esm(() => {
27787
+ init_drizzle_orm();
27788
+ init_table7();
27789
+ });
27790
+
27791
+ // ../data/src/helpers.index.ts
27792
+ var init_helpers_index = __esm(() => {
27793
+ init_helpers2();
27794
+ });
27770
27795
 
27771
27796
  // ../utils/src/fns.ts
27772
27797
  function sleep(ms) {
@@ -27776,15 +27801,584 @@ function sleep(ms) {
27776
27801
  return new Promise((resolve) => setTimeout(resolve, ms));
27777
27802
  }
27778
27803
 
27804
+ // ../timeback/dist/types.js
27805
+ function isObject(value) {
27806
+ return typeof value === "object" && value !== null;
27807
+ }
27808
+ function isCourseMetadata(value) {
27809
+ return isObject(value);
27810
+ }
27811
+ function isResourceMetadata(value) {
27812
+ return isObject(value);
27813
+ }
27814
+ function isPlaycademyResourceMetadata(value) {
27815
+ if (!isObject(value)) {
27816
+ return false;
27817
+ }
27818
+ if (!("mastery" in value) || value.mastery === undefined) {
27819
+ return true;
27820
+ }
27821
+ return isObject(value.mastery);
27822
+ }
27823
+ function isTimebackSubject(value) {
27824
+ return typeof value === "string" && SUBJECT_VALUES.includes(value);
27825
+ }
27826
+ function isTimebackGrade(value) {
27827
+ return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES.includes(value);
27828
+ }
27829
+ 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;
27830
+ var init_types2 = __esm(() => {
27831
+ init_src();
27832
+ init_constants3 = __esm2(() => {
27833
+ TIMEBACK_API_URLS = {
27834
+ production: "https://api.alpha-1edtech.ai",
27835
+ staging: "https://api.staging.alpha-1edtech.com"
27836
+ };
27837
+ TIMEBACK_AUTH_URLS = {
27838
+ production: "https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com",
27839
+ staging: "https://alpha-auth-development-idp.auth.us-west-2.amazoncognito.com"
27840
+ };
27841
+ CALIPER_API_URLS = {
27842
+ production: "https://caliper.alpha-1edtech.ai",
27843
+ staging: "https://caliper-staging.alpha-1edtech.com"
27844
+ };
27845
+ ONEROSTER_ENDPOINTS = {
27846
+ organizations: "/ims/oneroster/rostering/v1p2/orgs",
27847
+ courses: "/ims/oneroster/rostering/v1p2/courses",
27848
+ courseComponents: "/ims/oneroster/rostering/v1p2/courses/components",
27849
+ resources: "/ims/oneroster/resources/v1p2/resources",
27850
+ componentResources: "/ims/oneroster/rostering/v1p2/courses/component-resources",
27851
+ classes: "/ims/oneroster/rostering/v1p2/classes",
27852
+ enrollments: "/ims/oneroster/rostering/v1p2/enrollments",
27853
+ assessmentLineItems: "/ims/oneroster/gradebook/v1p2/assessmentLineItems",
27854
+ assessmentResults: "/ims/oneroster/gradebook/v1p2/assessmentResults",
27855
+ users: "/ims/oneroster/rostering/v1p2/users"
27856
+ };
27857
+ QTI_ENDPOINTS = {
27858
+ assessmentTests: "/assessment-tests",
27859
+ assessmentItems: "/assessment-items"
27860
+ };
27861
+ CALIPER_ENDPOINTS = {
27862
+ event: "/caliper/event",
27863
+ events: "/caliper/events",
27864
+ validate: "/caliper/event/validate"
27865
+ };
27866
+ CALIPER_CONSTANTS = {
27867
+ context: "http://purl.imsglobal.org/ctx/caliper/v1p2",
27868
+ profile: "TimebackProfile",
27869
+ dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2"
27870
+ };
27871
+ TIMEBACK_EVENT_TYPES = {
27872
+ activityEvent: "ActivityEvent",
27873
+ timeSpentEvent: "TimeSpentEvent"
27874
+ };
27875
+ TIMEBACK_ACTIONS = {
27876
+ completed: "Completed",
27877
+ spentTime: "SpentTime"
27878
+ };
27879
+ TIMEBACK_TYPES = {
27880
+ user: "TimebackUser",
27881
+ activityContext: "TimebackActivityContext",
27882
+ activityMetricsCollection: "TimebackActivityMetricsCollection",
27883
+ timeSpentMetricsCollection: "TimebackTimeSpentMetricsCollection"
27884
+ };
27885
+ ACTIVITY_METRIC_TYPES = {
27886
+ totalQuestions: "totalQuestions",
27887
+ correctQuestions: "correctQuestions",
27888
+ xpEarned: "xpEarned",
27889
+ masteredUnits: "masteredUnits"
27890
+ };
27891
+ TIME_METRIC_TYPES = {
27892
+ active: "active",
27893
+ inactive: "inactive",
27894
+ waste: "waste",
27895
+ unknown: "unknown",
27896
+ antiPattern: "anti-pattern"
27897
+ };
27898
+ TIMEBACK_SUBJECTS = [
27899
+ "Math",
27900
+ "FastMath",
27901
+ "Science",
27902
+ "Social Studies",
27903
+ "Language",
27904
+ "Reading",
27905
+ "Vocabulary",
27906
+ "Writing"
27907
+ ];
27908
+ TIMEBACK_GRADE_LEVELS = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
27909
+ TIMEBACK_GRADE_LEVEL_LABELS = {
27910
+ "-1": "pre-k",
27911
+ "0": "kindergarten",
27912
+ "1": "1st grade",
27913
+ "2": "2nd grade",
27914
+ "3": "3rd grade",
27915
+ "4": "4th grade",
27916
+ "5": "5th grade",
27917
+ "6": "6th grade",
27918
+ "7": "7th grade",
27919
+ "8": "8th grade",
27920
+ "9": "9th grade",
27921
+ "10": "10th grade",
27922
+ "11": "11th grade",
27923
+ "12": "12th grade",
27924
+ "13": "AP"
27925
+ };
27926
+ CALIPER_SUBJECTS = {
27927
+ Reading: "Reading",
27928
+ Language: "Language",
27929
+ Vocabulary: "Vocabulary",
27930
+ SocialStudies: "Social Studies",
27931
+ Writing: "Writing",
27932
+ Science: "Science",
27933
+ FastMath: "FastMath",
27934
+ Math: "Math",
27935
+ None: "None"
27936
+ };
27937
+ ONEROSTER_STATUS = {
27938
+ active: "active",
27939
+ toBeDeleted: "tobedeleted"
27940
+ };
27941
+ SCORE_STATUS = {
27942
+ exempt: "exempt",
27943
+ fullyGraded: "fully graded",
27944
+ notSubmitted: "not submitted",
27945
+ partiallyGraded: "partially graded",
27946
+ submitted: "submitted"
27947
+ };
27948
+ ENV_VARS = {
27949
+ clientId: "TIMEBACK_CLIENT_ID",
27950
+ clientSecret: "TIMEBACK_CLIENT_SECRET",
27951
+ baseUrl: "TIMEBACK_BASE_URL",
27952
+ environment: "TIMEBACK_ENVIRONMENT",
27953
+ vendorResourceId: "TIMEBACK_VENDOR_RESOURCE_ID",
27954
+ launchBaseUrl: "GAME_URL",
27955
+ qtiClientId: "QTI_CLIENT_ID",
27956
+ qtiClientSecret: "QTI_CLIENT_SECRET",
27957
+ qtiAuthUrl: "QTI_AUTH_URL"
27958
+ };
27959
+ HTTP_DEFAULTS = {
27960
+ timeout: 30000,
27961
+ retries: 3,
27962
+ retryBackoffBase: 2
27963
+ };
27964
+ AUTH_DEFAULTS = {
27965
+ tokenCacheDuration: 50000
27966
+ };
27967
+ CACHE_DEFAULTS = {
27968
+ defaultTTL: 10 * 60 * 1000,
27969
+ defaultMaxSize: 500,
27970
+ defaultName: "TimebackCache",
27971
+ studentTTL: 10 * 60 * 1000,
27972
+ studentMaxSize: 500,
27973
+ assessmentTTL: 30 * 60 * 1000,
27974
+ assessmentMaxSize: 200,
27975
+ enrollmentTTL: 5 * 1000,
27976
+ enrollmentMaxSize: 100
27977
+ };
27978
+ CONFIG_DEFAULTS = {
27979
+ fileNames: ["timeback.config.js", "timeback.config.json"]
27980
+ };
27981
+ PLAYCADEMY_DEFAULTS = {
27982
+ organization: TIMEBACK_ORG_SOURCED_ID,
27983
+ launchBaseUrls: PLAYCADEMY_BASE_URLS
27984
+ };
27985
+ RESOURCE_DEFAULTS = {
27986
+ organization: {
27987
+ name: TIMEBACK_ORG_NAME,
27988
+ type: TIMEBACK_ORG_TYPE
27989
+ },
27990
+ course: {
27991
+ gradingScheme: TIMEBACK_COURSE_DEFAULTS.gradingScheme,
27992
+ level: TIMEBACK_COURSE_DEFAULTS.level,
27993
+ metadata: {
27994
+ goals: TIMEBACK_COURSE_DEFAULTS.goals,
27995
+ metrics: TIMEBACK_COURSE_DEFAULTS.metrics
27996
+ }
27997
+ },
27998
+ component: TIMEBACK_COMPONENT_DEFAULTS,
27999
+ resource: TIMEBACK_RESOURCE_DEFAULTS,
28000
+ componentResource: TIMEBACK_COMPONENT_RESOURCE_DEFAULTS
28001
+ };
28002
+ HTTP_STATUS = {
28003
+ CLIENT_ERROR_MIN: 400,
28004
+ CLIENT_ERROR_MAX: 500,
28005
+ SERVER_ERROR_MIN: 500
28006
+ };
28007
+ ERROR_NAMES = {
28008
+ timebackAuth: "TimebackAuthError",
28009
+ timebackApi: "TimebackApiError",
28010
+ timebackConfig: "TimebackConfigError",
28011
+ timebackSdk: "TimebackSDKError"
28012
+ };
28013
+ });
28014
+ init_constants3();
28015
+ SUBJECT_VALUES = TIMEBACK_SUBJECTS;
28016
+ GRADE_VALUES = TIMEBACK_GRADE_LEVELS;
28017
+ });
28018
+
28019
+ // ../utils/src/string.ts
28020
+ function kebabToTitleCase(kebabStr) {
28021
+ return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
28022
+ }
28023
+
28024
+ // ../api-core/src/utils/timeback.util.ts
28025
+ function isRecord2(value) {
28026
+ return typeof value === "object" && value !== null;
28027
+ }
28028
+ function filterEnrollmentsByGame(enrollments, gameId) {
28029
+ return enrollments.filter((enrollment) => enrollment.gameId === gameId).map(({ gameId: _, ...enrollment }) => enrollment);
28030
+ }
28031
+ function mapEnrollmentsToUserEnrollments(enrollments, integrations) {
28032
+ const enrollmentByCourse = new Map(enrollments.map((enrollment) => [enrollment.courseId, enrollment]));
28033
+ const courseToSchool = new Map(enrollments.filter((enrollment) => enrollment.school?.id).map((enrollment) => [enrollment.courseId, enrollment.school.id]));
28034
+ return integrations.map((integration) => {
28035
+ const enrollment = enrollmentByCourse.get(integration.courseId);
28036
+ return {
28037
+ gameId: integration.gameId,
28038
+ grade: integration.grade,
28039
+ subject: integration.subject,
28040
+ courseId: integration.courseId,
28041
+ orgId: courseToSchool.get(integration.courseId),
28042
+ ...enrollment ? { id: enrollment.sourcedId } : {}
28043
+ };
28044
+ });
28045
+ }
28046
+ function buildGameTimebackSummaries(integrations) {
28047
+ const summaries = {};
28048
+ for (const integration of integrations) {
28049
+ const summary = summaries[integration.gameId] ?? {
28050
+ subject: null,
28051
+ hasActiveIntegration: false,
28052
+ hasRemovedIntegration: false
28053
+ };
28054
+ const isRemoved = integration.status === DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS;
28055
+ if (isRemoved) {
28056
+ summary.hasRemovedIntegration = true;
28057
+ } else {
28058
+ summary.hasActiveIntegration = true;
28059
+ summary.subject ??= integration.subject;
28060
+ }
28061
+ summaries[integration.gameId] = summary;
28062
+ }
28063
+ return summaries;
28064
+ }
28065
+ function getStringValue(value) {
28066
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
28067
+ }
28068
+ function parseSourcedIdFromUrl(url) {
28069
+ if (!url) {
28070
+ return;
28071
+ }
28072
+ const trimmed = url.trim().replace(/\/$/, "");
28073
+ if (!trimmed) {
28074
+ return;
28075
+ }
28076
+ const segments = trimmed.split("/");
28077
+ const lastSegment = segments.at(-1);
28078
+ return lastSegment ? decodeURIComponent(lastSegment) : undefined;
28079
+ }
28080
+ function getGeneratedMetricValue(event, type) {
28081
+ const items = event.generated?.items;
28082
+ if (!Array.isArray(items)) {
28083
+ return;
28084
+ }
28085
+ const metric = items.find((item) => item?.type === type);
28086
+ if (!metric) {
28087
+ return;
28088
+ }
28089
+ const value = typeof metric.value === "number" ? metric.value : Number(metric.value);
28090
+ return Number.isFinite(value) ? value : undefined;
28091
+ }
28092
+ function getMergedCaliperExtensions(event) {
28093
+ const objectActivityExtensions = isRecord2(event.object.activity?.extensions) ? event.object.activity.extensions : undefined;
28094
+ const generatedExtensions = isRecord2(event.generated?.extensions) ? event.generated.extensions : undefined;
28095
+ const eventExtensions = isRecord2(event.extensions) ? event.extensions : undefined;
28096
+ return {
28097
+ ...objectActivityExtensions,
28098
+ ...generatedExtensions,
28099
+ ...eventExtensions
28100
+ };
28101
+ }
28102
+ function getPlaycademyMetadata(event) {
28103
+ const extensions = getMergedCaliperExtensions(event);
28104
+ return isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
28105
+ }
28106
+ function getActivityId(event, playcademy) {
28107
+ const metadataActivityId = getStringValue(playcademy?.activityId);
28108
+ if (metadataActivityId) {
28109
+ return metadataActivityId;
28110
+ }
28111
+ const activityId = getStringValue(event.object.activity?.id);
28112
+ if (activityId) {
28113
+ return activityId;
28114
+ }
28115
+ const objectId = getStringValue(event.object.id);
28116
+ if (!objectId) {
28117
+ return;
28118
+ }
28119
+ const trimmed = objectId.replace(/\/$/, "");
28120
+ const segments = trimmed.split("/");
28121
+ const activityIndex = segments.lastIndexOf("activities");
28122
+ if (activityIndex !== -1 && segments.length >= activityIndex + 3) {
28123
+ const candidate = segments[activityIndex + 2];
28124
+ return candidate ? decodeURIComponent(candidate) : undefined;
28125
+ }
28126
+ return;
28127
+ }
28128
+ function buildResourceMetadata({
28129
+ baseMetadata,
28130
+ subject,
28131
+ grade,
28132
+ totalXp,
28133
+ masterableUnits
28134
+ }) {
28135
+ const normalizedBaseMetadata = isResourceMetadata(baseMetadata) ? baseMetadata : undefined;
28136
+ const metadata2 = {
28137
+ ...normalizedBaseMetadata
28138
+ };
28139
+ metadata2.subject = subject;
28140
+ metadata2.grades = [grade];
28141
+ metadata2.xp = totalXp;
28142
+ if (masterableUnits !== undefined && masterableUnits !== null) {
28143
+ const existingPlaycademy = isPlaycademyResourceMetadata(metadata2.playcademy) ? metadata2.playcademy : undefined;
28144
+ metadata2.playcademy = {
28145
+ ...existingPlaycademy,
28146
+ mastery: {
28147
+ ...existingPlaycademy?.mastery,
28148
+ masterableUnits
28149
+ }
28150
+ };
28151
+ }
28152
+ return metadata2;
28153
+ }
28154
+ function getDurationSecondsFromExtensions(event) {
28155
+ const extensions = getMergedCaliperExtensions(event);
28156
+ const playcademy = isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
28157
+ const rawValue = extensions.durationSeconds ?? playcademy?.durationSeconds;
28158
+ const value = typeof rawValue === "number" ? rawValue : Number(rawValue);
28159
+ return Number.isFinite(value) ? value : undefined;
28160
+ }
28161
+ function getCanonicalRunId(session2) {
28162
+ const sessionId = getStringValue(session2?.id);
28163
+ if (!sessionId) {
28164
+ return;
28165
+ }
28166
+ return sessionId.replace(/^urn:uuid:/, "");
28167
+ }
28168
+ function getResumeId(event) {
28169
+ const playcademy = getPlaycademyMetadata(event);
28170
+ return getStringValue(playcademy?.resumeId);
28171
+ }
28172
+ function isCaliperRemediationOrCompletionEvent(event) {
28173
+ const playcademy = getPlaycademyMetadata(event);
28174
+ return REMEDIATION_OR_COMPLETION_EVENT_KINDS.has(getStringValue(playcademy?.eventKind) || "");
28175
+ }
28176
+ function groupCaliperEventsByRun(events) {
28177
+ const groups = new Map;
28178
+ for (const event of events) {
28179
+ const objectId = getStringValue(event.object.id) || "unknown-activity";
28180
+ const groupKey = `${objectId}::${getStringValue(event.session?.id) || event.externalId}`;
28181
+ const existing = groups.get(groupKey);
28182
+ if (existing) {
28183
+ existing.push(event);
28184
+ } else {
28185
+ groups.set(groupKey, [event]);
28186
+ }
28187
+ }
28188
+ return groups;
28189
+ }
28190
+ function findCaliperEventGroupContainingExternalId(events, externalId) {
28191
+ const targetExternalId = externalId.trim();
28192
+ if (!targetExternalId) {
28193
+ return;
28194
+ }
28195
+ return [...groupCaliperEventsByRun(events).values()].find((group) => group.some((event) => event.externalId === targetExternalId));
28196
+ }
28197
+ function mapCaliperEventGroupToActivity(events, relevantCourseIds) {
28198
+ if (events.length === 0) {
28199
+ return null;
28200
+ }
28201
+ const sortedEvents = events.toSorted((a, b) => a.eventTime.localeCompare(b.eventTime));
28202
+ const activityEvent = [...sortedEvents].toReversed().find((event) => event.type === "ActivityEvent");
28203
+ const contextSource = activityEvent || sortedEvents.at(-1);
28204
+ if (!contextSource) {
28205
+ return null;
28206
+ }
28207
+ const ctx = parseCaliperEventContext(contextSource, relevantCourseIds);
28208
+ if (!ctx) {
28209
+ return null;
28210
+ }
28211
+ const score = activityEvent !== undefined ? (() => {
28212
+ const totalQuestions = getGeneratedMetricValue(activityEvent, "totalQuestions");
28213
+ const correctQuestions = getGeneratedMetricValue(activityEvent, "correctQuestions");
28214
+ if (totalQuestions === undefined || correctQuestions === undefined || totalQuestions <= 0) {
28215
+ return;
28216
+ }
28217
+ return correctQuestions / totalQuestions * 100;
28218
+ })() : undefined;
28219
+ const xpEarned = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "xpEarned") : undefined;
28220
+ const masteredUnits = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "masteredUnits") : undefined;
28221
+ const timeSpentEvents = sortedEvents.filter((event) => event.type === "TimeSpentEvent");
28222
+ let totalActiveTimeSeconds;
28223
+ if (timeSpentEvents.length > 0) {
28224
+ totalActiveTimeSeconds = timeSpentEvents.reduce((sum, event) => sum + (getGeneratedMetricValue(event, "active") ?? 0), 0);
28225
+ } else if (activityEvent !== undefined) {
28226
+ totalActiveTimeSeconds = getDurationSecondsFromExtensions(activityEvent);
28227
+ }
28228
+ const fallbackActivityId = getActivityId(contextSource, getPlaycademyMetadata(contextSource));
28229
+ const occurredAt = getStringValue(activityEvent?.eventTime) || getStringValue(sortedEvents.at(-1)?.eventTime);
28230
+ const runId = getCanonicalRunId(contextSource.session);
28231
+ const resumeIds = new Set(sortedEvents.map((event) => getResumeId(event)).filter((resumeId) => resumeId !== undefined));
28232
+ const sessionCount = resumeIds.size > 0 ? resumeIds.size : 1;
28233
+ const kind = activityEvent !== undefined ? "activity" : "activity-in-progress";
28234
+ if (!occurredAt) {
28235
+ return null;
28236
+ }
28237
+ return {
28238
+ id: activityEvent?.externalId || sortedEvents.at(-1)?.externalId || events[0].externalId,
28239
+ kind,
28240
+ occurredAt,
28241
+ courseId: ctx.courseId,
28242
+ title: getStringValue(activityEvent?.object.activity?.name) || ctx.titleFromEvent || (fallbackActivityId ? kebabToTitleCase(fallbackActivityId) : "Activity completed"),
28243
+ ...ctx.activityId ? { activityId: ctx.activityId } : {},
28244
+ ...ctx.appName ? { appName: ctx.appName } : {},
28245
+ ...score !== undefined ? { score } : {},
28246
+ ...xpEarned !== undefined ? { xpDelta: xpEarned } : {},
28247
+ ...masteredUnits !== undefined ? { masteredUnitsDelta: masteredUnits } : {},
28248
+ ...totalActiveTimeSeconds !== undefined ? { timeDeltaSeconds: totalActiveTimeSeconds } : {},
28249
+ ...runId ? { runId } : {},
28250
+ ...sessionCount > 0 ? { sessionCount } : {}
28251
+ };
28252
+ }
28253
+ function parseCaliperEventContext(event, relevantCourseIds) {
28254
+ const playcademy = getPlaycademyMetadata(event);
28255
+ const courseId = getStringValue(playcademy?.courseId) || parseSourcedIdFromUrl(event.object.course?.id);
28256
+ if (!courseId || !relevantCourseIds.has(courseId)) {
28257
+ return null;
28258
+ }
28259
+ const occurredAt = getStringValue(event.eventTime);
28260
+ if (!occurredAt) {
28261
+ return null;
28262
+ }
28263
+ return {
28264
+ courseId,
28265
+ occurredAt,
28266
+ eventKind: getStringValue(playcademy?.eventKind),
28267
+ source: getStringValue(playcademy?.source),
28268
+ reason: getStringValue(playcademy?.reason),
28269
+ titleFromEvent: getStringValue(event.object.activity?.name),
28270
+ appName: getStringValue(event.object.app?.name),
28271
+ activityId: getActivityId(event, playcademy)
28272
+ };
28273
+ }
28274
+ function mapTimeSpentRemediation(event, ctx) {
28275
+ if (ctx.eventKind !== "remediation-time") {
28276
+ return null;
28277
+ }
28278
+ return {
28279
+ id: event.externalId,
28280
+ kind: "remediation-time",
28281
+ occurredAt: ctx.occurredAt,
28282
+ courseId: ctx.courseId,
28283
+ title: "Time Adjustment",
28284
+ activityId: ctx.activityId,
28285
+ appName: ctx.appName,
28286
+ reason: ctx.reason,
28287
+ timeDeltaSeconds: getGeneratedMetricValue(event, "active")
28288
+ };
28289
+ }
28290
+ function mapActivityRemediation(event, ctx) {
28291
+ if (ctx.eventKind === "remediation-xp") {
28292
+ return {
28293
+ id: event.externalId,
28294
+ kind: "remediation-xp",
28295
+ occurredAt: ctx.occurredAt,
28296
+ courseId: ctx.courseId,
28297
+ title: "XP Adjustment",
28298
+ activityId: ctx.activityId,
28299
+ appName: ctx.appName,
28300
+ reason: ctx.reason,
28301
+ xpDelta: getGeneratedMetricValue(event, "xpEarned"),
28302
+ masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
28303
+ };
28304
+ }
28305
+ if (ctx.eventKind === "remediation-mastery") {
28306
+ return {
28307
+ id: event.externalId,
28308
+ kind: "remediation-mastery",
28309
+ occurredAt: ctx.occurredAt,
28310
+ courseId: ctx.courseId,
28311
+ title: "Mastery Adjustment",
28312
+ activityId: ctx.activityId,
28313
+ appName: ctx.appName,
28314
+ reason: ctx.reason,
28315
+ xpDelta: getGeneratedMetricValue(event, "xpEarned"),
28316
+ masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
28317
+ };
28318
+ }
28319
+ if (ctx.eventKind === "course-completed") {
28320
+ return {
28321
+ id: event.externalId,
28322
+ kind: "course-completed",
28323
+ occurredAt: ctx.occurredAt,
28324
+ courseId: ctx.courseId,
28325
+ title: ctx.source === "admin" ? "Course marked complete" : "Course completed",
28326
+ activityId: ctx.activityId,
28327
+ appName: ctx.appName,
28328
+ reason: ctx.reason
28329
+ };
28330
+ }
28331
+ if (ctx.eventKind === "course-resumed") {
28332
+ return {
28333
+ id: event.externalId,
28334
+ kind: "course-resumed",
28335
+ occurredAt: ctx.occurredAt,
28336
+ courseId: ctx.courseId,
28337
+ title: "Course resumed",
28338
+ activityId: ctx.activityId,
28339
+ appName: ctx.appName,
28340
+ reason: ctx.reason
28341
+ };
28342
+ }
28343
+ return null;
28344
+ }
28345
+ function mapCaliperEventToRemediationActivity(event, relevantCourseIds) {
28346
+ const ctx = parseCaliperEventContext(event, relevantCourseIds);
28347
+ if (!ctx) {
28348
+ return null;
28349
+ }
28350
+ if (event.type === "TimeSpentEvent") {
28351
+ return mapTimeSpentRemediation(event, ctx);
28352
+ }
28353
+ if (event.type === "ActivityEvent") {
28354
+ return mapActivityRemediation(event, ctx);
28355
+ }
28356
+ return null;
28357
+ }
28358
+ var REMEDIATION_OR_COMPLETION_EVENT_KINDS;
28359
+ var init_timeback_util = __esm(() => {
28360
+ init_helpers_index();
28361
+ init_types2();
28362
+ REMEDIATION_OR_COMPLETION_EVENT_KINDS = new Set([
28363
+ "remediation-xp",
28364
+ "remediation-time",
28365
+ "remediation-mastery",
28366
+ "course-completed",
28367
+ "course-resumed"
28368
+ ]);
28369
+ });
28370
+
27779
28371
  // ../api-core/src/services/game.service.ts
27780
28372
  var inFlightManifestFetches, GameService;
27781
28373
  var init_game_service = __esm(() => {
27782
28374
  init_drizzle_orm();
27783
28375
  init_src();
28376
+ init_helpers_index();
27784
28377
  init_tables_index();
27785
28378
  init_spans();
27786
28379
  init_errors();
27787
28380
  init_deployment_util();
28381
+ init_timeback_util();
27788
28382
  inFlightManifestFetches = new Map;
27789
28383
  GameService = class GameService {
27790
28384
  deps;
@@ -27928,6 +28522,7 @@ var init_game_service = __esm(() => {
27928
28522
  const db2 = this.deps.db;
27929
28523
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
27930
28524
  columns: { gameId: true, subject: true },
28525
+ where: isActiveGameTimebackIntegrationStatus(),
27931
28526
  orderBy: [asc(gameTimebackIntegrations.createdAt)]
27932
28527
  });
27933
28528
  const subjectMap = {};
@@ -27938,6 +28533,26 @@ var init_game_service = __esm(() => {
27938
28533
  }
27939
28534
  return subjectMap;
27940
28535
  }
28536
+ async getTimebackSummaries(user) {
28537
+ const db2 = this.deps.db;
28538
+ const canSeeAllGames = user.role === "admin" || user.role === "teacher";
28539
+ let accessibleGameIds = null;
28540
+ if (!canSeeAllGames) {
28541
+ const accessibleGames = await this.listAccessible(user);
28542
+ accessibleGameIds = new Set(accessibleGames.map((game2) => game2.id));
28543
+ }
28544
+ if (accessibleGameIds?.size === 0) {
28545
+ return {};
28546
+ }
28547
+ const integrations = await db2.query.gameTimebackIntegrations.findMany({
28548
+ columns: { gameId: true, subject: true, status: true },
28549
+ ...accessibleGameIds && {
28550
+ where: inArray(gameTimebackIntegrations.gameId, [...accessibleGameIds])
28551
+ },
28552
+ orderBy: [asc(gameTimebackIntegrations.createdAt)]
28553
+ });
28554
+ return buildGameTimebackSummaries(integrations);
28555
+ }
27941
28556
  async getById(gameId, caller) {
27942
28557
  const db2 = this.deps.db;
27943
28558
  const game2 = await db2.query.games.findFirst({
@@ -28575,7 +29190,7 @@ var init_client2 = () => {};
28575
29190
 
28576
29191
  // ../alerts/src/discord/types.ts
28577
29192
  var DiscordColors;
28578
- var init_types2 = __esm(() => {
29193
+ var init_types3 = __esm(() => {
28579
29194
  DiscordColors = {
28580
29195
  DEFAULT: 0,
28581
29196
  WHITE: 16777215,
@@ -28613,7 +29228,7 @@ var init_types2 = __esm(() => {
28613
29228
  // ../alerts/src/discord/index.ts
28614
29229
  var init_discord = __esm(() => {
28615
29230
  init_client2();
28616
- init_types2();
29231
+ init_types3();
28617
29232
  });
28618
29233
 
28619
29234
  // ../api-core/src/services/alerts.service.ts
@@ -29744,7 +30359,7 @@ var init_secrets_service = __esm(() => {
29744
30359
 
29745
30360
  // ../edge-play/src/constants.ts
29746
30361
  var ASSET_ROUTE_PREFIX = "/api/assets/", ROUTES;
29747
- var init_constants3 = __esm(() => {
30362
+ var init_constants4 = __esm(() => {
29748
30363
  init_src();
29749
30364
  ROUTES = {
29750
30365
  INDEX: "/api",
@@ -29771,7 +30386,7 @@ function prefixSecrets(secrets) {
29771
30386
  }
29772
30387
  var init_setup2 = __esm(() => {
29773
30388
  init_src();
29774
- init_constants3();
30389
+ init_constants4();
29775
30390
  });
29776
30391
 
29777
30392
  // ../api-core/src/services/seed.service.ts
@@ -30496,11 +31111,11 @@ var init_schemas3 = __esm(() => {
30496
31111
  });
30497
31112
 
30498
31113
  // ../data/src/domains/timeback/schemas.ts
30499
- function isTimebackGrade(value) {
31114
+ function isTimebackGrade2(value) {
30500
31115
  return Number.isInteger(value) && TIMEBACK_GRADES.includes(value);
30501
31116
  }
30502
- function isTimebackSubject(value) {
30503
- return TIMEBACK_SUBJECTS.includes(value);
31117
+ function isTimebackSubject2(value) {
31118
+ return TIMEBACK_SUBJECTS2.includes(value);
30504
31119
  }
30505
31120
  function isValidAdminAttributionDate(value) {
30506
31121
  const match = value.match(/^(\d{4})-(\d{2})-(\d{2})$/);
@@ -30514,13 +31129,13 @@ function isValidAdminAttributionDate(value) {
30514
31129
  const date3 = new Date(Date.UTC(year, month - 1, day, 12, 0, 0));
30515
31130
  return date3.getUTCFullYear() === year && date3.getUTCMonth() + 1 === month && date3.getUTCDate() === day;
30516
31131
  }
30517
- 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;
31132
+ 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;
30518
31133
  var init_schemas4 = __esm(() => {
30519
31134
  init_drizzle_zod();
30520
31135
  init_esm();
30521
31136
  init_table7();
30522
31137
  TIMEBACK_GRADES = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
30523
- TIMEBACK_SUBJECTS = [
31138
+ TIMEBACK_SUBJECTS2 = [
30524
31139
  "Reading",
30525
31140
  "Language",
30526
31141
  "Vocabulary",
@@ -30534,7 +31149,7 @@ var init_schemas4 = __esm(() => {
30534
31149
  TimebackGradeSchema = exports_external.number().int().refine((val) => TIMEBACK_GRADES.includes(val), {
30535
31150
  message: `Grade must be one of: ${TIMEBACK_GRADES.join(", ")}`
30536
31151
  });
30537
- TimebackSubjectSchema = exports_external.enum(TIMEBACK_SUBJECTS);
31152
+ TimebackSubjectSchema = exports_external.enum(TIMEBACK_SUBJECTS2);
30538
31153
  CourseGoalsSchema = exports_external.object({
30539
31154
  dailyXp: exports_external.number().int().nonnegative().nullable().optional(),
30540
31155
  dailyLessons: exports_external.number().int().nonnegative().nullable().optional(),
@@ -30553,6 +31168,15 @@ var init_schemas4 = __esm(() => {
30553
31168
  isSupplemental: exports_external.boolean().optional(),
30554
31169
  timebackVisible: exports_external.boolean().nullable().optional()
30555
31170
  });
31171
+ CreateGameTimebackIntegrationRequestSchema = exports_external.object({
31172
+ title: exports_external.string().trim().min(1),
31173
+ courseCode: exports_external.string().trim().min(1),
31174
+ subject: TimebackSubjectSchema,
31175
+ grade: TimebackGradeSchema,
31176
+ totalXp: exports_external.number().int().positive(),
31177
+ masterableUnits: exports_external.number().int().nonnegative(),
31178
+ level: exports_external.string().trim().min(1).optional()
31179
+ });
30556
31180
  TimebackActivityDataSchema = exports_external.object({
30557
31181
  activityId: exports_external.string().min(1),
30558
31182
  activityName: exports_external.string().optional(),
@@ -30998,10 +31622,6 @@ var init_log = __esm(() => {
30998
31622
  init_ansi();
30999
31623
  init_spinner();
31000
31624
  });
31001
- // ../utils/src/string.ts
31002
- function kebabToTitleCase(kebabStr) {
31003
- return kebabStr.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
31004
- }
31005
31625
  // ../utils/src/timezone.ts
31006
31626
  function formatDateYMDInTimezone(timeZone, date3 = new Date) {
31007
31627
  const parts2 = new Intl.DateTimeFormat("en-US", {
@@ -31111,16 +31731,45 @@ var init_src4 = __esm(() => {
31111
31731
  });
31112
31732
 
31113
31733
  // ../timeback/dist/index.js
31734
+ import { createHash } from "node:crypto";
31114
31735
  import { AsyncLocalStorage } from "node:async_hooks";
31115
31736
  function createOneRosterUrls(baseUrl) {
31116
- const effective = baseUrl || TIMEBACK_API_URLS.production;
31737
+ const effective = baseUrl || TIMEBACK_API_URLS2.production;
31117
31738
  const base = effective.replace(/\/$/, "");
31118
31739
  return {
31119
- user: (userId) => `${base}${ONEROSTER_ENDPOINTS.users}/${userId}`,
31120
- course: (courseId) => `${base}${ONEROSTER_ENDPOINTS.courses}/${courseId}`,
31121
- componentResource: (resourceId) => `${base}${ONEROSTER_ENDPOINTS.componentResources}/${resourceId}`
31740
+ user: (userId) => `${base}${ONEROSTER_ENDPOINTS2.users}/${userId}`,
31741
+ course: (courseId) => `${base}${ONEROSTER_ENDPOINTS2.courses}/${courseId}`,
31742
+ componentResource: (resourceId) => `${base}${ONEROSTER_ENDPOINTS2.componentResources}/${resourceId}`
31122
31743
  };
31123
31744
  }
31745
+ function resolveCourseIdFromCourseUrl(url2) {
31746
+ try {
31747
+ const parts2 = new URL(url2).pathname.split("/").filter(Boolean);
31748
+ const maybeCourses = parts2.at(-2);
31749
+ const maybeId = parts2.at(-1);
31750
+ if (maybeCourses !== "courses" || !maybeId) {
31751
+ return null;
31752
+ }
31753
+ if (UUID_REGEX2.test(maybeId)) {
31754
+ return maybeId;
31755
+ }
31756
+ if (maybeId.length > 2 && !maybeId.includes("/")) {
31757
+ return maybeId;
31758
+ }
31759
+ return null;
31760
+ } catch {
31761
+ return null;
31762
+ }
31763
+ }
31764
+ function computeCaliperLineItemId(objectId, courseSourcedId, courseUrl) {
31765
+ const recovered = resolveCourseIdFromCourseUrl(courseUrl);
31766
+ if (recovered !== courseSourcedId) {
31767
+ 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.`);
31768
+ }
31769
+ const idParts = [objectId, courseSourcedId].join("_");
31770
+ const hashedId = createHash("sha256").update(idParts).digest("hex");
31771
+ return `caliper_${hashedId}`;
31772
+ }
31124
31773
  function deriveSourcedIds(courseId) {
31125
31774
  return {
31126
31775
  course: courseId,
@@ -31132,7 +31781,7 @@ function deriveSourcedIds(courseId) {
31132
31781
  async function fetchTimebackConfig(client, courseId) {
31133
31782
  const sourcedIds = deriveSourcedIds(courseId);
31134
31783
  const [org, course, component, resource, componentResource] = await Promise.all([
31135
- client.oneroster.organizations.get(PLAYCADEMY_DEFAULTS.organization),
31784
+ client.oneroster.organizations.get(PLAYCADEMY_DEFAULTS2.organization),
31136
31785
  client.oneroster.courses.get(sourcedIds.course),
31137
31786
  client.oneroster.courseComponents.get(sourcedIds.component),
31138
31787
  client.oneroster.resources.get(sourcedIds.resource),
@@ -31142,7 +31791,7 @@ async function fetchTimebackConfig(client, courseId) {
31142
31791
  organization: {
31143
31792
  name: org.name,
31144
31793
  type: org.type,
31145
- identifier: org.identifier || PLAYCADEMY_DEFAULTS.organization
31794
+ identifier: org.identifier || PLAYCADEMY_DEFAULTS2.organization
31146
31795
  },
31147
31796
  course: {
31148
31797
  title: course.title || "",
@@ -31202,23 +31851,23 @@ async function verifyTimebackResources(client, courseId) {
31202
31851
  }
31203
31852
  };
31204
31853
  }
31205
- function isObject(value) {
31854
+ function isObject2(value) {
31206
31855
  return typeof value === "object" && value !== null;
31207
31856
  }
31208
- function isPlaycademyResourceMetadata(value) {
31209
- if (!isObject(value)) {
31857
+ function isPlaycademyResourceMetadata2(value) {
31858
+ if (!isObject2(value)) {
31210
31859
  return false;
31211
31860
  }
31212
31861
  if (!("mastery" in value) || value.mastery === undefined) {
31213
31862
  return true;
31214
31863
  }
31215
- return isObject(value.mastery);
31864
+ return isObject2(value.mastery);
31216
31865
  }
31217
- function isTimebackSubject2(value) {
31218
- return typeof value === "string" && SUBJECT_VALUES.includes(value);
31866
+ function isTimebackSubject3(value) {
31867
+ return typeof value === "string" && SUBJECT_VALUES2.includes(value);
31219
31868
  }
31220
- function isTimebackGrade2(value) {
31221
- return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES.includes(value);
31869
+ function isTimebackGrade3(value) {
31870
+ return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES2.includes(value);
31222
31871
  }
31223
31872
  async function deleteTimebackResources(client, courseId) {
31224
31873
  const sourcedIds = deriveSourcedIds(courseId);
@@ -31246,17 +31895,7 @@ async function deleteTimebackResources(client, courseId) {
31246
31895
  prerequisites: config2.component.prerequisites,
31247
31896
  prerequisiteCriteria: config2.component.prerequisiteCriteria
31248
31897
  }),
31249
- client.oneroster.resources.update(sourcedIds.resource, {
31250
- sourcedId: sourcedIds.resource,
31251
- status: "tobedeleted",
31252
- title: config2.resource.title,
31253
- vendorResourceId: config2.resource.vendorResourceId,
31254
- vendorId: config2.resource.vendorId,
31255
- applicationId: config2.resource.applicationId,
31256
- roles: config2.resource.roles,
31257
- importance: config2.resource.importance,
31258
- metadata: config2.resource.metadata
31259
- }),
31898
+ client.oneroster.resources.delete(sourcedIds.resource),
31260
31899
  client.oneroster.componentResources.update(sourcedIds.componentResource, {
31261
31900
  sourcedId: sourcedIds.componentResource,
31262
31901
  status: "tobedeleted",
@@ -31269,6 +31908,15 @@ async function deleteTimebackResources(client, courseId) {
31269
31908
  ]);
31270
31909
  setAttribute("app.timeback.resources_deleted", true);
31271
31910
  }
31911
+ async function updateTimebackCourseStatus(client, courseId, status) {
31912
+ const course = await client.oneroster.courses.get(courseId);
31913
+ await client.oneroster.courses.update(courseId, {
31914
+ ...course,
31915
+ sourcedId: courseId,
31916
+ status
31917
+ });
31918
+ setAttribute("app.timeback.course_status", status);
31919
+ }
31272
31920
  async function createCourse(client, config2) {
31273
31921
  const courseData = {
31274
31922
  status: "active",
@@ -31517,14 +32165,14 @@ async function getTimebackTokenResponse(config2) {
31517
32165
  }
31518
32166
  }
31519
32167
  function getAuthUrl(environment = "production") {
31520
- return TIMEBACK_AUTH_URLS[environment];
32168
+ return TIMEBACK_AUTH_URLS2[environment];
31521
32169
  }
31522
32170
  function parseEduBridgeGrade(value) {
31523
32171
  if (value === null || value === undefined || value.trim() === "") {
31524
32172
  return null;
31525
32173
  }
31526
32174
  const parsed = Number(value);
31527
- return isTimebackGrade2(parsed) ? parsed : null;
32175
+ return isTimebackGrade3(parsed) ? parsed : null;
31528
32176
  }
31529
32177
  function normalizeHighestGradeMastered(response, subject) {
31530
32178
  const grades = {
@@ -31601,12 +32249,12 @@ async function withTimebackClientTelemetry(fn) {
31601
32249
  }
31602
32250
  function handleHttpError(res, errorBody, attempt, retries, context2) {
31603
32251
  const error = new TimebackApiError(res.status, res.statusText, errorBody);
31604
- if (res.status >= HTTP_STATUS.CLIENT_ERROR_MIN && res.status < HTTP_STATUS.CLIENT_ERROR_MAX) {
32252
+ if (res.status >= HTTP_STATUS2.CLIENT_ERROR_MIN && res.status < HTTP_STATUS2.CLIENT_ERROR_MAX) {
31605
32253
  recordTimebackHttpFailure();
31606
32254
  throw error;
31607
32255
  }
31608
32256
  if (attempt < retries) {
31609
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32257
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31610
32258
  recordTimebackRetry();
31611
32259
  addEvent("timeback.request_retry", {
31612
32260
  "app.timeback.attempt": attempt + 1,
@@ -31683,7 +32331,7 @@ async function request({
31683
32331
  const result = handleHttpError(res, errorBody, attempt, retries, { method, path });
31684
32332
  lastError = result.error;
31685
32333
  if (result.retry) {
31686
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32334
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31687
32335
  await new Promise((resolve) => setTimeout(resolve, delay));
31688
32336
  }
31689
32337
  } else {
@@ -31695,7 +32343,7 @@ async function request({
31695
32343
  }
31696
32344
  lastError = error instanceof Error ? error : new Error(String(error));
31697
32345
  if (attempt < retries) {
31698
- const delay = HTTP_DEFAULTS.retryBackoffBase ** attempt * 1000;
32346
+ const delay = HTTP_DEFAULTS2.retryBackoffBase ** attempt * 1000;
31699
32347
  recordTimebackRetry();
31700
32348
  addEvent("timeback.network_retry", {
31701
32349
  "app.timeback.attempt": attempt + 1,
@@ -31744,10 +32392,10 @@ function createCaliperNamespace(client) {
31744
32392
  const envelope = {
31745
32393
  sensor: sensorUrl,
31746
32394
  sendTime: new Date().toISOString(),
31747
- dataVersion: CALIPER_CONSTANTS.dataVersion,
32395
+ dataVersion: CALIPER_CONSTANTS2.dataVersion,
31748
32396
  data: [event]
31749
32397
  };
31750
- return client["requestCaliper"](CALIPER_ENDPOINTS.event, "POST", envelope);
32398
+ return client["requestCaliper"](CALIPER_ENDPOINTS2.event, "POST", envelope);
31751
32399
  },
31752
32400
  emitBatch: async (events, sensorUrl) => {
31753
32401
  if (events.length === 0) {
@@ -31756,10 +32404,10 @@ function createCaliperNamespace(client) {
31756
32404
  const envelope = {
31757
32405
  sensor: sensorUrl,
31758
32406
  sendTime: new Date().toISOString(),
31759
- dataVersion: CALIPER_CONSTANTS.dataVersion,
32407
+ dataVersion: CALIPER_CONSTANTS2.dataVersion,
31760
32408
  data: events
31761
32409
  };
31762
- return client["requestCaliper"](CALIPER_ENDPOINTS.event, "POST", envelope);
32410
+ return client["requestCaliper"](CALIPER_ENDPOINTS2.event, "POST", envelope);
31763
32411
  },
31764
32412
  events: {
31765
32413
  list: async (params = {}) => {
@@ -31789,7 +32437,7 @@ function createCaliperNamespace(client) {
31789
32437
  query.set(`extensions.${key}`, value);
31790
32438
  }
31791
32439
  }
31792
- const requestPath = `${CALIPER_ENDPOINTS.events}?${query.toString()}`;
32440
+ const requestPath = `${CALIPER_ENDPOINTS2.events}?${query.toString()}`;
31793
32441
  return client["requestCaliper"](requestPath, "GET");
31794
32442
  }
31795
32443
  },
@@ -31799,21 +32447,21 @@ function createCaliperNamespace(client) {
31799
32447
  gameId: data.gameId
31800
32448
  });
31801
32449
  const event = {
31802
- "@context": CALIPER_CONSTANTS.context,
32450
+ "@context": CALIPER_CONSTANTS2.context,
31803
32451
  id: `urn:uuid:${crypto.randomUUID()}`,
31804
- type: TIMEBACK_EVENT_TYPES.activityEvent,
32452
+ type: TIMEBACK_EVENT_TYPES2.activityEvent,
31805
32453
  eventTime: data.eventTime || new Date().toISOString(),
31806
- profile: CALIPER_CONSTANTS.profile,
32454
+ profile: CALIPER_CONSTANTS2.profile,
31807
32455
  actor: {
31808
32456
  id: urls.user(data.studentId),
31809
- type: TIMEBACK_TYPES.user,
32457
+ type: TIMEBACK_TYPES2.user,
31810
32458
  email: data.studentEmail
31811
32459
  },
31812
- action: TIMEBACK_ACTIONS.completed,
32460
+ action: TIMEBACK_ACTIONS2.completed,
31813
32461
  ...data.runId ? { session: `urn:uuid:${data.runId}` } : {},
31814
32462
  object: {
31815
32463
  id: data.objectId || caliper.buildActivityUrl(data),
31816
- type: TIMEBACK_TYPES.activityContext,
32464
+ type: TIMEBACK_TYPES2.activityContext,
31817
32465
  subject: data.subject,
31818
32466
  app: {
31819
32467
  name: data.appName
@@ -31827,25 +32475,25 @@ function createCaliperNamespace(client) {
31827
32475
  },
31828
32476
  generated: {
31829
32477
  id: data.generatedId || `urn:timeback:metrics:activity-completion-${crypto.randomUUID()}`,
31830
- type: TIMEBACK_TYPES.activityMetricsCollection,
32478
+ type: TIMEBACK_TYPES2.activityMetricsCollection,
31831
32479
  ...data.includeAttempt === false ? {} : { attempt: data.attemptNumber || 1 },
31832
32480
  items: [
31833
32481
  ...data.totalQuestions !== undefined ? [
31834
32482
  {
31835
- type: ACTIVITY_METRIC_TYPES.totalQuestions,
32483
+ type: ACTIVITY_METRIC_TYPES2.totalQuestions,
31836
32484
  value: data.totalQuestions
31837
32485
  }
31838
32486
  ] : [],
31839
32487
  ...data.correctQuestions !== undefined ? [
31840
32488
  {
31841
- type: ACTIVITY_METRIC_TYPES.correctQuestions,
32489
+ type: ACTIVITY_METRIC_TYPES2.correctQuestions,
31842
32490
  value: data.correctQuestions
31843
32491
  }
31844
32492
  ] : [],
31845
- ...data.xpEarned !== undefined ? [{ type: ACTIVITY_METRIC_TYPES.xpEarned, value: data.xpEarned }] : [],
32493
+ ...data.xpEarned !== undefined ? [{ type: ACTIVITY_METRIC_TYPES2.xpEarned, value: data.xpEarned }] : [],
31846
32494
  ...data.masteredUnits !== undefined ? [
31847
32495
  {
31848
- type: ACTIVITY_METRIC_TYPES.masteredUnits,
32496
+ type: ACTIVITY_METRIC_TYPES2.masteredUnits,
31849
32497
  value: data.masteredUnits
31850
32498
  }
31851
32499
  ] : []
@@ -31867,21 +32515,21 @@ function createCaliperNamespace(client) {
31867
32515
  gameId: data.gameId
31868
32516
  });
31869
32517
  const event = {
31870
- "@context": CALIPER_CONSTANTS.context,
32518
+ "@context": CALIPER_CONSTANTS2.context,
31871
32519
  id: `urn:uuid:${crypto.randomUUID()}`,
31872
- type: TIMEBACK_EVENT_TYPES.timeSpentEvent,
32520
+ type: TIMEBACK_EVENT_TYPES2.timeSpentEvent,
31873
32521
  eventTime: data.eventTime || new Date().toISOString(),
31874
- profile: CALIPER_CONSTANTS.profile,
32522
+ profile: CALIPER_CONSTANTS2.profile,
31875
32523
  actor: {
31876
32524
  id: urls.user(data.studentId),
31877
- type: TIMEBACK_TYPES.user,
32525
+ type: TIMEBACK_TYPES2.user,
31878
32526
  email: data.studentEmail
31879
32527
  },
31880
- action: TIMEBACK_ACTIONS.spentTime,
32528
+ action: TIMEBACK_ACTIONS2.spentTime,
31881
32529
  ...data.runId ? { session: `urn:uuid:${data.runId}` } : {},
31882
32530
  object: {
31883
32531
  id: caliper.buildActivityUrl(data),
31884
- type: TIMEBACK_TYPES.activityContext,
32532
+ type: TIMEBACK_TYPES2.activityContext,
31885
32533
  subject: data.subject,
31886
32534
  app: {
31887
32535
  name: data.appName
@@ -31894,16 +32542,16 @@ function createCaliperNamespace(client) {
31894
32542
  },
31895
32543
  generated: {
31896
32544
  id: `urn:timeback:metrics:time-spent-${crypto.randomUUID()}`,
31897
- type: TIMEBACK_TYPES.timeSpentMetricsCollection,
32545
+ type: TIMEBACK_TYPES2.timeSpentMetricsCollection,
31898
32546
  items: [
31899
- { type: TIME_METRIC_TYPES.active, value: data.activeTimeSeconds },
32547
+ { type: TIME_METRIC_TYPES2.active, value: data.activeTimeSeconds },
31900
32548
  ...data.inactiveTimeSeconds !== undefined ? [
31901
32549
  {
31902
- type: TIME_METRIC_TYPES.inactive,
32550
+ type: TIME_METRIC_TYPES2.inactive,
31903
32551
  value: data.inactiveTimeSeconds
31904
32552
  }
31905
32553
  ] : [],
31906
- ...data.wasteTimeSeconds !== undefined ? [{ type: TIME_METRIC_TYPES.waste, value: data.wasteTimeSeconds }] : []
32554
+ ...data.wasteTimeSeconds !== undefined ? [{ type: TIME_METRIC_TYPES2.waste, value: data.wasteTimeSeconds }] : []
31907
32555
  ],
31908
32556
  ...data.extensions ? { extensions: data.extensions } : {}
31909
32557
  },
@@ -31914,7 +32562,8 @@ function createCaliperNamespace(client) {
31914
32562
  buildActivityUrl: (data) => {
31915
32563
  const base = data.sensorUrl.replace(/\/$/, "");
31916
32564
  return `${base}/activities/${encodeURIComponent(data.courseId)}/${encodeURIComponent(data.activityId)}`;
31917
- }
32565
+ },
32566
+ buildCourseUrl: (courseId) => urls.course(courseId)
31918
32567
  };
31919
32568
  return caliper;
31920
32569
  }
@@ -32037,17 +32686,17 @@ async function listOneRosterCollection(client, endpoint, collectionKey, options)
32037
32686
  function createOneRosterNamespace(client) {
32038
32687
  return {
32039
32688
  classes: {
32040
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.classes, "POST", { class: data }),
32689
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.classes, "POST", { class: data }),
32041
32690
  get: async (sourcedId) => {
32042
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.classes}/${sourcedId}`, "GET");
32691
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.classes}/${sourcedId}`, "GET");
32043
32692
  return res.class;
32044
32693
  },
32045
32694
  update: async (sourcedId, data) => {
32046
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.classes}/${sourcedId}`, "PUT", { class: data });
32695
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.classes}/${sourcedId}`, "PUT", { class: data });
32047
32696
  return res.class;
32048
32697
  },
32049
32698
  listByCourse: async (courseSourcedId) => {
32050
- const res = await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${courseSourcedId}/classes`, "GET");
32699
+ const res = await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${courseSourcedId}/classes`, "GET");
32051
32700
  return res.classes;
32052
32701
  },
32053
32702
  listByStudent: async (userSourcedId, options) => {
@@ -32058,7 +32707,7 @@ function createOneRosterNamespace(client) {
32058
32707
  if (options?.offset) {
32059
32708
  queryParams.set("offset", String(options.offset));
32060
32709
  }
32061
- const endpoint = `${ONEROSTER_ENDPOINTS.users}/${userSourcedId}/classes`;
32710
+ const endpoint = `${ONEROSTER_ENDPOINTS2.users}/${userSourcedId}/classes`;
32062
32711
  const url2 = queryParams.toString() ? `${endpoint}?${queryParams}` : endpoint;
32063
32712
  const res = await client["request"](url2, "GET");
32064
32713
  return res.classes || [];
@@ -32066,7 +32715,7 @@ function createOneRosterNamespace(client) {
32066
32715
  },
32067
32716
  enrollments: {
32068
32717
  get: async (sourcedId) => {
32069
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "GET");
32718
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "GET");
32070
32719
  return response.enrollment;
32071
32720
  },
32072
32721
  listByClass: async (classSourcedId, options) => {
@@ -32082,7 +32731,7 @@ function createOneRosterNamespace(client) {
32082
32731
  if (options?.offset) {
32083
32732
  queryParams.set("offset", String(options.offset));
32084
32733
  }
32085
- const url2 = `${ONEROSTER_ENDPOINTS.enrollments}?${queryParams}`;
32734
+ const url2 = `${ONEROSTER_ENDPOINTS2.enrollments}?${queryParams}`;
32086
32735
  try {
32087
32736
  const response = await client["request"](url2, "GET");
32088
32737
  return response.enrollments || [];
@@ -32115,7 +32764,7 @@ function createOneRosterNamespace(client) {
32115
32764
  }
32116
32765
  queryParams.set("filter", filters.join(" AND "));
32117
32766
  queryParams.set("limit", "3000");
32118
- const url2 = `${ONEROSTER_ENDPOINTS.enrollments}?${queryParams}`;
32767
+ const url2 = `${ONEROSTER_ENDPOINTS2.enrollments}?${queryParams}`;
32119
32768
  const response = await client["request"](url2, "GET");
32120
32769
  return response.enrollments || [];
32121
32770
  }));
@@ -32145,72 +32794,72 @@ function createOneRosterNamespace(client) {
32145
32794
  throw error;
32146
32795
  }
32147
32796
  },
32148
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.enrollments, "POST", { enrollment: data }),
32797
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.enrollments, "POST", { enrollment: data }),
32149
32798
  update: async (sourcedId, data) => {
32150
- await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "PUT", {
32799
+ await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "PUT", {
32151
32800
  enrollment: data
32152
32801
  });
32153
32802
  },
32154
32803
  delete: async (sourcedId) => {
32155
- await client["request"](`${ONEROSTER_ENDPOINTS.enrollments}/${sourcedId}`, "DELETE");
32804
+ await client["request"](`${ONEROSTER_ENDPOINTS2.enrollments}/${sourcedId}`, "DELETE");
32156
32805
  }
32157
32806
  },
32158
32807
  organizations: {
32159
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.organizations, "POST", data),
32160
- get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS.organizations}/${sourcedId}`, "GET").then((res) => res.org),
32161
- update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS.organizations}/${sourcedId}`, "PUT", data)
32808
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.organizations, "POST", data),
32809
+ get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS2.organizations}/${sourcedId}`, "GET").then((res) => res.org),
32810
+ update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS2.organizations}/${sourcedId}`, "PUT", data)
32162
32811
  },
32163
32812
  courses: {
32164
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.courses, "POST", data),
32813
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.courses, "POST", data),
32165
32814
  get: async (sourcedId) => {
32166
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${sourcedId}`, "GET");
32815
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${sourcedId}`, "GET");
32167
32816
  return response.course;
32168
32817
  },
32169
32818
  update: async (sourcedId, data) => {
32170
- await client["request"](`${ONEROSTER_ENDPOINTS.courses}/${sourcedId}`, "PUT", {
32819
+ await client["request"](`${ONEROSTER_ENDPOINTS2.courses}/${sourcedId}`, "PUT", {
32171
32820
  course: data
32172
32821
  });
32173
32822
  }
32174
32823
  },
32175
32824
  courseComponents: {
32176
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.courseComponents, "POST", data),
32825
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.courseComponents, "POST", data),
32177
32826
  get: async (sourcedId) => {
32178
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.courseComponents}/${sourcedId}`, "GET");
32827
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.courseComponents}/${sourcedId}`, "GET");
32179
32828
  return response.courseComponent;
32180
32829
  },
32181
32830
  update: async (sourcedId, data) => {
32182
- await client["request"](`${ONEROSTER_ENDPOINTS.courseComponents}/${sourcedId}`, "PUT", { courseComponent: data });
32831
+ await client["request"](`${ONEROSTER_ENDPOINTS2.courseComponents}/${sourcedId}`, "PUT", { courseComponent: data });
32183
32832
  }
32184
32833
  },
32185
32834
  resources: {
32186
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.resources, "POST", data),
32835
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.resources, "POST", data),
32187
32836
  get: async (sourcedId) => {
32188
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "GET");
32837
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "GET");
32189
32838
  return response.resource;
32190
32839
  },
32191
32840
  update: async (sourcedId, data) => {
32192
- await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "PUT", {
32841
+ await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "PUT", {
32193
32842
  resource: data
32194
32843
  });
32195
32844
  },
32196
32845
  delete: async (sourcedId) => {
32197
- await client["request"](`${ONEROSTER_ENDPOINTS.resources}/${sourcedId}`, "DELETE");
32846
+ await client["request"](`${ONEROSTER_ENDPOINTS2.resources}/${sourcedId}`, "DELETE");
32198
32847
  }
32199
32848
  },
32200
32849
  componentResources: {
32201
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.componentResources, "POST", data),
32850
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.componentResources, "POST", data),
32202
32851
  get: async (sourcedId) => {
32203
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.componentResources}/${sourcedId}`, "GET");
32852
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.componentResources}/${sourcedId}`, "GET");
32204
32853
  return response.componentResource;
32205
32854
  },
32206
32855
  update: async (sourcedId, data) => {
32207
- await client["request"](`${ONEROSTER_ENDPOINTS.componentResources}/${sourcedId}`, "PUT", { componentResource: data });
32856
+ await client["request"](`${ONEROSTER_ENDPOINTS2.componentResources}/${sourcedId}`, "PUT", { componentResource: data });
32208
32857
  }
32209
32858
  },
32210
32859
  assessmentLineItems: {
32211
32860
  list: async (options) => {
32212
32861
  try {
32213
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentLineItems, "assessmentLineItems", options);
32862
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentLineItems, "assessmentLineItems", options);
32214
32863
  } catch (error) {
32215
32864
  logTimebackError("list assessment line items", error, {
32216
32865
  filter: options?.filter
@@ -32218,14 +32867,14 @@ function createOneRosterNamespace(client) {
32218
32867
  return [];
32219
32868
  }
32220
32869
  },
32221
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.assessmentLineItems, "POST", { assessmentLineItem: data }),
32870
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.assessmentLineItems, "POST", { assessmentLineItem: data }),
32222
32871
  get: async (sourcedId) => {
32223
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentLineItems}/${sourcedId}`, "GET");
32872
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentLineItems}/${sourcedId}`, "GET");
32224
32873
  return response.assessmentLineItem;
32225
32874
  },
32226
32875
  findOrCreate: async (sourcedId, data) => {
32227
32876
  try {
32228
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentLineItems}/${sourcedId}`, "GET");
32877
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentLineItems}/${sourcedId}`, "GET");
32229
32878
  return response.assessmentLineItem;
32230
32879
  } catch {
32231
32880
  const createData = {
@@ -32234,7 +32883,7 @@ function createOneRosterNamespace(client) {
32234
32883
  dateLastModified: new Date().toISOString()
32235
32884
  };
32236
32885
  try {
32237
- const response = await client["request"](ONEROSTER_ENDPOINTS.assessmentLineItems, "POST", { assessmentLineItem: createData });
32886
+ const response = await client["request"](ONEROSTER_ENDPOINTS2.assessmentLineItems, "POST", { assessmentLineItem: createData });
32238
32887
  if (!response.sourcedIdPairs?.allocatedSourcedId) {
32239
32888
  throw new Error("Invalid response from OneRoster API - missing allocatedSourcedId");
32240
32889
  }
@@ -32249,7 +32898,7 @@ function createOneRosterNamespace(client) {
32249
32898
  assessmentResults: {
32250
32899
  list: async (options) => {
32251
32900
  try {
32252
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentResults, "assessmentResults", options);
32901
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", options);
32253
32902
  } catch (error) {
32254
32903
  logTimebackError("list assessment results", error, {
32255
32904
  filter: options?.filter
@@ -32257,10 +32906,11 @@ function createOneRosterNamespace(client) {
32257
32906
  return [];
32258
32907
  }
32259
32908
  },
32260
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.assessmentResults, "POST", { assessmentResult: data }),
32909
+ listOrThrow: async (options) => await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", options),
32910
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.assessmentResults, "POST", { assessmentResult: data }),
32261
32911
  listByStudent: async (studentSourcedId, options) => {
32262
32912
  try {
32263
- return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS.assessmentResults, "assessmentResults", {
32913
+ return await listOneRosterCollection(client, ONEROSTER_ENDPOINTS2.assessmentResults, "assessmentResults", {
32264
32914
  limit: options?.limit,
32265
32915
  offset: options?.offset,
32266
32916
  fields: options?.fields,
@@ -32279,54 +32929,22 @@ function createOneRosterNamespace(client) {
32279
32929
  sourcedId,
32280
32930
  dateLastModified: new Date().toISOString()
32281
32931
  };
32282
- return client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "PUT", { assessmentResult });
32932
+ return client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "PUT", { assessmentResult });
32283
32933
  },
32284
32934
  get: async (sourcedId) => {
32285
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "GET");
32935
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "GET");
32286
32936
  return response.assessmentResult;
32287
32937
  },
32288
- update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS.assessmentResults}/${sourcedId}`, "PUT", data),
32289
- getAttemptStats: async (studentId, lineItemId) => {
32290
- try {
32291
- const filter = `student.sourcedId='${studentId}' AND assessmentLineItem.sourcedId='${lineItemId}'`;
32292
- const url2 = `${ONEROSTER_ENDPOINTS.assessmentResults}?filter=${encodeURIComponent(filter)}`;
32293
- const response = await client["request"](url2, "GET");
32294
- const results = response.assessmentResults || [];
32295
- const firstResult = results[0];
32296
- if (!firstResult) {
32297
- return null;
32298
- }
32299
- let maxAttemptResult = firstResult;
32300
- let maxAttemptNumber = maxAttemptResult.metadata?.attemptNumber || 0;
32301
- let activeAttemptCount = 0;
32302
- for (const result of results) {
32303
- const attemptNumber = result.metadata?.attemptNumber || 0;
32304
- if (attemptNumber > maxAttemptNumber) {
32305
- maxAttemptNumber = attemptNumber;
32306
- maxAttemptResult = result;
32307
- }
32308
- if (result.status === "active") {
32309
- activeAttemptCount++;
32310
- }
32311
- }
32312
- return { maxAttemptNumber, activeAttemptCount, maxAttemptResult };
32313
- } catch (error) {
32314
- logTimebackError("query attempt stats", error, {
32315
- studentId,
32316
- lineItemId
32317
- });
32318
- return null;
32319
- }
32320
- }
32938
+ update: async (sourcedId, data) => client["request"](`${ONEROSTER_ENDPOINTS2.assessmentResults}/${sourcedId}`, "PUT", data)
32321
32939
  },
32322
32940
  users: {
32323
- create: async (data) => client["request"](ONEROSTER_ENDPOINTS.users, "POST", {
32941
+ create: async (data) => client["request"](ONEROSTER_ENDPOINTS2.users, "POST", {
32324
32942
  user: data
32325
32943
  }),
32326
- get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS.users}/${sourcedId}`, "GET").then((res) => res.user),
32944
+ get: async (sourcedId) => client["request"](`${ONEROSTER_ENDPOINTS2.users}/${sourcedId}`, "GET").then((res) => res.user),
32327
32945
  findByEmail: async (email) => {
32328
32946
  const params = new URLSearchParams({ filter: `email='${email}'` });
32329
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.users}?${params}`, "GET");
32947
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.users}?${params}`, "GET");
32330
32948
  if (!response || !response.users || !Array.isArray(response.users)) {
32331
32949
  throw new Error(`Invalid response format from OneRoster API when searching for user with email: ${email}. ` + `Expected { users: [...] } but received: ${JSON.stringify(response)}`);
32332
32950
  }
@@ -32345,7 +32963,7 @@ function createOneRosterNamespace(client) {
32345
32963
  const results = await Promise.all(batches.map(async (batch) => {
32346
32964
  const filter = batch.map((id) => `sourcedId='${escapeFilterValue(id)}'`).join(" OR ");
32347
32965
  const params = new URLSearchParams({ filter });
32348
- const response = await client["request"](`${ONEROSTER_ENDPOINTS.users}?${params}`, "GET");
32966
+ const response = await client["request"](`${ONEROSTER_ENDPOINTS2.users}?${params}`, "GET");
32349
32967
  return response.users || [];
32350
32968
  }));
32351
32969
  return results.flat();
@@ -32362,11 +32980,11 @@ function createOneRosterNamespace(client) {
32362
32980
  function createQtiNamespace(client) {
32363
32981
  return {
32364
32982
  items: {
32365
- create: async (data) => client["requestQti"](QTI_ENDPOINTS.assessmentItems, "POST", data),
32366
- get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "GET"),
32367
- update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "PUT", data),
32983
+ create: async (data) => client["requestQti"](QTI_ENDPOINTS2.assessmentItems, "POST", data),
32984
+ get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "GET"),
32985
+ update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "PUT", data),
32368
32986
  delete: async (identifier) => {
32369
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentItems}/${identifier}`, "DELETE");
32987
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentItems}/${identifier}`, "DELETE");
32370
32988
  }
32371
32989
  },
32372
32990
  tests: {
@@ -32388,25 +33006,25 @@ function createQtiNamespace(client) {
32388
33006
  params.set("order", options.order);
32389
33007
  }
32390
33008
  const query = params.toString();
32391
- return client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}${query ? `?${query}` : ""}`, "GET");
33009
+ return client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}${query ? `?${query}` : ""}`, "GET");
32392
33010
  },
32393
- create: async (data) => client["requestQti"](QTI_ENDPOINTS.assessmentTests, "POST", data),
32394
- get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "GET"),
32395
- getQuestions: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}/questions`, "GET"),
32396
- update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "PUT", data),
33011
+ create: async (data) => client["requestQti"](QTI_ENDPOINTS2.assessmentTests, "POST", data),
33012
+ get: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "GET"),
33013
+ getQuestions: async (identifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}/questions`, "GET"),
33014
+ update: async (identifier, data) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "PUT", data),
32397
33015
  delete: async (identifier) => {
32398
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${identifier}`, "DELETE");
33016
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${identifier}`, "DELETE");
32399
33017
  },
32400
- addItem: async (testId, partId, sectionId, itemIdentifier) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items`, "POST", { identifier: itemIdentifier }),
33018
+ addItem: async (testId, partId, sectionId, itemIdentifier) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items`, "POST", { identifier: itemIdentifier }),
32401
33019
  removeItem: async (testId, partId, sectionId, itemIdentifier) => {
32402
- await client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/${itemIdentifier}`, "DELETE");
33020
+ await client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/${itemIdentifier}`, "DELETE");
32403
33021
  },
32404
- reorderItems: async (testId, partId, sectionId, items) => client["requestQti"](`${QTI_ENDPOINTS.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/order`, "PUT", { items })
33022
+ reorderItems: async (testId, partId, sectionId, items) => client["requestQti"](`${QTI_ENDPOINTS2.assessmentTests}/${testId}/test-parts/${partId}/sections/${sectionId}/items/order`, "PUT", { items })
32405
33023
  }
32406
33024
  };
32407
33025
  }
32408
33026
  function toCaliperSubject(subject) {
32409
- return isTimebackSubject2(subject) ? subject : "None";
33027
+ return isTimebackSubject3(subject) ? subject : "None";
32410
33028
  }
32411
33029
  function buildAdminEventMetadata({
32412
33030
  reason,
@@ -32470,7 +33088,7 @@ class AdminEventRecorder {
32470
33088
  defaultActivityId: "playcademy-admin-manual-xp",
32471
33089
  eventKind: "remediation-xp"
32472
33090
  });
32473
- const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS[this.environment]).course(data.courseId);
33091
+ const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS2[this.environment]).course(data.courseId);
32474
33092
  await this.caliper.emitActivityEvent({
32475
33093
  studentId: ctx.student.id,
32476
33094
  studentEmail: ctx.student.email,
@@ -32520,7 +33138,7 @@ class AdminEventRecorder {
32520
33138
  defaultActivityId: "playcademy-admin-mastery-adjustment",
32521
33139
  eventKind: "remediation-mastery"
32522
33140
  });
32523
- const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS[this.environment]).course(data.courseId);
33141
+ const courseUrl = createOneRosterUrls(TIMEBACK_API_URLS2[this.environment]).course(data.courseId);
32524
33142
  await this.caliper.emitActivityEvent({
32525
33143
  studentId: ctx.student.id,
32526
33144
  studentEmail: ctx.student.email,
@@ -32554,9 +33172,9 @@ class TimebackCache {
32554
33172
  maxSize;
32555
33173
  name;
32556
33174
  constructor(options = {}) {
32557
- this.defaultTTL = options.defaultTTL || CACHE_DEFAULTS.defaultTTL;
32558
- this.maxSize = options.maxSize || CACHE_DEFAULTS.defaultMaxSize;
32559
- this.name = options.name || CACHE_DEFAULTS.defaultName;
33175
+ this.defaultTTL = options.defaultTTL || CACHE_DEFAULTS2.defaultTTL;
33176
+ this.maxSize = options.maxSize || CACHE_DEFAULTS2.defaultMaxSize;
33177
+ this.name = options.name || CACHE_DEFAULTS2.defaultName;
32560
33178
  }
32561
33179
  get(key) {
32562
33180
  const entry = this.cache.get(key);
@@ -32647,23 +33265,23 @@ class TimebackCacheManager {
32647
33265
  enrollmentCache;
32648
33266
  constructor() {
32649
33267
  this.studentCache = new TimebackCache({
32650
- defaultTTL: CACHE_DEFAULTS.studentTTL,
32651
- maxSize: CACHE_DEFAULTS.studentMaxSize,
33268
+ defaultTTL: CACHE_DEFAULTS2.studentTTL,
33269
+ maxSize: CACHE_DEFAULTS2.studentMaxSize,
32652
33270
  name: "StudentCache"
32653
33271
  });
32654
33272
  this.assessmentLineItemCache = new TimebackCache({
32655
- defaultTTL: CACHE_DEFAULTS.assessmentTTL,
32656
- maxSize: CACHE_DEFAULTS.assessmentMaxSize,
33273
+ defaultTTL: CACHE_DEFAULTS2.assessmentTTL,
33274
+ maxSize: CACHE_DEFAULTS2.assessmentMaxSize,
32657
33275
  name: "AssessmentLineItemCache"
32658
33276
  });
32659
33277
  this.resourceMasteryCache = new TimebackCache({
32660
- defaultTTL: CACHE_DEFAULTS.assessmentTTL,
32661
- maxSize: CACHE_DEFAULTS.assessmentMaxSize,
33278
+ defaultTTL: CACHE_DEFAULTS2.assessmentTTL,
33279
+ maxSize: CACHE_DEFAULTS2.assessmentMaxSize,
32662
33280
  name: "ResourceMasteryCache"
32663
33281
  });
32664
33282
  this.enrollmentCache = new TimebackCache({
32665
- defaultTTL: CACHE_DEFAULTS.enrollmentTTL,
32666
- maxSize: CACHE_DEFAULTS.enrollmentMaxSize,
33283
+ defaultTTL: CACHE_DEFAULTS2.enrollmentTTL,
33284
+ maxSize: CACHE_DEFAULTS2.enrollmentMaxSize,
32667
33285
  name: "EnrollmentCache"
32668
33286
  });
32669
33287
  }
@@ -32919,18 +33537,18 @@ class MasteryTracker {
32919
33537
  await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
32920
33538
  sourcedId: lineItemId,
32921
33539
  title: "Mastery Completion",
32922
- status: ONEROSTER_STATUS.active,
33540
+ status: ONEROSTER_STATUS2.active,
32923
33541
  ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } },
32924
33542
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
32925
33543
  });
32926
33544
  await this.onerosterNamespace.assessmentResults.upsert(resultId, {
32927
33545
  sourcedId: resultId,
32928
- status: ONEROSTER_STATUS.active,
33546
+ status: ONEROSTER_STATUS2.active,
32929
33547
  assessmentLineItem: { sourcedId: lineItemId },
32930
33548
  student: { sourcedId: studentId },
32931
33549
  score: 100,
32932
33550
  scoreDate: new Date().toISOString(),
32933
- scoreStatus: SCORE_STATUS.fullyGraded,
33551
+ scoreStatus: SCORE_STATUS2.fullyGraded,
32934
33552
  inProgress: "false",
32935
33553
  metadata: {
32936
33554
  isMasteryCompletion: true,
@@ -32942,6 +33560,7 @@ class MasteryTracker {
32942
33560
  "app.timeback.line_item_id": lineItemId,
32943
33561
  "app.timeback.result_id": resultId
32944
33562
  });
33563
+ return true;
32945
33564
  } catch (error) {
32946
33565
  addEvent("timeback.mastery_completion_failed", {
32947
33566
  "app.timeback.student_id": studentId,
@@ -32949,6 +33568,7 @@ class MasteryTracker {
32949
33568
  "exception.type": errorType(error),
32950
33569
  "app.error.message": errorMessage(error)
32951
33570
  });
33571
+ return false;
32952
33572
  }
32953
33573
  }
32954
33574
  async revokeCompletionEntry(studentId, courseId, classId, appName) {
@@ -32959,18 +33579,18 @@ class MasteryTracker {
32959
33579
  await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
32960
33580
  sourcedId: lineItemId,
32961
33581
  title: "Mastery Completion",
32962
- status: ONEROSTER_STATUS.active,
33582
+ status: ONEROSTER_STATUS2.active,
32963
33583
  ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } },
32964
33584
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
32965
33585
  });
32966
33586
  await this.onerosterNamespace.assessmentResults.upsert(resultId, {
32967
33587
  sourcedId: resultId,
32968
- status: ONEROSTER_STATUS.active,
33588
+ status: ONEROSTER_STATUS2.active,
32969
33589
  assessmentLineItem: { sourcedId: lineItemId },
32970
33590
  student: { sourcedId: studentId },
32971
33591
  score: 0,
32972
33592
  scoreDate: new Date().toISOString(),
32973
- scoreStatus: SCORE_STATUS.notSubmitted,
33593
+ scoreStatus: SCORE_STATUS2.notSubmitted,
32974
33594
  inProgress: "true",
32975
33595
  metadata: {
32976
33596
  isMasteryCompletion: true,
@@ -33005,7 +33625,7 @@ class MasteryTracker {
33005
33625
  if (!playcademyMetadata) {
33006
33626
  return;
33007
33627
  }
33008
- const masterableUnits = isPlaycademyResourceMetadata(playcademyMetadata) ? playcademyMetadata.mastery?.masterableUnits : undefined;
33628
+ const masterableUnits = isPlaycademyResourceMetadata2(playcademyMetadata) ? playcademyMetadata.mastery?.masterableUnits : undefined;
33009
33629
  this.cacheManager.setResourceMasterableUnits(resourceId, masterableUnits ?? null);
33010
33630
  return masterableUnits;
33011
33631
  } catch (error) {
@@ -33085,13 +33705,11 @@ function validateSessionData(sessionData) {
33085
33705
 
33086
33706
  class ProgressRecorder {
33087
33707
  studentResolver;
33088
- cacheManager;
33089
33708
  onerosterNamespace;
33090
33709
  caliperNamespace;
33091
33710
  masteryTracker;
33092
- constructor(studentResolver, cacheManager, onerosterNamespace, caliperNamespace, masteryTracker) {
33711
+ constructor(studentResolver, onerosterNamespace, caliperNamespace, masteryTracker) {
33093
33712
  this.studentResolver = studentResolver;
33094
- this.cacheManager = cacheManager;
33095
33713
  this.onerosterNamespace = onerosterNamespace;
33096
33714
  this.caliperNamespace = caliperNamespace;
33097
33715
  this.masteryTracker = masteryTracker;
@@ -33100,26 +33718,37 @@ class ProgressRecorder {
33100
33718
  validateProgressData(progressData);
33101
33719
  const { ids, activityId, activityName, courseName, student } = await this.resolveContext(courseId, studentIdentifier, progressData);
33102
33720
  const { id: studentId, email: studentEmail } = student;
33103
- const {
33104
- score,
33105
- totalQuestions,
33106
- correctQuestions,
33107
- xpEarned = 0,
33108
- attemptNumber
33109
- } = progressData;
33110
- let extensions = progressData.extensions;
33111
- const masteryProgress = await this.masteryTracker.checkProgress({
33112
- studentId,
33113
- courseId,
33114
- resourceId: ids.resource,
33115
- masteredUnits: progressData.masteredUnits ?? 0,
33116
- masteredUnitsAbsolute: progressData.masteredUnitsAbsolute
33721
+ const { totalQuestions, correctQuestions, xpEarned = 0, attemptNumber } = progressData;
33722
+ const activityUrl = this.caliperNamespace.buildActivityUrl({
33723
+ courseId: ids.course,
33724
+ activityId,
33725
+ sensorUrl: progressData.sensorUrl
33117
33726
  });
33727
+ const courseUrl = this.caliperNamespace.buildCourseUrl(ids.course);
33728
+ let caliperLineItemId;
33729
+ try {
33730
+ caliperLineItemId = computeCaliperLineItemId(activityUrl, ids.course, courseUrl);
33731
+ } catch (error) {
33732
+ setAttributes({ "app.timeback.course_id_not_url_safe": true });
33733
+ throw error;
33734
+ }
33735
+ const legacyLineItemId = `${ids.course}-${activityId}-assessment`;
33736
+ const [currentAttemptNumber, masteryProgress] = await Promise.all([
33737
+ this.resolveAttemptNumber(attemptNumber, studentId, caliperLineItemId, legacyLineItemId),
33738
+ this.masteryTracker.checkProgress({
33739
+ studentId,
33740
+ courseId,
33741
+ resourceId: ids.resource,
33742
+ masteredUnits: progressData.masteredUnits ?? 0,
33743
+ masteredUnitsAbsolute: progressData.masteredUnitsAbsolute
33744
+ })
33745
+ ]);
33746
+ setAttributes({ "app.timeback.attempt_number": currentAttemptNumber });
33747
+ let extensions = progressData.extensions;
33118
33748
  const effectiveMasteredUnits = masteryProgress ? masteryProgress.effectiveDelta : progressData.masteredUnits ?? 0;
33119
33749
  let pctCompleteApp;
33120
33750
  let masteryAchieved = false;
33121
- let scoreStatus = SCORE_STATUS.fullyGraded;
33122
- const inProgress = "false";
33751
+ let completionEntryWritten = false;
33123
33752
  const warnings = masteryProgress?.writeWarning ? [masteryProgress.writeWarning] : undefined;
33124
33753
  if (masteryProgress) {
33125
33754
  masteryAchieved = masteryProgress.masteryAchieved;
@@ -33128,32 +33757,12 @@ class ProgressRecorder {
33128
33757
  ...extensions,
33129
33758
  ...pctCompleteApp !== undefined ? { pctCompleteApp } : {}
33130
33759
  };
33131
- if (masteryAchieved) {
33132
- scoreStatus = SCORE_STATUS.fullyGraded;
33133
- }
33134
33760
  }
33135
- const actualLineItemId = await this.resolveAssessmentLineItem(activityId, activityName, progressData.classId, ids);
33136
- const currentAttemptNumber = await this.resolveAttemptNumber(attemptNumber, score, studentId, actualLineItemId);
33137
- if (score !== undefined) {
33138
- await this.createGradebookEntry({
33139
- lineItemId: actualLineItemId,
33140
- studentId,
33141
- attemptNumber: currentAttemptNumber,
33142
- score,
33143
- xp: xpEarned,
33144
- scoreStatus,
33145
- inProgress,
33146
- appName: progressData.appName,
33147
- totalQuestions,
33148
- correctQuestions,
33149
- masteredUnits: effectiveMasteredUnits || undefined,
33150
- pctCompleteApp
33151
- });
33152
- } else {
33153
- setAttribute("app.timeback.score_provided", false);
33761
+ if (masteryAchieved) {
33762
+ setAttributes({ "app.timeback.mastery_achieved": true });
33154
33763
  }
33155
33764
  if (masteryAchieved) {
33156
- await this.masteryTracker.createCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33765
+ completionEntryWritten = await this.masteryTracker.createCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33157
33766
  await this.emitCourseCompletionHistoryEvent({
33158
33767
  studentId,
33159
33768
  studentEmail,
@@ -33169,30 +33778,36 @@ class ProgressRecorder {
33169
33778
  if (masteryProgress?.masteryRevoked) {
33170
33779
  await this.masteryTracker.revokeCompletionEntry(studentId, courseId, progressData.classId, progressData.appName);
33171
33780
  }
33172
- await this.emitCaliperEvent({
33173
- studentId,
33174
- studentEmail,
33175
- gameId: progressData.gameId,
33176
- activityId,
33177
- activityName,
33178
- courseId: ids.course,
33179
- courseName,
33180
- totalQuestions,
33181
- correctQuestions,
33182
- xpEarned,
33183
- masteredUnits: effectiveMasteredUnits || undefined,
33184
- attemptNumber: currentAttemptNumber,
33185
- progressData,
33186
- extensions,
33187
- runId: progressData.runId
33188
- });
33781
+ try {
33782
+ await this.emitCaliperEvent({
33783
+ studentId,
33784
+ studentEmail,
33785
+ gameId: progressData.gameId,
33786
+ activityId,
33787
+ activityName,
33788
+ courseId: ids.course,
33789
+ courseName,
33790
+ totalQuestions,
33791
+ correctQuestions,
33792
+ xpEarned,
33793
+ masteredUnits: effectiveMasteredUnits || undefined,
33794
+ attemptNumber: currentAttemptNumber,
33795
+ objectId: activityUrl,
33796
+ progressData,
33797
+ extensions,
33798
+ runId: progressData.runId
33799
+ });
33800
+ } catch (error) {
33801
+ if (completionEntryWritten) {
33802
+ setAttributes({ "app.timeback.completion_orphaned": true });
33803
+ }
33804
+ throw error;
33805
+ }
33189
33806
  return {
33190
33807
  xpAwarded: xpEarned,
33191
33808
  attemptNumber: currentAttemptNumber,
33192
33809
  masteredUnitsApplied: effectiveMasteredUnits,
33193
33810
  pctCompleteApp,
33194
- scoreStatus,
33195
- inProgress,
33196
33811
  ...warnings ? { warnings } : {}
33197
33812
  };
33198
33813
  }
@@ -33204,89 +33819,48 @@ class ProgressRecorder {
33204
33819
  const student = await this.studentResolver.resolve(studentIdentifier, progressData.studentEmail);
33205
33820
  return { ids, activityId, activityName, courseName, student };
33206
33821
  }
33207
- async resolveAssessmentLineItem(activityId, activityName, classId, ids) {
33208
- const lineItemId = `${ids.course}-${activityId}-assessment`;
33209
- let actualLineItemId = this.cacheManager.getAssessmentLineItem(lineItemId);
33210
- if (!actualLineItemId) {
33211
- actualLineItemId = await this.getOrCreateLineItem(lineItemId, activityName, classId, ids);
33212
- this.cacheManager.setAssessmentLineItem(lineItemId, actualLineItemId);
33213
- }
33214
- return actualLineItemId;
33215
- }
33216
- async resolveAttemptNumber(providedAttemptNumber, score, studentId, lineItemId) {
33822
+ async resolveAttemptNumber(providedAttemptNumber, studentId, caliperLineItemId, legacyLineItemId) {
33217
33823
  if (providedAttemptNumber) {
33824
+ setAttributes({ "app.timeback.attempt_source": "provided" });
33218
33825
  return providedAttemptNumber;
33219
33826
  }
33220
- if (score !== undefined) {
33221
- return this.determineAttemptNumber(studentId, lineItemId);
33222
- }
33223
- return 1;
33224
- }
33225
- async getOrCreateLineItem(lineItemId, activityName, classId, ids) {
33226
- try {
33227
- const lineItem = await this.onerosterNamespace.assessmentLineItems.findOrCreate(lineItemId, {
33228
- sourcedId: lineItemId,
33229
- title: activityName,
33230
- status: ONEROSTER_STATUS.active,
33231
- ...classId ? { class: { sourcedId: classId } } : { course: { sourcedId: ids.course } }
33827
+ const caliperAttempt = await this.getLatestActivityAttempt(studentId, caliperLineItemId, "attempt");
33828
+ if (caliperAttempt !== null) {
33829
+ const next = caliperAttempt + 1;
33830
+ setAttributes({
33831
+ "app.timeback.attempt_source": caliperAttempt > 0 ? "caliper" : "caliper_unreadable"
33232
33832
  });
33233
- if (!lineItem.sourcedId) {
33234
- throw new TimebackError(`Assessment line item created but has no sourcedId. ` + `This should not happen and indicates an upstream API issue.`);
33235
- }
33236
- return lineItem.sourcedId;
33237
- } catch (error) {
33238
- if (error instanceof TimebackApiError && error.status === 404) {
33239
- const errorDetails = error.details;
33240
- const description = errorDetails?.imsx_description || error.message;
33241
- 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")) {
33242
- throw new ResourceNotFoundError("TimeBack resources", "setup-not-run");
33243
- }
33833
+ if (caliperAttempt === 0) {
33834
+ setAttributes({
33835
+ "app.timeback.attempt_regressed": true,
33836
+ "app.timeback.attempt_emitted": next
33837
+ });
33244
33838
  }
33245
- throw error;
33839
+ return next;
33246
33840
  }
33247
- }
33248
- async determineAttemptNumber(studentId, lineItemId) {
33249
- const stats = await this.onerosterNamespace.assessmentResults.getAttemptStats(studentId, lineItemId);
33250
- if (stats) {
33251
- return stats.activeAttemptCount + 1;
33841
+ const legacyAttempt = await this.getLatestActivityAttempt(studentId, legacyLineItemId, "attemptNumber");
33842
+ if (legacyAttempt !== null) {
33843
+ setAttributes({
33844
+ "app.timeback.attempt_source": "legacy_seed",
33845
+ "app.timeback.legacy_seed_attempt": legacyAttempt
33846
+ });
33847
+ return legacyAttempt + 1;
33252
33848
  }
33849
+ setAttributes({ "app.timeback.attempt_source": "first" });
33253
33850
  return 1;
33254
33851
  }
33255
- async createGradebookEntry({
33256
- lineItemId,
33257
- studentId,
33258
- attemptNumber,
33259
- score,
33260
- xp,
33261
- scoreStatus,
33262
- inProgress,
33263
- appName,
33264
- totalQuestions,
33265
- correctQuestions,
33266
- masteredUnits,
33267
- pctCompleteApp
33268
- }) {
33269
- const timestamp3 = Date.now().toString(36);
33270
- const resultId = `${lineItemId}:${studentId}:${timestamp3}`;
33271
- await this.onerosterNamespace.assessmentResults.upsert(resultId, {
33272
- sourcedId: resultId,
33273
- status: ONEROSTER_STATUS.active,
33274
- assessmentLineItem: { sourcedId: lineItemId },
33275
- student: { sourcedId: studentId },
33276
- score,
33277
- scoreDate: new Date().toISOString(),
33278
- scoreStatus,
33279
- inProgress,
33280
- metadata: {
33281
- xp,
33282
- attemptNumber,
33283
- appName,
33284
- ...totalQuestions !== undefined ? { totalQuestions } : {},
33285
- ...correctQuestions !== undefined ? { correctQuestions } : {},
33286
- ...masteredUnits !== undefined ? { masteredUnits } : {},
33287
- ...pctCompleteApp !== undefined ? { pctCompleteApp } : {}
33288
- }
33852
+ async getLatestActivityAttempt(studentId, lineItemId, metadataField) {
33853
+ const results = await this.onerosterNamespace.assessmentResults.listOrThrow({
33854
+ filter: `student.sourcedId='${escapeFilterValue(studentId)}' AND assessmentLineItem.sourcedId='${escapeFilterValue(lineItemId)}' AND status='active'`,
33855
+ sort: "dateLastModified",
33856
+ orderBy: "desc",
33857
+ limit: 1
33289
33858
  });
33859
+ const latest = results[0];
33860
+ if (!latest) {
33861
+ return null;
33862
+ }
33863
+ return latest.metadata?.[metadataField] || 0;
33290
33864
  }
33291
33865
  async emitCaliperEvent({
33292
33866
  studentId,
@@ -33301,6 +33875,7 @@ class ProgressRecorder {
33301
33875
  xpEarned,
33302
33876
  masteredUnits,
33303
33877
  attemptNumber,
33878
+ objectId,
33304
33879
  progressData,
33305
33880
  extensions,
33306
33881
  runId
@@ -33318,12 +33893,18 @@ class ProgressRecorder {
33318
33893
  xpEarned,
33319
33894
  masteredUnits,
33320
33895
  attemptNumber,
33896
+ objectId,
33897
+ process: true,
33321
33898
  subject: progressData.subject,
33322
33899
  appName: progressData.appName,
33323
33900
  sensorUrl: progressData.sensorUrl,
33324
33901
  extensions: extensions || progressData.extensions,
33325
33902
  ...runId ? { runId } : {}
33326
- }).catch(catchEvent("timeback.caliper_event_failed"));
33903
+ }).catch((error) => {
33904
+ setAttributes({ "app.timeback.caliper_emit_failed": true });
33905
+ catchEvent("timeback.caliper_event_failed")(error);
33906
+ throw error;
33907
+ });
33327
33908
  }
33328
33909
  async emitCourseCompletionHistoryEvent(data) {
33329
33910
  await this.caliperNamespace.emitActivityEvent({
@@ -33501,15 +34082,15 @@ class TimebackClient {
33501
34082
  masteryTracker;
33502
34083
  constructor(config2) {
33503
34084
  this.baseUrl = TimebackClient.resolveBaseUrl(config2?.baseUrl);
33504
- this.environment = process.env[ENV_VARS.environment] === "staging" ? "staging" : "production";
34085
+ this.environment = process.env[ENV_VARS2.environment] === "staging" ? "staging" : "production";
33505
34086
  this.caliperUrl = TimebackClient.resolveCaliperUrl(config2?.caliperUrl, this.environment);
33506
34087
  this.authUrl = config2?.credentials?.authUrl;
33507
34088
  this.credentials = config2?.credentials;
33508
34089
  this.qtiCredentials = config2?.qtiCredentials;
33509
34090
  this.options = {
33510
- retries: config2?.options?.retries ?? HTTP_DEFAULTS.retries,
33511
- cacheDuration: config2?.options?.cacheDuration ?? AUTH_DEFAULTS.tokenCacheDuration,
33512
- timeout: config2?.options?.timeout ?? HTTP_DEFAULTS.timeout,
34091
+ retries: config2?.options?.retries ?? HTTP_DEFAULTS2.retries,
34092
+ cacheDuration: config2?.options?.cacheDuration ?? AUTH_DEFAULTS2.tokenCacheDuration,
34093
+ timeout: config2?.options?.timeout ?? HTTP_DEFAULTS2.timeout,
33513
34094
  sensorUrl: config2?.options?.sensorUrl
33514
34095
  };
33515
34096
  this.oneroster = createOneRosterNamespace(this);
@@ -33519,7 +34100,7 @@ class TimebackClient {
33519
34100
  this.cacheManager = new TimebackCacheManager;
33520
34101
  this.studentResolver = new StudentResolver(this.cacheManager, this.oneroster);
33521
34102
  this.masteryTracker = new MasteryTracker(this.cacheManager, this.oneroster, this.edubridge);
33522
- this.progressRecorder = new ProgressRecorder(this.studentResolver, this.cacheManager, this.oneroster, this.caliper, this.masteryTracker);
34103
+ this.progressRecorder = new ProgressRecorder(this.studentResolver, this.oneroster, this.caliper, this.masteryTracker);
33523
34104
  this.sessionRecorder = new SessionRecorder(this.studentResolver, this.caliper);
33524
34105
  this.adminEventRecorder = new AdminEventRecorder(this.studentResolver, this.oneroster, this.caliper, this.environment);
33525
34106
  if (this.credentials) {
@@ -33528,16 +34109,16 @@ class TimebackClient {
33528
34109
  }
33529
34110
  static async init(config2) {
33530
34111
  let credentials = config2?.credentials;
33531
- if (!credentials && process.env[ENV_VARS.clientId] && process.env[ENV_VARS.clientSecret]) {
34112
+ if (!credentials && process.env[ENV_VARS2.clientId] && process.env[ENV_VARS2.clientSecret]) {
33532
34113
  credentials = {
33533
- clientId: process.env[ENV_VARS.clientId],
33534
- clientSecret: process.env[ENV_VARS.clientSecret]
34114
+ clientId: process.env[ENV_VARS2.clientId],
34115
+ clientSecret: process.env[ENV_VARS2.clientSecret]
33535
34116
  };
33536
34117
  }
33537
- const qtiCredentials = config2?.qtiCredentials ?? (process.env[ENV_VARS.qtiClientId] && process.env[ENV_VARS.qtiClientSecret] && process.env[ENV_VARS.qtiAuthUrl] ? {
33538
- clientId: process.env[ENV_VARS.qtiClientId],
33539
- clientSecret: process.env[ENV_VARS.qtiClientSecret],
33540
- authUrl: process.env[ENV_VARS.qtiAuthUrl]
34118
+ const qtiCredentials = config2?.qtiCredentials ?? (process.env[ENV_VARS2.qtiClientId] && process.env[ENV_VARS2.qtiClientSecret] && process.env[ENV_VARS2.qtiAuthUrl] ? {
34119
+ clientId: process.env[ENV_VARS2.qtiClientId],
34120
+ clientSecret: process.env[ENV_VARS2.qtiClientSecret],
34121
+ authUrl: process.env[ENV_VARS2.qtiAuthUrl]
33541
34122
  } : undefined);
33542
34123
  return new TimebackClient({
33543
34124
  ...config2,
@@ -33550,15 +34131,15 @@ class TimebackClient {
33550
34131
  if (explicit) {
33551
34132
  return explicit;
33552
34133
  }
33553
- const envName = process.env[ENV_VARS.environment] === "staging" ? "staging" : "production";
33554
- return TIMEBACK_API_URLS[envName];
34134
+ const envName = process.env[ENV_VARS2.environment] === "staging" ? "staging" : "production";
34135
+ return TIMEBACK_API_URLS2[envName];
33555
34136
  }
33556
34137
  static resolveCaliperUrl(input, environment = "production") {
33557
34138
  const explicit = (input || "").trim();
33558
34139
  if (explicit) {
33559
34140
  return explicit;
33560
34141
  }
33561
- return CALIPER_API_URLS[environment];
34142
+ return CALIPER_API_URLS2[environment];
33562
34143
  }
33563
34144
  getBaseUrl() {
33564
34145
  return this.baseUrl;
@@ -33679,14 +34260,14 @@ class TimebackClient {
33679
34260
  await this._ensureAuthenticated();
33680
34261
  return this.token;
33681
34262
  }
33682
- throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl}.`);
34263
+ throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl}.`);
33683
34264
  }
33684
34265
  async ensureQtiAuthenticated() {
33685
34266
  if (this.isQtiAuthenticated()) {
33686
34267
  return;
33687
34268
  }
33688
34269
  if (!this.qtiCredentials) {
33689
- throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl}.`);
34270
+ throw new TimebackAuthenticationError(`QTI credentials are required. Set ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl}.`);
33690
34271
  }
33691
34272
  try {
33692
34273
  const tokenData = await getTimebackTokenResponse({
@@ -33698,11 +34279,11 @@ class TimebackClient {
33698
34279
  this.setQtiToken(tokenData.access_token, tokenData.expires_in);
33699
34280
  } catch (error) {
33700
34281
  const errMsg = errorMessage(error);
33701
- throw new TimebackAuthenticationError(`QTI authentication failed: ${errMsg}. ` + `Verify that ${ENV_VARS.qtiClientId}, ${ENV_VARS.qtiClientSecret}, and ${ENV_VARS.qtiAuthUrl} are correct.`);
34282
+ throw new TimebackAuthenticationError(`QTI authentication failed: ${errMsg}. ` + `Verify that ${ENV_VARS2.qtiClientId}, ${ENV_VARS2.qtiClientSecret}, and ${ENV_VARS2.qtiAuthUrl} are correct.`);
33702
34283
  }
33703
34284
  }
33704
34285
  canUseCoreCredentialsForQti() {
33705
- return this.baseUrl.replace(/\/$/, "") === TIMEBACK_API_URLS.production;
34286
+ return this.baseUrl.replace(/\/$/, "") === TIMEBACK_API_URLS2.production;
33706
34287
  }
33707
34288
  async resolveStudent(studentIdentifier, providedEmail) {
33708
34289
  return this.studentResolver.resolve(studentIdentifier, providedEmail);
@@ -33723,8 +34304,8 @@ class TimebackClient {
33723
34304
  await this._ensureAuthenticated();
33724
34305
  const edubridgeEnrollments = await this.edubridge.enrollments.listByUser(studentId);
33725
34306
  const enrollments = edubridgeEnrollments.map((enrollment) => {
33726
- const grades = enrollment.course.grades ? enrollment.course.grades.map((g) => parseInt(g, 10)).filter(isTimebackGrade2) : null;
33727
- const subjects = enrollment.course.subjects ? enrollment.course.subjects.filter(isTimebackSubject2) : null;
34307
+ const grades = enrollment.course.grades ? enrollment.course.grades.map((g) => parseInt(g, 10)).filter(isTimebackGrade3) : null;
34308
+ const subjects = enrollment.course.subjects ? enrollment.course.subjects.filter(isTimebackSubject3) : null;
33728
34309
  return {
33729
34310
  sourcedId: enrollment.id,
33730
34311
  title: enrollment.course.title,
@@ -33790,9 +34371,9 @@ class TimebackClient {
33790
34371
  if (options?.include?.perCourse) {
33791
34372
  const gradeStr = enrollment.course.grades?.[0];
33792
34373
  const parsedGrade = gradeStr ? parseInt(gradeStr, 10) : 0;
33793
- const grade = isTimebackGrade2(parsedGrade) ? parsedGrade : 0;
34374
+ const grade = isTimebackGrade3(parsedGrade) ? parsedGrade : 0;
33794
34375
  const subjectStr = enrollment.course.subjects?.[0];
33795
- const subject = subjectStr && isTimebackSubject2(subjectStr) ? subjectStr : "None";
34376
+ const subject = subjectStr && isTimebackSubject3(subjectStr) ? subjectStr : "None";
33796
34377
  courses.push({
33797
34378
  grade,
33798
34379
  subject,
@@ -33866,9 +34447,9 @@ class TimebackClient {
33866
34447
  if (options?.include?.perCourse) {
33867
34448
  const gradeStr = enrollment.course.grades?.[0];
33868
34449
  const parsedGrade = gradeStr ? parseInt(gradeStr, 10) : 0;
33869
- const grade = isTimebackGrade2(parsedGrade) ? parsedGrade : 0;
34450
+ const grade = isTimebackGrade3(parsedGrade) ? parsedGrade : 0;
33870
34451
  const subjectStr = enrollment.course.subjects?.[0];
33871
- const subject = subjectStr && isTimebackSubject2(subjectStr) ? subjectStr : "None";
34452
+ const subject = subjectStr && isTimebackSubject3(subjectStr) ? subjectStr : "None";
33872
34453
  courses.push({
33873
34454
  grade,
33874
34455
  subject,
@@ -33924,6 +34505,12 @@ class TimebackClient {
33924
34505
  async cleanup(courseId) {
33925
34506
  return deleteTimebackResources(this, courseId);
33926
34507
  }
34508
+ async deactivateCourse(courseId) {
34509
+ return updateTimebackCourseStatus(this, courseId, "tobedeleted");
34510
+ }
34511
+ async reactivateCourse(courseId) {
34512
+ return updateTimebackCourseStatus(this, courseId, "active");
34513
+ }
33927
34514
  }
33928
34515
  var __defProp2, __export2 = (target, all) => {
33929
34516
  for (var name3 in all)
@@ -33933,7 +34520,7 @@ var __defProp2, __export2 = (target, all) => {
33933
34520
  configurable: true,
33934
34521
  set: (newValue) => all[name3] = () => newValue
33935
34522
  });
33936
- }, __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;
34523
+ }, __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;
33937
34524
  var init_dist2 = __esm(() => {
33938
34525
  init_src();
33939
34526
  init_src();
@@ -33959,293 +34546,7 @@ var init_dist2 = __esm(() => {
33959
34546
  init_spans();
33960
34547
  init_esm();
33961
34548
  __defProp2 = Object.defineProperty;
33962
- init_constants4 = __esm2(() => {
33963
- TIMEBACK_API_URLS = {
33964
- production: "https://api.alpha-1edtech.ai",
33965
- staging: "https://api.staging.alpha-1edtech.com"
33966
- };
33967
- TIMEBACK_AUTH_URLS = {
33968
- production: "https://prod-beyond-timeback-api-2-idp.auth.us-east-1.amazoncognito.com",
33969
- staging: "https://alpha-auth-development-idp.auth.us-west-2.amazoncognito.com"
33970
- };
33971
- CALIPER_API_URLS = {
33972
- production: "https://caliper.alpha-1edtech.ai",
33973
- staging: "https://caliper-staging.alpha-1edtech.com"
33974
- };
33975
- ONEROSTER_ENDPOINTS = {
33976
- organizations: "/ims/oneroster/rostering/v1p2/orgs",
33977
- courses: "/ims/oneroster/rostering/v1p2/courses",
33978
- courseComponents: "/ims/oneroster/rostering/v1p2/courses/components",
33979
- resources: "/ims/oneroster/resources/v1p2/resources",
33980
- componentResources: "/ims/oneroster/rostering/v1p2/courses/component-resources",
33981
- classes: "/ims/oneroster/rostering/v1p2/classes",
33982
- enrollments: "/ims/oneroster/rostering/v1p2/enrollments",
33983
- assessmentLineItems: "/ims/oneroster/gradebook/v1p2/assessmentLineItems",
33984
- assessmentResults: "/ims/oneroster/gradebook/v1p2/assessmentResults",
33985
- users: "/ims/oneroster/rostering/v1p2/users"
33986
- };
33987
- QTI_ENDPOINTS = {
33988
- assessmentTests: "/assessment-tests",
33989
- assessmentItems: "/assessment-items"
33990
- };
33991
- CALIPER_ENDPOINTS = {
33992
- event: "/caliper/event",
33993
- events: "/caliper/events",
33994
- validate: "/caliper/event/validate"
33995
- };
33996
- CALIPER_CONSTANTS = {
33997
- context: "http://purl.imsglobal.org/ctx/caliper/v1p2",
33998
- profile: "TimebackProfile",
33999
- dataVersion: "http://purl.imsglobal.org/ctx/caliper/v1p2"
34000
- };
34001
- TIMEBACK_EVENT_TYPES = {
34002
- activityEvent: "ActivityEvent",
34003
- timeSpentEvent: "TimeSpentEvent"
34004
- };
34005
- TIMEBACK_ACTIONS = {
34006
- completed: "Completed",
34007
- spentTime: "SpentTime"
34008
- };
34009
- TIMEBACK_TYPES = {
34010
- user: "TimebackUser",
34011
- activityContext: "TimebackActivityContext",
34012
- activityMetricsCollection: "TimebackActivityMetricsCollection",
34013
- timeSpentMetricsCollection: "TimebackTimeSpentMetricsCollection"
34014
- };
34015
- ACTIVITY_METRIC_TYPES = {
34016
- totalQuestions: "totalQuestions",
34017
- correctQuestions: "correctQuestions",
34018
- xpEarned: "xpEarned",
34019
- masteredUnits: "masteredUnits"
34020
- };
34021
- TIME_METRIC_TYPES = {
34022
- active: "active",
34023
- inactive: "inactive",
34024
- waste: "waste",
34025
- unknown: "unknown",
34026
- antiPattern: "anti-pattern"
34027
- };
34028
- TIMEBACK_SUBJECTS2 = [
34029
- "Math",
34030
- "FastMath",
34031
- "Science",
34032
- "Social Studies",
34033
- "Language",
34034
- "Reading",
34035
- "Vocabulary",
34036
- "Writing"
34037
- ];
34038
- TIMEBACK_GRADE_LEVELS = [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
34039
- TIMEBACK_GRADE_LEVEL_LABELS = {
34040
- "-1": "pre-k",
34041
- "0": "kindergarten",
34042
- "1": "1st grade",
34043
- "2": "2nd grade",
34044
- "3": "3rd grade",
34045
- "4": "4th grade",
34046
- "5": "5th grade",
34047
- "6": "6th grade",
34048
- "7": "7th grade",
34049
- "8": "8th grade",
34050
- "9": "9th grade",
34051
- "10": "10th grade",
34052
- "11": "11th grade",
34053
- "12": "12th grade",
34054
- "13": "AP"
34055
- };
34056
- CALIPER_SUBJECTS = {
34057
- Reading: "Reading",
34058
- Language: "Language",
34059
- Vocabulary: "Vocabulary",
34060
- SocialStudies: "Social Studies",
34061
- Writing: "Writing",
34062
- Science: "Science",
34063
- FastMath: "FastMath",
34064
- Math: "Math",
34065
- None: "None"
34066
- };
34067
- ONEROSTER_STATUS = {
34068
- active: "active",
34069
- toBeDeleted: "tobedeleted"
34070
- };
34071
- SCORE_STATUS = {
34072
- exempt: "exempt",
34073
- fullyGraded: "fully graded",
34074
- notSubmitted: "not submitted",
34075
- partiallyGraded: "partially graded",
34076
- submitted: "submitted"
34077
- };
34078
- ENV_VARS = {
34079
- clientId: "TIMEBACK_CLIENT_ID",
34080
- clientSecret: "TIMEBACK_CLIENT_SECRET",
34081
- baseUrl: "TIMEBACK_BASE_URL",
34082
- environment: "TIMEBACK_ENVIRONMENT",
34083
- vendorResourceId: "TIMEBACK_VENDOR_RESOURCE_ID",
34084
- launchBaseUrl: "GAME_URL",
34085
- qtiClientId: "QTI_CLIENT_ID",
34086
- qtiClientSecret: "QTI_CLIENT_SECRET",
34087
- qtiAuthUrl: "QTI_AUTH_URL"
34088
- };
34089
- HTTP_DEFAULTS = {
34090
- timeout: 30000,
34091
- retries: 3,
34092
- retryBackoffBase: 2
34093
- };
34094
- AUTH_DEFAULTS = {
34095
- tokenCacheDuration: 50000
34096
- };
34097
- CACHE_DEFAULTS = {
34098
- defaultTTL: 10 * 60 * 1000,
34099
- defaultMaxSize: 500,
34100
- defaultName: "TimebackCache",
34101
- studentTTL: 10 * 60 * 1000,
34102
- studentMaxSize: 500,
34103
- assessmentTTL: 30 * 60 * 1000,
34104
- assessmentMaxSize: 200,
34105
- enrollmentTTL: 5 * 1000,
34106
- enrollmentMaxSize: 100
34107
- };
34108
- CONFIG_DEFAULTS = {
34109
- fileNames: ["timeback.config.js", "timeback.config.json"]
34110
- };
34111
- PLAYCADEMY_DEFAULTS = {
34112
- organization: TIMEBACK_ORG_SOURCED_ID,
34113
- launchBaseUrls: PLAYCADEMY_BASE_URLS
34114
- };
34115
- RESOURCE_DEFAULTS = {
34116
- organization: {
34117
- name: TIMEBACK_ORG_NAME,
34118
- type: TIMEBACK_ORG_TYPE
34119
- },
34120
- course: {
34121
- gradingScheme: TIMEBACK_COURSE_DEFAULTS.gradingScheme,
34122
- level: TIMEBACK_COURSE_DEFAULTS.level,
34123
- metadata: {
34124
- goals: TIMEBACK_COURSE_DEFAULTS.goals,
34125
- metrics: TIMEBACK_COURSE_DEFAULTS.metrics
34126
- }
34127
- },
34128
- component: TIMEBACK_COMPONENT_DEFAULTS,
34129
- resource: TIMEBACK_RESOURCE_DEFAULTS,
34130
- componentResource: TIMEBACK_COMPONENT_RESOURCE_DEFAULTS
34131
- };
34132
- HTTP_STATUS = {
34133
- CLIENT_ERROR_MIN: 400,
34134
- CLIENT_ERROR_MAX: 500,
34135
- SERVER_ERROR_MIN: 500
34136
- };
34137
- ERROR_NAMES = {
34138
- timebackAuth: "TimebackAuthError",
34139
- timebackApi: "TimebackApiError",
34140
- timebackConfig: "TimebackConfigError",
34141
- timebackSdk: "TimebackSDKError"
34142
- };
34143
- });
34144
- exports_verify = {};
34145
- __export2(exports_verify, {
34146
- verifyTimebackResources: () => verifyTimebackResources,
34147
- fetchTimebackConfig: () => fetchTimebackConfig
34148
- });
34149
- init_verify = __esm2(() => {
34150
- init_constants4();
34151
- });
34152
- init_constants4();
34153
- TimebackError = class TimebackError extends Error {
34154
- constructor(message) {
34155
- super(message);
34156
- this.name = ERROR_NAMES.timebackSdk;
34157
- }
34158
- };
34159
- TimebackApiError = class TimebackApiError extends Error {
34160
- status;
34161
- details;
34162
- constructor(status, message, details) {
34163
- super(`${status} ${message}`);
34164
- this.name = ERROR_NAMES.timebackApi;
34165
- this.status = status;
34166
- this.details = details;
34167
- Object.setPrototypeOf(this, TimebackApiError.prototype);
34168
- }
34169
- };
34170
- TimebackAuthenticationError = class TimebackAuthenticationError extends TimebackError {
34171
- constructor(message) {
34172
- super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
34173
- this.name = "TimebackAuthenticationError";
34174
- Object.setPrototypeOf(this, TimebackAuthenticationError.prototype);
34175
- }
34176
- };
34177
- StudentNotFoundError = class StudentNotFoundError extends TimebackError {
34178
- identifier;
34179
- identifierType;
34180
- constructor(identifier, identifierType = "email") {
34181
- 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.`);
34182
- this.name = "StudentNotFoundError";
34183
- this.identifier = identifier;
34184
- this.identifierType = identifierType;
34185
- Object.setPrototypeOf(this, StudentNotFoundError.prototype);
34186
- }
34187
- };
34188
- ConfigurationError = class ConfigurationError extends TimebackError {
34189
- field;
34190
- constructor(field, message) {
34191
- super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
34192
- this.name = "ConfigurationError";
34193
- this.field = field;
34194
- Object.setPrototypeOf(this, ConfigurationError.prototype);
34195
- }
34196
- };
34197
- ResourceNotFoundError = class ResourceNotFoundError extends TimebackError {
34198
- resourceType;
34199
- sourcedId;
34200
- constructor(resourceType, sourcedId) {
34201
- 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`;
34202
- super(message);
34203
- this.name = "ResourceNotFoundError";
34204
- this.resourceType = resourceType;
34205
- this.sourcedId = sourcedId;
34206
- Object.setPrototypeOf(this, ResourceNotFoundError.prototype);
34207
- }
34208
- };
34209
- init_constants4();
34210
- SUBJECT_VALUES = TIMEBACK_SUBJECTS2;
34211
- GRADE_VALUES = TIMEBACK_GRADE_LEVELS;
34212
- init_verify();
34213
- init_constants4();
34214
- init_constants4();
34215
- if (process.env.DEBUG === "true") {
34216
- process.env.TERM = "dumb";
34217
- }
34218
- TimebackAuthError = class TimebackAuthError extends Error {
34219
- statusCode;
34220
- constructor(message, statusCode) {
34221
- super(message);
34222
- this.name = ERROR_NAMES.timebackAuth;
34223
- this.statusCode = statusCode;
34224
- }
34225
- };
34226
- init_constants4();
34227
- UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
34228
- storage = new AsyncLocalStorage;
34229
- init_constants4();
34230
- init_constants4();
34231
- init_constants4();
34232
- init_constants4();
34233
- init_constants4();
34234
- init_constants4();
34235
- init_constants4();
34236
- init_constants4();
34237
- EmailSchema = exports_external.string().email();
34238
- StudentSourcedIdSchema = exports_external.string().min(1, {
34239
- message: "Student sourcedId must be a non-empty string"
34240
- });
34241
- StudentIdentifierSchema = exports_external.union([EmailSchema, StudentSourcedIdSchema]);
34242
- });
34243
-
34244
- // ../timeback/dist/constants.js
34245
- 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;
34246
- var init_constants5 = __esm(() => {
34247
- init_src();
34248
- init_constants6 = __esm3(() => {
34549
+ init_constants5 = __esm3(() => {
34249
34550
  TIMEBACK_API_URLS2 = {
34250
34551
  production: "https://api.alpha-1edtech.ai",
34251
34552
  staging: "https://api.staging.alpha-1edtech.com"
@@ -34427,36 +34728,153 @@ var init_constants5 = __esm(() => {
34427
34728
  timebackSdk: "TimebackSDKError"
34428
34729
  };
34429
34730
  });
34430
- init_constants6();
34731
+ init_errors4 = __esm3(() => {
34732
+ init_constants5();
34733
+ TimebackError = class TimebackError2 extends Error {
34734
+ constructor(message) {
34735
+ super(message);
34736
+ this.name = ERROR_NAMES2.timebackSdk;
34737
+ }
34738
+ };
34739
+ TimebackApiError = class TimebackApiError2 extends Error {
34740
+ status;
34741
+ details;
34742
+ constructor(status, message, details) {
34743
+ super(`${status} ${message}`);
34744
+ this.name = ERROR_NAMES2.timebackApi;
34745
+ this.status = status;
34746
+ this.details = details;
34747
+ Object.setPrototypeOf(this, TimebackApiError2.prototype);
34748
+ }
34749
+ };
34750
+ TimebackAuthenticationError = class TimebackAuthenticationError2 extends TimebackError {
34751
+ constructor(message) {
34752
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
34753
+ this.name = "TimebackAuthenticationError";
34754
+ Object.setPrototypeOf(this, TimebackAuthenticationError2.prototype);
34755
+ }
34756
+ };
34757
+ StudentNotFoundError = class StudentNotFoundError2 extends TimebackError {
34758
+ identifier;
34759
+ identifierType;
34760
+ constructor(identifier, identifierType = "email") {
34761
+ 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.`);
34762
+ this.name = "StudentNotFoundError";
34763
+ this.identifier = identifier;
34764
+ this.identifierType = identifierType;
34765
+ Object.setPrototypeOf(this, StudentNotFoundError2.prototype);
34766
+ }
34767
+ };
34768
+ ConfigurationError = class ConfigurationError2 extends TimebackError {
34769
+ field;
34770
+ constructor(field, message) {
34771
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
34772
+ this.name = "ConfigurationError";
34773
+ this.field = field;
34774
+ Object.setPrototypeOf(this, ConfigurationError2.prototype);
34775
+ }
34776
+ };
34777
+ ResourceAlreadyExistsError = class ResourceAlreadyExistsError2 extends TimebackError {
34778
+ resourceType;
34779
+ sourcedId;
34780
+ originalError;
34781
+ constructor(resourceType, sourcedId, originalError) {
34782
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
34783
+ this.name = "ResourceAlreadyExistsError";
34784
+ this.resourceType = resourceType;
34785
+ this.sourcedId = sourcedId;
34786
+ this.originalError = originalError;
34787
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError2.prototype);
34788
+ }
34789
+ };
34790
+ ResourceNotFoundError = class ResourceNotFoundError2 extends TimebackError {
34791
+ resourceType;
34792
+ sourcedId;
34793
+ constructor(resourceType, sourcedId) {
34794
+ 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`;
34795
+ super(message);
34796
+ this.name = "ResourceNotFoundError";
34797
+ this.resourceType = resourceType;
34798
+ this.sourcedId = sourcedId;
34799
+ Object.setPrototypeOf(this, ResourceNotFoundError2.prototype);
34800
+ }
34801
+ };
34802
+ });
34803
+ init_ids = __esm3(() => {
34804
+ init_errors4();
34805
+ 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;
34806
+ });
34807
+ exports_verify = {};
34808
+ __export2(exports_verify, {
34809
+ verifyTimebackResources: () => verifyTimebackResources,
34810
+ fetchTimebackConfig: () => fetchTimebackConfig
34811
+ });
34812
+ init_verify = __esm3(() => {
34813
+ init_constants5();
34814
+ init_ids();
34815
+ });
34816
+ init_constants5();
34817
+ SUBJECT_VALUES2 = TIMEBACK_SUBJECTS3;
34818
+ GRADE_VALUES2 = TIMEBACK_GRADE_LEVELS2;
34819
+ init_ids();
34820
+ init_ids();
34821
+ init_verify();
34822
+ init_ids();
34823
+ init_constants5();
34824
+ init_errors4();
34825
+ init_constants5();
34826
+ if (process.env.DEBUG === "true") {
34827
+ process.env.TERM = "dumb";
34828
+ }
34829
+ TimebackAuthError = class TimebackAuthError extends Error {
34830
+ statusCode;
34831
+ constructor(message, statusCode) {
34832
+ super(message);
34833
+ this.name = ERROR_NAMES2.timebackAuth;
34834
+ this.statusCode = statusCode;
34835
+ }
34836
+ };
34837
+ init_ids();
34838
+ init_constants5();
34839
+ init_errors4();
34840
+ UUID_PATTERN = /[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi;
34841
+ storage = new AsyncLocalStorage;
34842
+ init_constants5();
34843
+ init_constants5();
34844
+ init_errors4();
34845
+ init_constants5();
34846
+ init_constants5();
34847
+ init_constants5();
34848
+ init_constants5();
34849
+ init_constants5();
34850
+ init_ids();
34851
+ init_ids();
34852
+ init_errors4();
34853
+ init_ids();
34854
+ init_errors4();
34855
+ EmailSchema = exports_external.string().email();
34856
+ StudentSourcedIdSchema = exports_external.string().min(1, {
34857
+ message: "Student sourcedId must be a non-empty string"
34858
+ });
34859
+ StudentIdentifierSchema = exports_external.union([EmailSchema, StudentSourcedIdSchema]);
34860
+ init_ids();
34431
34861
  });
34432
34862
 
34433
- // ../timeback/dist/types.js
34434
- function isObject2(value) {
34435
- return typeof value === "object" && value !== null;
34436
- }
34437
- function isCourseMetadata(value) {
34438
- return isObject2(value);
34439
- }
34440
- function isResourceMetadata(value) {
34441
- return isObject2(value);
34442
- }
34443
- function isPlaycademyResourceMetadata2(value) {
34444
- if (!isObject2(value)) {
34445
- return false;
34863
+ // ../timeback/dist/constants.js
34864
+ function deriveTimebackCourseLevelFromGrade(grade) {
34865
+ if (grade === 13) {
34866
+ return TIMEBACK_COURSE_DEFAULTS.level.ap;
34446
34867
  }
34447
- if (!("mastery" in value) || value.mastery === undefined) {
34448
- return true;
34868
+ if (grade <= 5) {
34869
+ return TIMEBACK_COURSE_DEFAULTS.level.elementary;
34449
34870
  }
34450
- return isObject2(value.mastery);
34451
- }
34452
- function isTimebackSubject3(value) {
34453
- return typeof value === "string" && SUBJECT_VALUES2.includes(value);
34454
- }
34455
- function isTimebackGrade3(value) {
34456
- return typeof value === "number" && Number.isInteger(value) && GRADE_VALUES2.includes(value);
34871
+ if (grade <= 8) {
34872
+ return TIMEBACK_COURSE_DEFAULTS.level.middle;
34873
+ }
34874
+ return TIMEBACK_COURSE_DEFAULTS.level.high;
34457
34875
  }
34458
- 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;
34459
- var init_types3 = __esm(() => {
34876
+ 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;
34877
+ var init_constants6 = __esm(() => {
34460
34878
  init_src();
34461
34879
  init_constants7 = __esm4(() => {
34462
34880
  TIMEBACK_API_URLS3 = {
@@ -34641,8 +35059,6 @@ var init_types3 = __esm(() => {
34641
35059
  };
34642
35060
  });
34643
35061
  init_constants7();
34644
- SUBJECT_VALUES2 = TIMEBACK_SUBJECTS4;
34645
- GRADE_VALUES2 = TIMEBACK_GRADE_LEVELS3;
34646
35062
  });
34647
35063
 
34648
35064
  // ../timeback/dist/utils.js
@@ -34664,7 +35080,7 @@ function deriveAssessmentBankIds(courseId) {
34664
35080
  function escapeFilterValue2(value) {
34665
35081
  return value.replaceAll("'", String.raw`\'`);
34666
35082
  }
34667
- 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;
35083
+ 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;
34668
35084
  var init_utils6 = __esm(() => {
34669
35085
  init_src();
34670
35086
  init_constants8 = __esm5(() => {
@@ -34849,6 +35265,82 @@ var init_utils6 = __esm(() => {
34849
35265
  timebackSdk: "TimebackSDKError"
34850
35266
  };
34851
35267
  });
35268
+ init_errors5 = __esm5(() => {
35269
+ init_constants8();
35270
+ TimebackError2 = class TimebackError3 extends Error {
35271
+ constructor(message) {
35272
+ super(message);
35273
+ this.name = ERROR_NAMES4.timebackSdk;
35274
+ }
35275
+ };
35276
+ TimebackApiError2 = class TimebackApiError3 extends Error {
35277
+ status;
35278
+ details;
35279
+ constructor(status, message, details) {
35280
+ super(`${status} ${message}`);
35281
+ this.name = ERROR_NAMES4.timebackApi;
35282
+ this.status = status;
35283
+ this.details = details;
35284
+ Object.setPrototypeOf(this, TimebackApiError3.prototype);
35285
+ }
35286
+ };
35287
+ TimebackAuthenticationError2 = class TimebackAuthenticationError3 extends TimebackError2 {
35288
+ constructor(message) {
35289
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
35290
+ this.name = "TimebackAuthenticationError";
35291
+ Object.setPrototypeOf(this, TimebackAuthenticationError3.prototype);
35292
+ }
35293
+ };
35294
+ StudentNotFoundError2 = class StudentNotFoundError3 extends TimebackError2 {
35295
+ identifier;
35296
+ identifierType;
35297
+ constructor(identifier, identifierType = "email") {
35298
+ 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.`);
35299
+ this.name = "StudentNotFoundError";
35300
+ this.identifier = identifier;
35301
+ this.identifierType = identifierType;
35302
+ Object.setPrototypeOf(this, StudentNotFoundError3.prototype);
35303
+ }
35304
+ };
35305
+ ConfigurationError2 = class ConfigurationError3 extends TimebackError2 {
35306
+ field;
35307
+ constructor(field, message) {
35308
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
35309
+ this.name = "ConfigurationError";
35310
+ this.field = field;
35311
+ Object.setPrototypeOf(this, ConfigurationError3.prototype);
35312
+ }
35313
+ };
35314
+ ResourceAlreadyExistsError2 = class ResourceAlreadyExistsError3 extends TimebackError2 {
35315
+ resourceType;
35316
+ sourcedId;
35317
+ originalError;
35318
+ constructor(resourceType, sourcedId, originalError) {
35319
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
35320
+ this.name = "ResourceAlreadyExistsError";
35321
+ this.resourceType = resourceType;
35322
+ this.sourcedId = sourcedId;
35323
+ this.originalError = originalError;
35324
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError3.prototype);
35325
+ }
35326
+ };
35327
+ ResourceNotFoundError2 = class ResourceNotFoundError3 extends TimebackError2 {
35328
+ resourceType;
35329
+ sourcedId;
35330
+ constructor(resourceType, sourcedId) {
35331
+ 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`;
35332
+ super(message);
35333
+ this.name = "ResourceNotFoundError";
35334
+ this.resourceType = resourceType;
35335
+ this.sourcedId = sourcedId;
35336
+ Object.setPrototypeOf(this, ResourceNotFoundError3.prototype);
35337
+ }
35338
+ };
35339
+ });
35340
+ init_ids2 = __esm5(() => {
35341
+ init_errors5();
35342
+ 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;
35343
+ });
34852
35344
  init_constants8();
34853
35345
  init_constants8();
34854
35346
  if (process.env.DEBUG === "true") {
@@ -35011,333 +35503,6 @@ var init_timeback_admin_util = __esm(() => {
35011
35503
  init_errors();
35012
35504
  });
35013
35505
 
35014
- // ../api-core/src/utils/timeback.util.ts
35015
- function isRecord2(value) {
35016
- return typeof value === "object" && value !== null;
35017
- }
35018
- function filterEnrollmentsByGame(enrollments, gameId) {
35019
- return enrollments.filter((enrollment) => enrollment.gameId === gameId).map(({ gameId: _, ...enrollment }) => enrollment);
35020
- }
35021
- function mapEnrollmentsToUserEnrollments(enrollments, integrations) {
35022
- const enrollmentByCourse = new Map(enrollments.map((enrollment) => [enrollment.courseId, enrollment]));
35023
- const courseToSchool = new Map(enrollments.filter((enrollment) => enrollment.school?.id).map((enrollment) => [enrollment.courseId, enrollment.school.id]));
35024
- return integrations.map((integration) => {
35025
- const enrollment = enrollmentByCourse.get(integration.courseId);
35026
- return {
35027
- gameId: integration.gameId,
35028
- grade: integration.grade,
35029
- subject: integration.subject,
35030
- courseId: integration.courseId,
35031
- orgId: courseToSchool.get(integration.courseId),
35032
- ...enrollment ? { id: enrollment.sourcedId } : {}
35033
- };
35034
- });
35035
- }
35036
- function getStringValue(value) {
35037
- return typeof value === "string" && value.trim().length > 0 ? value.trim() : undefined;
35038
- }
35039
- function parseSourcedIdFromUrl(url2) {
35040
- if (!url2) {
35041
- return;
35042
- }
35043
- const trimmed = url2.trim().replace(/\/$/, "");
35044
- if (!trimmed) {
35045
- return;
35046
- }
35047
- const segments = trimmed.split("/");
35048
- const lastSegment = segments.at(-1);
35049
- return lastSegment ? decodeURIComponent(lastSegment) : undefined;
35050
- }
35051
- function getGeneratedMetricValue(event, type) {
35052
- const items = event.generated?.items;
35053
- if (!Array.isArray(items)) {
35054
- return;
35055
- }
35056
- const metric = items.find((item) => item?.type === type);
35057
- if (!metric) {
35058
- return;
35059
- }
35060
- const value = typeof metric.value === "number" ? metric.value : Number(metric.value);
35061
- return Number.isFinite(value) ? value : undefined;
35062
- }
35063
- function getMergedCaliperExtensions(event) {
35064
- const objectActivityExtensions = isRecord2(event.object.activity?.extensions) ? event.object.activity.extensions : undefined;
35065
- const generatedExtensions = isRecord2(event.generated?.extensions) ? event.generated.extensions : undefined;
35066
- const eventExtensions = isRecord2(event.extensions) ? event.extensions : undefined;
35067
- return {
35068
- ...objectActivityExtensions,
35069
- ...generatedExtensions,
35070
- ...eventExtensions
35071
- };
35072
- }
35073
- function getPlaycademyMetadata(event) {
35074
- const extensions = getMergedCaliperExtensions(event);
35075
- return isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
35076
- }
35077
- function getActivityId(event, playcademy) {
35078
- const metadataActivityId = getStringValue(playcademy?.activityId);
35079
- if (metadataActivityId) {
35080
- return metadataActivityId;
35081
- }
35082
- const activityId = getStringValue(event.object.activity?.id);
35083
- if (activityId) {
35084
- return activityId;
35085
- }
35086
- const objectId = getStringValue(event.object.id);
35087
- if (!objectId) {
35088
- return;
35089
- }
35090
- const trimmed = objectId.replace(/\/$/, "");
35091
- const segments = trimmed.split("/");
35092
- const activityIndex = segments.lastIndexOf("activities");
35093
- if (activityIndex !== -1 && segments.length >= activityIndex + 3) {
35094
- const candidate = segments[activityIndex + 2];
35095
- return candidate ? decodeURIComponent(candidate) : undefined;
35096
- }
35097
- return;
35098
- }
35099
- function buildResourceMetadata({
35100
- baseMetadata,
35101
- subject,
35102
- grade,
35103
- totalXp,
35104
- masterableUnits
35105
- }) {
35106
- const normalizedBaseMetadata = isResourceMetadata(baseMetadata) ? baseMetadata : undefined;
35107
- const metadata2 = {
35108
- ...normalizedBaseMetadata
35109
- };
35110
- metadata2.subject = subject;
35111
- metadata2.grades = [grade];
35112
- metadata2.xp = totalXp;
35113
- if (masterableUnits !== undefined && masterableUnits !== null) {
35114
- const existingPlaycademy = isPlaycademyResourceMetadata2(metadata2.playcademy) ? metadata2.playcademy : undefined;
35115
- metadata2.playcademy = {
35116
- ...existingPlaycademy,
35117
- mastery: {
35118
- ...existingPlaycademy?.mastery,
35119
- masterableUnits
35120
- }
35121
- };
35122
- }
35123
- return metadata2;
35124
- }
35125
- function getDurationSecondsFromExtensions(event) {
35126
- const extensions = getMergedCaliperExtensions(event);
35127
- const playcademy = isRecord2(extensions.playcademy) ? extensions.playcademy : undefined;
35128
- const rawValue = extensions.durationSeconds ?? playcademy?.durationSeconds;
35129
- const value = typeof rawValue === "number" ? rawValue : Number(rawValue);
35130
- return Number.isFinite(value) ? value : undefined;
35131
- }
35132
- function getCanonicalRunId(session2) {
35133
- const sessionId = getStringValue(session2?.id);
35134
- if (!sessionId) {
35135
- return;
35136
- }
35137
- return sessionId.replace(/^urn:uuid:/, "");
35138
- }
35139
- function getResumeId(event) {
35140
- const playcademy = getPlaycademyMetadata(event);
35141
- return getStringValue(playcademy?.resumeId);
35142
- }
35143
- function isCaliperRemediationOrCompletionEvent(event) {
35144
- const playcademy = getPlaycademyMetadata(event);
35145
- return REMEDIATION_OR_COMPLETION_EVENT_KINDS.has(getStringValue(playcademy?.eventKind) || "");
35146
- }
35147
- function groupCaliperEventsByRun(events) {
35148
- const groups = new Map;
35149
- for (const event of events) {
35150
- const objectId = getStringValue(event.object.id) || "unknown-activity";
35151
- const groupKey = `${objectId}::${getStringValue(event.session?.id) || event.externalId}`;
35152
- const existing = groups.get(groupKey);
35153
- if (existing) {
35154
- existing.push(event);
35155
- } else {
35156
- groups.set(groupKey, [event]);
35157
- }
35158
- }
35159
- return groups;
35160
- }
35161
- function findCaliperEventGroupContainingExternalId(events, externalId) {
35162
- const targetExternalId = externalId.trim();
35163
- if (!targetExternalId) {
35164
- return;
35165
- }
35166
- return [...groupCaliperEventsByRun(events).values()].find((group) => group.some((event) => event.externalId === targetExternalId));
35167
- }
35168
- function mapCaliperEventGroupToActivity(events, relevantCourseIds) {
35169
- if (events.length === 0) {
35170
- return null;
35171
- }
35172
- const sortedEvents = events.toSorted((a, b) => a.eventTime.localeCompare(b.eventTime));
35173
- const activityEvent = [...sortedEvents].toReversed().find((event) => event.type === "ActivityEvent");
35174
- const contextSource = activityEvent || sortedEvents.at(-1);
35175
- if (!contextSource) {
35176
- return null;
35177
- }
35178
- const ctx = parseCaliperEventContext(contextSource, relevantCourseIds);
35179
- if (!ctx) {
35180
- return null;
35181
- }
35182
- const score = activityEvent !== undefined ? (() => {
35183
- const totalQuestions = getGeneratedMetricValue(activityEvent, "totalQuestions");
35184
- const correctQuestions = getGeneratedMetricValue(activityEvent, "correctQuestions");
35185
- if (totalQuestions === undefined || correctQuestions === undefined || totalQuestions <= 0) {
35186
- return;
35187
- }
35188
- return correctQuestions / totalQuestions * 100;
35189
- })() : undefined;
35190
- const xpEarned = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "xpEarned") : undefined;
35191
- const masteredUnits = activityEvent !== undefined ? getGeneratedMetricValue(activityEvent, "masteredUnits") : undefined;
35192
- const timeSpentEvents = sortedEvents.filter((event) => event.type === "TimeSpentEvent");
35193
- let totalActiveTimeSeconds;
35194
- if (timeSpentEvents.length > 0) {
35195
- totalActiveTimeSeconds = timeSpentEvents.reduce((sum, event) => sum + (getGeneratedMetricValue(event, "active") ?? 0), 0);
35196
- } else if (activityEvent !== undefined) {
35197
- totalActiveTimeSeconds = getDurationSecondsFromExtensions(activityEvent);
35198
- }
35199
- const fallbackActivityId = getActivityId(contextSource, getPlaycademyMetadata(contextSource));
35200
- const occurredAt = getStringValue(activityEvent?.eventTime) || getStringValue(sortedEvents.at(-1)?.eventTime);
35201
- const runId = getCanonicalRunId(contextSource.session);
35202
- const resumeIds = new Set(sortedEvents.map((event) => getResumeId(event)).filter((resumeId) => resumeId !== undefined));
35203
- const sessionCount = resumeIds.size > 0 ? resumeIds.size : 1;
35204
- const kind = activityEvent !== undefined ? "activity" : "activity-in-progress";
35205
- if (!occurredAt) {
35206
- return null;
35207
- }
35208
- return {
35209
- id: activityEvent?.externalId || sortedEvents.at(-1)?.externalId || events[0].externalId,
35210
- kind,
35211
- occurredAt,
35212
- courseId: ctx.courseId,
35213
- title: getStringValue(activityEvent?.object.activity?.name) || ctx.titleFromEvent || (fallbackActivityId ? kebabToTitleCase(fallbackActivityId) : "Activity completed"),
35214
- ...ctx.activityId ? { activityId: ctx.activityId } : {},
35215
- ...ctx.appName ? { appName: ctx.appName } : {},
35216
- ...score !== undefined ? { score } : {},
35217
- ...xpEarned !== undefined ? { xpDelta: xpEarned } : {},
35218
- ...masteredUnits !== undefined ? { masteredUnitsDelta: masteredUnits } : {},
35219
- ...totalActiveTimeSeconds !== undefined ? { timeDeltaSeconds: totalActiveTimeSeconds } : {},
35220
- ...runId ? { runId } : {},
35221
- ...sessionCount > 0 ? { sessionCount } : {}
35222
- };
35223
- }
35224
- function parseCaliperEventContext(event, relevantCourseIds) {
35225
- const playcademy = getPlaycademyMetadata(event);
35226
- const courseId = getStringValue(playcademy?.courseId) || parseSourcedIdFromUrl(event.object.course?.id);
35227
- if (!courseId || !relevantCourseIds.has(courseId)) {
35228
- return null;
35229
- }
35230
- const occurredAt = getStringValue(event.eventTime);
35231
- if (!occurredAt) {
35232
- return null;
35233
- }
35234
- return {
35235
- courseId,
35236
- occurredAt,
35237
- eventKind: getStringValue(playcademy?.eventKind),
35238
- source: getStringValue(playcademy?.source),
35239
- reason: getStringValue(playcademy?.reason),
35240
- titleFromEvent: getStringValue(event.object.activity?.name),
35241
- appName: getStringValue(event.object.app?.name),
35242
- activityId: getActivityId(event, playcademy)
35243
- };
35244
- }
35245
- function mapTimeSpentRemediation(event, ctx) {
35246
- if (ctx.eventKind !== "remediation-time") {
35247
- return null;
35248
- }
35249
- return {
35250
- id: event.externalId,
35251
- kind: "remediation-time",
35252
- occurredAt: ctx.occurredAt,
35253
- courseId: ctx.courseId,
35254
- title: "Time Adjustment",
35255
- activityId: ctx.activityId,
35256
- appName: ctx.appName,
35257
- reason: ctx.reason,
35258
- timeDeltaSeconds: getGeneratedMetricValue(event, "active")
35259
- };
35260
- }
35261
- function mapActivityRemediation(event, ctx) {
35262
- if (ctx.eventKind === "remediation-xp") {
35263
- return {
35264
- id: event.externalId,
35265
- kind: "remediation-xp",
35266
- occurredAt: ctx.occurredAt,
35267
- courseId: ctx.courseId,
35268
- title: "XP Adjustment",
35269
- activityId: ctx.activityId,
35270
- appName: ctx.appName,
35271
- reason: ctx.reason,
35272
- xpDelta: getGeneratedMetricValue(event, "xpEarned"),
35273
- masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
35274
- };
35275
- }
35276
- if (ctx.eventKind === "remediation-mastery") {
35277
- return {
35278
- id: event.externalId,
35279
- kind: "remediation-mastery",
35280
- occurredAt: ctx.occurredAt,
35281
- courseId: ctx.courseId,
35282
- title: "Mastery Adjustment",
35283
- activityId: ctx.activityId,
35284
- appName: ctx.appName,
35285
- reason: ctx.reason,
35286
- xpDelta: getGeneratedMetricValue(event, "xpEarned"),
35287
- masteredUnitsDelta: getGeneratedMetricValue(event, "masteredUnits")
35288
- };
35289
- }
35290
- if (ctx.eventKind === "course-completed") {
35291
- return {
35292
- id: event.externalId,
35293
- kind: "course-completed",
35294
- occurredAt: ctx.occurredAt,
35295
- courseId: ctx.courseId,
35296
- title: ctx.source === "admin" ? "Course marked complete" : "Course completed",
35297
- activityId: ctx.activityId,
35298
- appName: ctx.appName,
35299
- reason: ctx.reason
35300
- };
35301
- }
35302
- if (ctx.eventKind === "course-resumed") {
35303
- return {
35304
- id: event.externalId,
35305
- kind: "course-resumed",
35306
- occurredAt: ctx.occurredAt,
35307
- courseId: ctx.courseId,
35308
- title: "Course resumed",
35309
- activityId: ctx.activityId,
35310
- appName: ctx.appName,
35311
- reason: ctx.reason
35312
- };
35313
- }
35314
- return null;
35315
- }
35316
- function mapCaliperEventToRemediationActivity(event, relevantCourseIds) {
35317
- const ctx = parseCaliperEventContext(event, relevantCourseIds);
35318
- if (!ctx) {
35319
- return null;
35320
- }
35321
- if (event.type === "TimeSpentEvent") {
35322
- return mapTimeSpentRemediation(event, ctx);
35323
- }
35324
- if (event.type === "ActivityEvent") {
35325
- return mapActivityRemediation(event, ctx);
35326
- }
35327
- return null;
35328
- }
35329
- var REMEDIATION_OR_COMPLETION_EVENT_KINDS;
35330
- var init_timeback_util = __esm(() => {
35331
- init_types3();
35332
- REMEDIATION_OR_COMPLETION_EVENT_KINDS = new Set([
35333
- "remediation-xp",
35334
- "remediation-time",
35335
- "remediation-mastery",
35336
- "course-completed",
35337
- "course-resumed"
35338
- ]);
35339
- });
35340
-
35341
35506
  // ../api-core/src/utils/timeback-discrepancy-queue.util.ts
35342
35507
  function parseDateInputParts(value) {
35343
35508
  const parts2 = value.split("-");
@@ -35711,7 +35876,7 @@ function isAllowedGradeLevelTestType(value) {
35711
35876
  }
35712
35877
  function isQualifyingGradeLevelTestResult(result, options) {
35713
35878
  const metadata2 = metadataOf(result);
35714
- 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);
35879
+ 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);
35715
35880
  }
35716
35881
  function mapGradeLevelTestSummary(result, options) {
35717
35882
  if (!isQualifyingGradeLevelTestResult(result, options)) {
@@ -35971,7 +36136,7 @@ function latestAssessmentResultsByLineItem(results) {
35971
36136
  const latestResultsByLineItem = new Map;
35972
36137
  for (const result of results) {
35973
36138
  const lineItemId = sourceIdFromRef(result.assessmentLineItem);
35974
- if (lineItemId && !latestResultsByLineItem.has(lineItemId) && result.scoreStatus === SCORE_STATUS2.fullyGraded) {
36139
+ if (lineItemId && !latestResultsByLineItem.has(lineItemId) && result.scoreStatus === SCORE_STATUS3.fullyGraded) {
35975
36140
  latestResultsByLineItem.set(lineItemId, result);
35976
36141
  }
35977
36142
  }
@@ -36071,7 +36236,7 @@ function qtiIdCandidates(parentLineItem, resource) {
36071
36236
  }
36072
36237
  var GRADE_LEVEL_TEST_TYPES, naturalTitleSort;
36073
36238
  var init_timeback_grade_level_results_util = __esm(() => {
36074
- init_constants5();
36239
+ init_constants6();
36075
36240
  init_utils6();
36076
36241
  GRADE_LEVEL_TEST_TYPES = [
36077
36242
  "placement",
@@ -36096,18 +36261,18 @@ async function upsertMasteryCompletionEntry(params) {
36096
36261
  await client.oneroster.assessmentLineItems.findOrCreate(lineItemId, {
36097
36262
  sourcedId: lineItemId,
36098
36263
  title: "Mastery Completion",
36099
- status: ONEROSTER_STATUS2.active,
36264
+ status: ONEROSTER_STATUS3.active,
36100
36265
  course: { sourcedId: ids.course },
36101
36266
  ...ids.componentResource ? { componentResource: { sourcedId: ids.componentResource } } : {}
36102
36267
  });
36103
36268
  await client.oneroster.assessmentResults.upsert(resultId, {
36104
36269
  sourcedId: resultId,
36105
- status: ONEROSTER_STATUS2.active,
36270
+ status: ONEROSTER_STATUS3.active,
36106
36271
  assessmentLineItem: { sourcedId: lineItemId },
36107
36272
  student: { sourcedId: studentId },
36108
36273
  score: 100,
36109
36274
  scoreDate: new Date().toISOString(),
36110
- scoreStatus: SCORE_STATUS2.fullyGraded,
36275
+ scoreStatus: SCORE_STATUS3.fullyGraded,
36111
36276
  inProgress: "false",
36112
36277
  metadata: {
36113
36278
  isMasteryCompletion: true,
@@ -36119,12 +36284,12 @@ async function upsertMasteryCompletionEntry(params) {
36119
36284
  try {
36120
36285
  await client.oneroster.assessmentResults.upsert(resultId, {
36121
36286
  sourcedId: resultId,
36122
- status: ONEROSTER_STATUS2.active,
36287
+ status: ONEROSTER_STATUS3.active,
36123
36288
  assessmentLineItem: { sourcedId: lineItemId },
36124
36289
  student: { sourcedId: studentId },
36125
36290
  score: 0,
36126
36291
  scoreDate: new Date().toISOString(),
36127
- scoreStatus: SCORE_STATUS2.notSubmitted,
36292
+ scoreStatus: SCORE_STATUS3.notSubmitted,
36128
36293
  inProgress: "true",
36129
36294
  metadata: {
36130
36295
  isMasteryCompletion: true,
@@ -36136,7 +36301,7 @@ async function upsertMasteryCompletionEntry(params) {
36136
36301
  }
36137
36302
  }
36138
36303
  var init_timeback_mastery_completion_util = __esm(() => {
36139
- init_constants5();
36304
+ init_constants6();
36140
36305
  init_utils6();
36141
36306
  });
36142
36307
 
@@ -36165,7 +36330,7 @@ class TimebackAdminService {
36165
36330
  this.deps = deps;
36166
36331
  }
36167
36332
  getGradeLevelTestCourseScope(integration) {
36168
- if (!isTimebackSubject(integration.subject) || !isTimebackGrade(integration.grade)) {
36333
+ if (!isTimebackSubject2(integration.subject) || !isTimebackGrade2(integration.grade)) {
36169
36334
  throw new ValidationError("Timeback integration has invalid grade or subject");
36170
36335
  }
36171
36336
  return {
@@ -36244,7 +36409,7 @@ class TimebackAdminService {
36244
36409
  await this.deps.validateDeveloperAccess(user, gameId);
36245
36410
  }
36246
36411
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
36247
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
36412
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
36248
36413
  });
36249
36414
  if (!integration) {
36250
36415
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -36342,7 +36507,7 @@ class TimebackAdminService {
36342
36507
  const ids = deriveSourcedIds2(courseId);
36343
36508
  const resource = await client.oneroster.resources.get(ids.resource);
36344
36509
  const playcademyMetadata = resource.metadata?.playcademy;
36345
- if (!isPlaycademyResourceMetadata2(playcademyMetadata)) {
36510
+ if (!isPlaycademyResourceMetadata(playcademyMetadata)) {
36346
36511
  return;
36347
36512
  }
36348
36513
  return playcademyMetadata?.mastery?.masterableUnits;
@@ -36746,7 +36911,7 @@ class TimebackAdminService {
36746
36911
  "app.timeback.include_inactive": options?.includeInactive ?? false
36747
36912
  });
36748
36913
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
36749
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
36914
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
36750
36915
  });
36751
36916
  if (!integration) {
36752
36917
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -36824,7 +36989,7 @@ class TimebackAdminService {
36824
36989
  columns: { id: true }
36825
36990
  }),
36826
36991
  this.deps.db.query.gameTimebackIntegrations.findMany({
36827
- where: eq(gameTimebackIntegrations.gameId, gameId)
36992
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
36828
36993
  }),
36829
36994
  this.deps.db.query.games.findFirst({
36830
36995
  where: eq(games.id, gameId),
@@ -36927,7 +37092,7 @@ class TimebackAdminService {
36927
37092
  "app.timeback.course_id": courseId
36928
37093
  });
36929
37094
  const integrations = await this.deps.db.query.gameTimebackIntegrations.findMany({
36930
- where: courseId ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId)) : eq(gameTimebackIntegrations.gameId, gameId)
37095
+ where: courseId ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus()) : and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
36931
37096
  });
36932
37097
  if (integrations.length === 0) {
36933
37098
  throw new NotFoundError("Timeback integration", gameId);
@@ -37017,7 +37182,7 @@ class TimebackAdminService {
37017
37182
  });
37018
37183
  const [integration, gameSource] = await Promise.all([
37019
37184
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37020
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37185
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37021
37186
  }),
37022
37187
  this.getGameActivitySource(gameId)
37023
37188
  ]);
@@ -37121,7 +37286,7 @@ class TimebackAdminService {
37121
37286
  "app.timeback.course_id": courseId
37122
37287
  });
37123
37288
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37124
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37289
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37125
37290
  });
37126
37291
  if (!integration) {
37127
37292
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37176,7 +37341,7 @@ class TimebackAdminService {
37176
37341
  "app.timeback.assessment_result_id": resultId
37177
37342
  });
37178
37343
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37179
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37344
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37180
37345
  });
37181
37346
  if (!integration) {
37182
37347
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37254,7 +37419,7 @@ class TimebackAdminService {
37254
37419
  });
37255
37420
  const [integration, gameSource, roster] = await Promise.all([
37256
37421
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37257
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37422
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37258
37423
  }),
37259
37424
  this.getGameActivitySource(gameId),
37260
37425
  client.oneroster.enrollments.listByCourse(courseId, {
@@ -37375,7 +37540,7 @@ class TimebackAdminService {
37375
37540
  });
37376
37541
  const [integration, gameSource] = await Promise.all([
37377
37542
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37378
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37543
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37379
37544
  }),
37380
37545
  this.getGameActivitySource(gameId)
37381
37546
  ]);
@@ -37459,7 +37624,7 @@ class TimebackAdminService {
37459
37624
  });
37460
37625
  const [integration, gameSource] = await Promise.all([
37461
37626
  this.deps.db.query.gameTimebackIntegrations.findFirst({
37462
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37627
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37463
37628
  }),
37464
37629
  this.getGameActivitySource(gameId)
37465
37630
  ]);
@@ -37688,7 +37853,7 @@ class TimebackAdminService {
37688
37853
  "app.timeback.course_id": courseId
37689
37854
  });
37690
37855
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37691
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
37856
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
37692
37857
  });
37693
37858
  if (!integration) {
37694
37859
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -37759,7 +37924,7 @@ class TimebackAdminService {
37759
37924
  "app.timeback.enrollment.operation": "enroll"
37760
37925
  });
37761
37926
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37762
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37927
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37763
37928
  });
37764
37929
  if (!integration) {
37765
37930
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37799,7 +37964,7 @@ class TimebackAdminService {
37799
37964
  "app.timeback.enrollment.operation": "unenroll"
37800
37965
  });
37801
37966
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37802
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37967
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37803
37968
  });
37804
37969
  if (!integration) {
37805
37970
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37820,7 +37985,7 @@ class TimebackAdminService {
37820
37985
  "app.timeback.enrollment.operation": "reactivate"
37821
37986
  });
37822
37987
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
37823
- where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId))
37988
+ where: and(eq(gameTimebackIntegrations.gameId, data.gameId), eq(gameTimebackIntegrations.courseId, data.courseId), isActiveGameTimebackIntegrationStatus())
37824
37989
  });
37825
37990
  if (!integration) {
37826
37991
  throw new NotFoundError("Timeback integration", `${data.gameId}:${data.courseId}`);
@@ -37866,7 +38031,7 @@ class TimebackAdminService {
37866
38031
  const resultId = `${lineItemId}:${studentId}:completion`;
37867
38032
  try {
37868
38033
  const result = await client.oneroster.assessmentResults.get(resultId);
37869
- if (result.scoreStatus === SCORE_STATUS2.fullyGraded) {
38034
+ if (result.scoreStatus === SCORE_STATUS3.fullyGraded) {
37870
38035
  return "complete";
37871
38036
  }
37872
38037
  return "incomplete";
@@ -37902,12 +38067,13 @@ class TimebackAdminService {
37902
38067
  var init_timeback_admin_service = __esm(() => {
37903
38068
  init_drizzle_orm();
37904
38069
  init_src();
38070
+ init_helpers_index();
37905
38071
  init_schemas_index();
37906
38072
  init_tables_index();
37907
38073
  init_spans();
37908
38074
  init_dist2();
37909
- init_constants5();
37910
- init_types3();
38075
+ init_constants6();
38076
+ init_types2();
37911
38077
  init_utils6();
37912
38078
  init_src4();
37913
38079
  init_timeback3();
@@ -37922,8 +38088,8 @@ var init_timeback_admin_service = __esm(() => {
37922
38088
  });
37923
38089
 
37924
38090
  // ../timeback/dist/errors.js
37925
- 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;
37926
- var init_errors4 = __esm(() => {
38091
+ 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;
38092
+ var init_errors6 = __esm(() => {
37927
38093
  init_src();
37928
38094
  init_constants9 = __esm6(() => {
37929
38095
  TIMEBACK_API_URLS5 = {
@@ -38107,18 +38273,79 @@ var init_errors4 = __esm(() => {
38107
38273
  timebackSdk: "TimebackSDKError"
38108
38274
  };
38109
38275
  });
38110
- init_constants9();
38111
- TimebackApiError2 = class TimebackApiError2 extends Error {
38112
- status;
38113
- details;
38114
- constructor(status, message, details) {
38115
- super(`${status} ${message}`);
38116
- this.name = ERROR_NAMES5.timebackApi;
38117
- this.status = status;
38118
- this.details = details;
38119
- Object.setPrototypeOf(this, TimebackApiError2.prototype);
38120
- }
38121
- };
38276
+ init_errors7 = __esm6(() => {
38277
+ init_constants9();
38278
+ TimebackError3 = class TimebackError4 extends Error {
38279
+ constructor(message) {
38280
+ super(message);
38281
+ this.name = ERROR_NAMES5.timebackSdk;
38282
+ }
38283
+ };
38284
+ TimebackApiError3 = class TimebackApiError4 extends Error {
38285
+ status;
38286
+ details;
38287
+ constructor(status, message, details) {
38288
+ super(`${status} ${message}`);
38289
+ this.name = ERROR_NAMES5.timebackApi;
38290
+ this.status = status;
38291
+ this.details = details;
38292
+ Object.setPrototypeOf(this, TimebackApiError4.prototype);
38293
+ }
38294
+ };
38295
+ TimebackAuthenticationError3 = class TimebackAuthenticationError4 extends TimebackError3 {
38296
+ constructor(message) {
38297
+ super(message || "Authentication failed. Please verify TIMEBACK_CLIENT_ID and TIMEBACK_CLIENT_SECRET are set correctly.");
38298
+ this.name = "TimebackAuthenticationError";
38299
+ Object.setPrototypeOf(this, TimebackAuthenticationError4.prototype);
38300
+ }
38301
+ };
38302
+ StudentNotFoundError3 = class StudentNotFoundError4 extends TimebackError3 {
38303
+ identifier;
38304
+ identifierType;
38305
+ constructor(identifier, identifierType = "email") {
38306
+ 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.`);
38307
+ this.name = "StudentNotFoundError";
38308
+ this.identifier = identifier;
38309
+ this.identifierType = identifierType;
38310
+ Object.setPrototypeOf(this, StudentNotFoundError4.prototype);
38311
+ }
38312
+ };
38313
+ ConfigurationError3 = class ConfigurationError4 extends TimebackError3 {
38314
+ field;
38315
+ constructor(field, message) {
38316
+ super(message || `Missing required configuration: ${field}. Please check your timeback.config.js file.`);
38317
+ this.name = "ConfigurationError";
38318
+ this.field = field;
38319
+ Object.setPrototypeOf(this, ConfigurationError4.prototype);
38320
+ }
38321
+ };
38322
+ ResourceAlreadyExistsError3 = class ResourceAlreadyExistsError4 extends TimebackError3 {
38323
+ resourceType;
38324
+ sourcedId;
38325
+ originalError;
38326
+ constructor(resourceType, sourcedId, originalError) {
38327
+ super(`${resourceType} with ID '${sourcedId}' already exists`);
38328
+ this.name = "ResourceAlreadyExistsError";
38329
+ this.resourceType = resourceType;
38330
+ this.sourcedId = sourcedId;
38331
+ this.originalError = originalError;
38332
+ Object.setPrototypeOf(this, ResourceAlreadyExistsError4.prototype);
38333
+ }
38334
+ };
38335
+ ResourceNotFoundError3 = class ResourceNotFoundError4 extends TimebackError3 {
38336
+ resourceType;
38337
+ sourcedId;
38338
+ constructor(resourceType, sourcedId) {
38339
+ 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`;
38340
+ super(message);
38341
+ this.name = "ResourceNotFoundError";
38342
+ this.resourceType = resourceType;
38343
+ this.sourcedId = sourcedId;
38344
+ Object.setPrototypeOf(this, ResourceNotFoundError4.prototype);
38345
+ }
38346
+ };
38347
+ });
38348
+ init_errors7();
38122
38349
  });
38123
38350
 
38124
38351
  // ../api-core/src/services/timeback-assessments.service.ts
@@ -38130,7 +38357,7 @@ class TimebackAssessmentsService {
38130
38357
  async resolveIntegrationId(gameId, courseId, user) {
38131
38358
  await this.deps.validateGameManagementAccess(user, gameId);
38132
38359
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
38133
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
38360
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
38134
38361
  });
38135
38362
  if (!integration) {
38136
38363
  throw new NotFoundError(`No Timeback integration found for game ${gameId} course ${courseId}`);
@@ -38223,7 +38450,7 @@ class TimebackAssessmentsService {
38223
38450
  ]
38224
38451
  });
38225
38452
  } catch (error) {
38226
- if (error instanceof TimebackApiError2 && error.status === 409) {} else {
38453
+ if (error instanceof TimebackApiError3 && error.status === 409) {} else {
38227
38454
  throw error;
38228
38455
  }
38229
38456
  }
@@ -38523,7 +38750,7 @@ class TimebackAssessmentsService {
38523
38750
  }
38524
38751
  async requireIntegration(integrationId) {
38525
38752
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
38526
- where: eq(gameTimebackIntegrations.id, integrationId)
38753
+ where: and(eq(gameTimebackIntegrations.id, integrationId), isActiveGameTimebackIntegrationStatus())
38527
38754
  });
38528
38755
  if (!integration) {
38529
38756
  throw new NotFoundError(`Integration not found: ${integrationId}`);
@@ -38554,7 +38781,7 @@ class TimebackAssessmentsService {
38554
38781
  }
38555
38782
  });
38556
38783
  } catch (error) {
38557
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38784
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38558
38785
  throw error;
38559
38786
  }
38560
38787
  }
@@ -38576,7 +38803,7 @@ class TimebackAssessmentsService {
38576
38803
  }
38577
38804
  });
38578
38805
  } catch (error) {
38579
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38806
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38580
38807
  throw error;
38581
38808
  }
38582
38809
  }
@@ -38594,7 +38821,7 @@ class TimebackAssessmentsService {
38594
38821
  }
38595
38822
  });
38596
38823
  } catch (error) {
38597
- if (!(error instanceof TimebackApiError2 && error.status === 409)) {
38824
+ if (!(error instanceof TimebackApiError3 && error.status === 409)) {
38598
38825
  throw error;
38599
38826
  }
38600
38827
  }
@@ -38612,14 +38839,63 @@ class TimebackAssessmentsService {
38612
38839
  }
38613
38840
  var init_timeback_assessments_service = __esm(() => {
38614
38841
  init_drizzle_orm();
38842
+ init_helpers_index();
38615
38843
  init_tables_index();
38616
38844
  init_spans();
38617
- init_constants5();
38618
- init_errors4();
38845
+ init_constants6();
38846
+ init_errors6();
38619
38847
  init_utils6();
38620
38848
  init_errors();
38621
38849
  });
38622
38850
 
38851
+ // ../api-core/src/utils/timeback-create-integration.util.ts
38852
+ function buildTimebackBaseConfigFromExistingConfig(config2) {
38853
+ return {
38854
+ organization: config2.organization,
38855
+ component: {
38856
+ ...config2.component,
38857
+ title: ""
38858
+ },
38859
+ resource: {
38860
+ ...config2.resource,
38861
+ title: ""
38862
+ },
38863
+ componentResource: {
38864
+ ...config2.componentResource,
38865
+ title: ""
38866
+ }
38867
+ };
38868
+ }
38869
+ function getMasterableUnitsFromTimebackConfig(config2) {
38870
+ const playcademyMetadata = config2.resource.metadata?.playcademy;
38871
+ if (!isPlaycademyResourceMetadata(playcademyMetadata)) {
38872
+ return null;
38873
+ }
38874
+ return playcademyMetadata?.mastery?.masterableUnits ?? null;
38875
+ }
38876
+ function getTotalXpFromTimebackConfig(config2) {
38877
+ const courseMetadata = isCourseMetadata(config2.course.metadata) ? config2.course.metadata : undefined;
38878
+ if (typeof courseMetadata?.metrics?.totalXp === "number") {
38879
+ return courseMetadata.metrics.totalXp;
38880
+ }
38881
+ const resourceMetadata = config2.resource.metadata;
38882
+ if (isRecord2(resourceMetadata) && typeof resourceMetadata.xp === "number") {
38883
+ return resourceMetadata.xp;
38884
+ }
38885
+ return null;
38886
+ }
38887
+ function timebackConfigMatchesCreateIntegrationRequest(config2, request2) {
38888
+ const subject = config2.course.subjects[0];
38889
+ const grade = config2.course.grades[0];
38890
+ const requestedLevel = request2.level ?? deriveTimebackCourseLevelFromGrade(request2.grade);
38891
+ 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;
38892
+ }
38893
+ var init_timeback_create_integration_util = __esm(() => {
38894
+ init_constants6();
38895
+ init_types2();
38896
+ init_timeback_util();
38897
+ });
38898
+
38623
38899
  // ../api-core/src/utils/timeback-promotion.util.ts
38624
38900
  async function promoteCompletedCourse({
38625
38901
  db: db2,
@@ -38629,7 +38905,7 @@ async function promoteCompletedCourse({
38629
38905
  enrollments: prefetchedEnrollments
38630
38906
  }) {
38631
38907
  const subjectIntegrations = await db2.query.gameTimebackIntegrations.findMany({
38632
- where: and(eq(gameTimebackIntegrations.gameId, currentIntegration.gameId), eq(gameTimebackIntegrations.subject, currentIntegration.subject))
38908
+ where: and(eq(gameTimebackIntegrations.gameId, currentIntegration.gameId), eq(gameTimebackIntegrations.subject, currentIntegration.subject), isActiveGameTimebackIntegrationStatus())
38633
38909
  });
38634
38910
  const nextIntegration = subjectIntegrations.filter((integration) => integration.grade > currentIntegration.grade).toSorted((left, right) => left.grade - right.grade)[0];
38635
38911
  if (!nextIntegration) {
@@ -38684,21 +38960,72 @@ async function promoteCompletedCourse({
38684
38960
  }
38685
38961
  var init_timeback_promotion_util = __esm(() => {
38686
38962
  init_drizzle_orm();
38963
+ init_helpers_index();
38687
38964
  init_tables_index();
38688
38965
  init_spans();
38689
38966
  });
38690
38967
 
38968
+ // ../api-core/src/utils/timeback-removed-integration.util.ts
38969
+ function toGameTimebackIntegration(integration) {
38970
+ return {
38971
+ id: integration.id,
38972
+ gameId: integration.gameId,
38973
+ courseId: integration.courseId,
38974
+ grade: integration.grade,
38975
+ subject: integration.subject,
38976
+ totalXp: integration.totalXp ?? null,
38977
+ status: integration.status ?? ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
38978
+ deactivatedAt: integration.deactivatedAt ?? null,
38979
+ reactivatedAt: integration.reactivatedAt ?? null,
38980
+ createdAt: integration.createdAt,
38981
+ updatedAt: integration.updatedAt,
38982
+ lastVerifiedAt: integration.lastVerifiedAt ?? null
38983
+ };
38984
+ }
38985
+ function buildFallbackRemovedGameTimebackIntegration(integration) {
38986
+ if (!isTimebackSubject(integration.subject)) {
38987
+ throw new ValidationError(`Invalid subject "${integration.subject}"`);
38988
+ }
38989
+ if (!isTimebackGrade(integration.grade)) {
38990
+ throw new ValidationError(`Invalid grade "${integration.grade}"`);
38991
+ }
38992
+ return {
38993
+ integration: toGameTimebackIntegration(integration),
38994
+ title: `${integration.subject} ${formatGradeLabel(integration.grade)}`,
38995
+ courseCode: integration.courseId,
38996
+ subject: integration.subject,
38997
+ grade: integration.grade,
38998
+ totalXp: integration.totalXp ?? null,
38999
+ masterableUnits: null,
39000
+ removedAt: integration.deactivatedAt ?? null,
39001
+ metadata: null
39002
+ };
39003
+ }
39004
+ var init_timeback_removed_integration_util = __esm(() => {
39005
+ init_helpers_index();
39006
+ init_types2();
39007
+ init_timeback3();
39008
+ init_errors();
39009
+ });
39010
+
38691
39011
  // ../api-core/src/services/timeback.service.ts
39012
+ async function findGameTimebackIntegrationForUpdate(db2, condition) {
39013
+ const [integration] = await db2.select().from(gameTimebackIntegrations).where(condition).limit(1).for("update");
39014
+ return integration;
39015
+ }
38692
39016
  var TimebackService;
38693
39017
  var init_timeback_service = __esm(() => {
38694
39018
  init_drizzle_orm();
38695
39019
  init_src();
39020
+ init_helpers_index();
38696
39021
  init_tables_index();
38697
39022
  init_spans();
38698
39023
  init_dist2();
38699
- init_types3();
39024
+ init_types2();
38700
39025
  init_errors();
39026
+ init_timeback_create_integration_util();
38701
39027
  init_timeback_promotion_util();
39028
+ init_timeback_removed_integration_util();
38702
39029
  init_timeback_util();
38703
39030
  TimebackService = class TimebackService {
38704
39031
  static HEARTBEAT_DEDUPE_TTL_MS = 5 * 60 * 1000;
@@ -38928,7 +39255,7 @@ var init_timeback_service = __esm(() => {
38928
39255
  return [];
38929
39256
  }
38930
39257
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
38931
- where: inArray(gameTimebackIntegrations.courseId, courseIds)
39258
+ where: and(inArray(gameTimebackIntegrations.courseId, courseIds), isActiveGameTimebackIntegrationStatus())
38932
39259
  });
38933
39260
  return mapEnrollmentsToUserEnrollments(enrollments, integrations);
38934
39261
  } catch (error) {
@@ -38953,6 +39280,7 @@ var init_timeback_service = __esm(() => {
38953
39280
  const verboseData = [];
38954
39281
  let integrationCreatedCount = 0;
38955
39282
  let integrationUpdatedCount = 0;
39283
+ let integrationReactivatedCount = 0;
38956
39284
  for (const courseConfig of courses) {
38957
39285
  let applySuffix = function(text3) {
38958
39286
  return suffix ? `${text3} ${suffix}` : text3;
@@ -38967,16 +39295,16 @@ var init_timeback_service = __esm(() => {
38967
39295
  totalXp: derivedTotalXp,
38968
39296
  masterableUnits: derivedMasterableUnits
38969
39297
  } = courseConfig;
38970
- if (!isTimebackSubject3(subjectInput)) {
39298
+ if (!isTimebackSubject(subjectInput)) {
38971
39299
  throw new ValidationError(`Invalid subject "${subjectInput}"`);
38972
39300
  }
38973
- if (!isTimebackGrade3(grade)) {
39301
+ if (!isTimebackGrade(grade)) {
38974
39302
  throw new ValidationError(`Invalid grade "${grade}"`);
38975
39303
  }
38976
39304
  const subject = subjectInput;
38977
39305
  const courseMetadata = isCourseMetadata(metadata2) ? metadata2 : undefined;
38978
39306
  const totalXp = derivedTotalXp ?? courseMetadata?.metrics?.totalXp;
38979
- const masterableUnits = derivedMasterableUnits ?? (isPlaycademyResourceMetadata2(courseMetadata?.playcademy) ? courseMetadata?.playcademy?.mastery?.masterableUnits : undefined);
39307
+ const masterableUnits = derivedMasterableUnits ?? (isPlaycademyResourceMetadata(courseMetadata?.playcademy) ? courseMetadata?.playcademy?.mastery?.masterableUnits : undefined);
38980
39308
  if (typeof totalXp !== "number") {
38981
39309
  throw new ValidationError(`Course "${title}" is missing totalXp`);
38982
39310
  }
@@ -39022,19 +39350,28 @@ var init_timeback_service = __esm(() => {
39022
39350
  title: applySuffix(baseConfig.componentResource.title || "")
39023
39351
  }
39024
39352
  };
39025
- const existingIntegration = existing.find((i2) => i2.grade === grade && i2.subject === subject);
39353
+ const matches = existing.filter((i2) => i2.grade === grade && i2.subject === subject);
39354
+ 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];
39026
39355
  if (existingIntegration) {
39027
- await client.update(existingIntegration.courseId, fullConfig);
39028
- const [updated] = await db2.update(gameTimebackIntegrations).set({ subject, totalXp, updatedAt: new Date }).where(eq(gameTimebackIntegrations.id, existingIntegration.id)).returning();
39356
+ const { updated, revived } = await this.updateSetupIntegration({
39357
+ client,
39358
+ existingIntegration,
39359
+ fullConfig,
39360
+ subject,
39361
+ totalXp
39362
+ });
39029
39363
  if (updated) {
39030
- integrations.push(this.toGameTimebackIntegration(updated));
39364
+ integrations.push(toGameTimebackIntegration(updated));
39031
39365
  integrationUpdatedCount++;
39366
+ if (revived) {
39367
+ integrationReactivatedCount++;
39368
+ }
39032
39369
  }
39033
39370
  } else {
39034
39371
  const result = await client.setup(fullConfig, { verbose });
39035
39372
  const [integration] = await db2.insert(gameTimebackIntegrations).values({ gameId, courseId: result.courseId, grade, subject, totalXp }).returning();
39036
39373
  if (integration) {
39037
- const dto = this.toGameTimebackIntegration(integration);
39374
+ const dto = toGameTimebackIntegration(integration);
39038
39375
  integrations.push(dto);
39039
39376
  integrationCreatedCount++;
39040
39377
  if (verbose && result.verboseData) {
@@ -39046,7 +39383,8 @@ var init_timeback_service = __esm(() => {
39046
39383
  setAttributes({
39047
39384
  "app.timeback.integration_count": integrations.length,
39048
39385
  "app.timeback.integration_created_count": integrationCreatedCount,
39049
- "app.timeback.integration_updated_count": integrationUpdatedCount
39386
+ "app.timeback.integration_updated_count": integrationUpdatedCount,
39387
+ "app.timeback.integration_reactivated_count": integrationReactivatedCount
39050
39388
  });
39051
39389
  return {
39052
39390
  integrations,
@@ -39054,19 +39392,221 @@ var init_timeback_service = __esm(() => {
39054
39392
  };
39055
39393
  });
39056
39394
  }
39395
+ async updateSetupIntegration(args2) {
39396
+ const { client, existingIntegration, fullConfig, subject, totalXp } = args2;
39397
+ const revived = existingIntegration.status === DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS;
39398
+ await client.update(existingIntegration.courseId, fullConfig);
39399
+ if (revived) {
39400
+ await client.reactivateCourse(existingIntegration.courseId);
39401
+ }
39402
+ const now2 = new Date;
39403
+ const [updated] = await this.deps.db.update(gameTimebackIntegrations).set({
39404
+ subject,
39405
+ totalXp,
39406
+ updatedAt: now2,
39407
+ ...revived && {
39408
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39409
+ deactivatedAt: null,
39410
+ reactivatedAt: now2
39411
+ }
39412
+ }).where(eq(gameTimebackIntegrations.id, existingIntegration.id)).returning();
39413
+ return { updated, revived };
39414
+ }
39415
+ async createIntegration(gameId, user, request2) {
39416
+ return this.withClientTelemetry(async () => {
39417
+ const client = this.requireClient();
39418
+ const db2 = this.deps.db;
39419
+ await this.deps.validateDeveloperAccess(user, gameId);
39420
+ setAttributes({
39421
+ "app.timeback.grade": request2.grade,
39422
+ "app.timeback.subject": request2.subject
39423
+ });
39424
+ const activeConflict = await db2.query.gameTimebackIntegrations.findFirst({
39425
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, request2.grade), eq(gameTimebackIntegrations.subject, request2.subject), isActiveGameTimebackIntegrationStatus())
39426
+ });
39427
+ if (activeConflict) {
39428
+ throw new ConflictError(`A TimeBack integration already exists for ${request2.subject} Grade ${request2.grade}`);
39429
+ }
39430
+ const removedCandidates = await db2.query.gameTimebackIntegrations.findMany({
39431
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, request2.grade), eq(gameTimebackIntegrations.subject, request2.subject), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))
39432
+ });
39433
+ for (const candidate of removedCandidates) {
39434
+ const config2 = await client.getConfig(candidate.courseId).catch((error) => {
39435
+ addEvent("timeback.removed_integration_config_fetch_failed", {
39436
+ "app.game.id": gameId,
39437
+ "app.timeback.course_id": candidate.courseId,
39438
+ "exception.type": errorType(error),
39439
+ "app.error.message": errorMessage(error)
39440
+ });
39441
+ return null;
39442
+ });
39443
+ if (config2 && timebackConfigMatchesCreateIntegrationRequest(config2, request2)) {
39444
+ const updated = await db2.transaction(async (tx) => {
39445
+ const database = tx;
39446
+ const lockedCandidate = await findGameTimebackIntegrationForUpdate(database, eq(gameTimebackIntegrations.id, candidate.id));
39447
+ if (lockedCandidate?.status !== DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS) {
39448
+ throw new ConflictError(`A TimeBack integration already exists for ${request2.subject} Grade ${request2.grade}`);
39449
+ }
39450
+ const now2 = new Date;
39451
+ const [integration2] = await database.update(gameTimebackIntegrations).set({
39452
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39453
+ totalXp: request2.totalXp,
39454
+ deactivatedAt: null,
39455
+ reactivatedAt: now2,
39456
+ updatedAt: now2
39457
+ }).where(and(eq(gameTimebackIntegrations.id, candidate.id), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))).returning();
39458
+ if (!integration2) {
39459
+ throw new NotFoundError("Timeback integration", candidate.id);
39460
+ }
39461
+ await client.reactivateCourse(candidate.courseId);
39462
+ return integration2;
39463
+ });
39464
+ setAttribute("app.timeback.course_create_mode", "reactivated-removed");
39465
+ return toGameTimebackIntegration(updated);
39466
+ }
39467
+ }
39468
+ const reference = await db2.query.gameTimebackIntegrations.findFirst({
39469
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus()),
39470
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.createdAt)]
39471
+ }) ?? await db2.query.gameTimebackIntegrations.findFirst({
39472
+ where: eq(gameTimebackIntegrations.gameId, gameId),
39473
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.createdAt)]
39474
+ });
39475
+ if (!reference) {
39476
+ throw new ValidationError("Run `playcademy timeback setup` before adding courses from the dashboard.");
39477
+ }
39478
+ const referenceConfig = await client.getConfig(reference.courseId);
39479
+ const result = await this.setupIntegration(gameId, {
39480
+ gameId,
39481
+ courses: [
39482
+ {
39483
+ title: request2.title,
39484
+ courseCode: request2.courseCode,
39485
+ subject: request2.subject,
39486
+ grade: request2.grade,
39487
+ level: request2.level ?? deriveTimebackCourseLevelFromGrade(request2.grade),
39488
+ totalXp: request2.totalXp,
39489
+ masterableUnits: request2.masterableUnits
39490
+ }
39491
+ ],
39492
+ baseConfig: buildTimebackBaseConfigFromExistingConfig(referenceConfig)
39493
+ }, user);
39494
+ const integration = result.integrations[0];
39495
+ if (!integration) {
39496
+ throw new InternalError("TimeBack course creation did not return an integration");
39497
+ }
39498
+ setAttribute("app.timeback.course_create_mode", "created-new");
39499
+ return integration;
39500
+ });
39501
+ }
39057
39502
  async getIntegrations(gameId, user) {
39058
39503
  await this.deps.validateGameManagementAccess(user, gameId);
39059
39504
  const rows = await this.deps.db.query.gameTimebackIntegrations.findMany({
39060
- where: eq(gameTimebackIntegrations.gameId, gameId)
39505
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39506
+ });
39507
+ return rows.map((row) => toGameTimebackIntegration(row));
39508
+ }
39509
+ async getRemovedIntegrations(gameId, user) {
39510
+ return this.withClientTelemetry(async () => {
39511
+ const client = this.requireClient();
39512
+ await this.deps.validateGameManagementAccess(user, gameId);
39513
+ const rows = await this.deps.db.query.gameTimebackIntegrations.findMany({
39514
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS)),
39515
+ orderBy: (table8, { asc: asc2 }) => [asc2(table8.subject), asc2(table8.grade)]
39516
+ });
39517
+ setAttribute("app.timeback.removed_integration_count", rows.length);
39518
+ return Promise.all(rows.map(async (row) => {
39519
+ try {
39520
+ const config2 = await client.getConfig(row.courseId);
39521
+ return this.toRemovedGameTimebackIntegration(row, config2);
39522
+ } catch (error) {
39523
+ addEvent("timeback.removed_integration_config_fetch_failed", {
39524
+ "app.game.id": gameId,
39525
+ "app.timeback.course_id": row.courseId,
39526
+ "exception.type": errorType(error),
39527
+ "app.error.message": errorMessage(error)
39528
+ });
39529
+ return buildFallbackRemovedGameTimebackIntegration(row);
39530
+ }
39531
+ }));
39532
+ });
39533
+ }
39534
+ async deactivateCourse(gameId, courseId, user) {
39535
+ return this.withClientTelemetry(async () => {
39536
+ const client = this.requireClient();
39537
+ const db2 = this.deps.db;
39538
+ await this.deps.validateDeveloperAccess(user, gameId);
39539
+ const updated = await db2.transaction(async (tx) => {
39540
+ const database = tx;
39541
+ const integration = await findGameTimebackIntegrationForUpdate(database, and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus()));
39542
+ if (!integration) {
39543
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39544
+ }
39545
+ const activeEnrollments = await client.oneroster.enrollments.listByCourse(courseId, {
39546
+ role: "student",
39547
+ includeUsers: false
39548
+ });
39549
+ setAttribute("app.timeback.active_enrollment_count", activeEnrollments.length);
39550
+ if (activeEnrollments.length > 0) {
39551
+ throw new ConflictError("Cannot remove course with active enrollments", {
39552
+ courseId,
39553
+ activeEnrollmentCount: activeEnrollments.length
39554
+ });
39555
+ }
39556
+ const now2 = new Date;
39557
+ const [updatedIntegration] = await database.update(gameTimebackIntegrations).set({
39558
+ status: DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS,
39559
+ deactivatedAt: now2,
39560
+ updatedAt: now2
39561
+ }).where(and(eq(gameTimebackIntegrations.id, integration.id), isActiveGameTimebackIntegrationStatus())).returning();
39562
+ if (!updatedIntegration) {
39563
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39564
+ }
39565
+ await client.deactivateCourse(courseId);
39566
+ return updatedIntegration;
39567
+ });
39568
+ return toGameTimebackIntegration(updated);
39569
+ });
39570
+ }
39571
+ async reactivateCourse(gameId, courseId, user) {
39572
+ return this.withClientTelemetry(async () => {
39573
+ const client = this.requireClient();
39574
+ const db2 = this.deps.db;
39575
+ await this.deps.validateDeveloperAccess(user, gameId);
39576
+ const updated = await db2.transaction(async (tx) => {
39577
+ const database = tx;
39578
+ const integration = await findGameTimebackIntegrationForUpdate(database, and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS)));
39579
+ if (!integration) {
39580
+ throw new NotFoundError("Removed Timeback course", `${gameId}:${courseId}`);
39581
+ }
39582
+ const activeConflict = await database.query.gameTimebackIntegrations.findFirst({
39583
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, integration.subject), isActiveGameTimebackIntegrationStatus())
39584
+ });
39585
+ if (activeConflict) {
39586
+ throw new ConflictError(`An active TimeBack course already exists for ${integration.subject} Grade ${integration.grade}`);
39587
+ }
39588
+ const now2 = new Date;
39589
+ const [updatedIntegration] = await database.update(gameTimebackIntegrations).set({
39590
+ status: ACTIVE_GAME_TIMEBACK_INTEGRATION_STATUS,
39591
+ deactivatedAt: null,
39592
+ reactivatedAt: now2,
39593
+ updatedAt: now2
39594
+ }).where(and(eq(gameTimebackIntegrations.id, integration.id), eq(gameTimebackIntegrations.status, DEACTIVATED_GAME_TIMEBACK_INTEGRATION_STATUS))).returning();
39595
+ if (!updatedIntegration) {
39596
+ throw new NotFoundError("Timeback course", `${gameId}:${courseId}`);
39597
+ }
39598
+ await client.reactivateCourse(courseId);
39599
+ return updatedIntegration;
39600
+ });
39601
+ return toGameTimebackIntegration(updated);
39061
39602
  });
39062
- return rows.map((row) => this.toGameTimebackIntegration(row));
39063
39603
  }
39064
39604
  async getIntegrationConfig(gameId, courseId, user) {
39065
39605
  return this.withClientTelemetry(async () => {
39066
39606
  const client = this.requireClient();
39067
39607
  await this.deps.validateGameManagementAccess(user, gameId);
39068
39608
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39069
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
39609
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
39070
39610
  });
39071
39611
  if (!integration) {
39072
39612
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
@@ -39083,15 +39623,15 @@ var init_timeback_service = __esm(() => {
39083
39623
  "app.timeback.course_id": courseId
39084
39624
  });
39085
39625
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39086
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId))
39626
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.courseId, courseId), isActiveGameTimebackIntegrationStatus())
39087
39627
  });
39088
39628
  if (!integration) {
39089
39629
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
39090
39630
  }
39091
39631
  const timebackConfig = await client.getConfig(courseId);
39092
39632
  const liveSubject = timebackConfig.course.subjects[0];
39093
- const subject = patch.subject ?? (isTimebackSubject3(liveSubject) ? liveSubject : integration.subject);
39094
- if (!isTimebackSubject3(subject)) {
39633
+ const subject = patch.subject ?? (isTimebackSubject(liveSubject) ? liveSubject : integration.subject);
39634
+ if (!isTimebackSubject(subject)) {
39095
39635
  throw new ValidationError(`Invalid subject "${subject}"`);
39096
39636
  }
39097
39637
  setAttributes({
@@ -39101,14 +39641,14 @@ var init_timeback_service = __esm(() => {
39101
39641
  });
39102
39642
  if (subject !== integration.subject) {
39103
39643
  const subjectConflict = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39104
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, subject))
39644
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, integration.grade), eq(gameTimebackIntegrations.subject, subject), isActiveGameTimebackIntegrationStatus())
39105
39645
  });
39106
39646
  if (subjectConflict && subjectConflict.id !== integration.id) {
39107
39647
  throw new ValidationError(`A TimeBack integration already exists for ${subject} Grade ${integration.grade}`);
39108
39648
  }
39109
39649
  }
39110
- const totalXp = "totalXp" in patch ? patch.totalXp ?? null : TimebackService.getTotalXpFromConfig(timebackConfig) ?? integration.totalXp ?? null;
39111
- const masterableUnits = "masterableUnits" in patch ? patch.masterableUnits ?? null : TimebackService.getMasterableUnitsFromConfig(timebackConfig);
39650
+ const totalXp = "totalXp" in patch ? patch.totalXp ?? null : getTotalXpFromTimebackConfig(timebackConfig) ?? integration.totalXp ?? null;
39651
+ const masterableUnits = "masterableUnits" in patch ? patch.masterableUnits ?? null : getMasterableUnitsFromTimebackConfig(timebackConfig);
39112
39652
  setAttributes({
39113
39653
  "app.timeback.total_xp": totalXp,
39114
39654
  "app.timeback.masterable_units": masterableUnits
@@ -39128,7 +39668,7 @@ var init_timeback_service = __esm(() => {
39128
39668
  if (!updated) {
39129
39669
  throw new NotFoundError("Timeback integration", `${gameId}:${courseId}`);
39130
39670
  }
39131
- return this.toGameTimebackIntegration(updated);
39671
+ return toGameTimebackIntegration(updated);
39132
39672
  });
39133
39673
  }
39134
39674
  async verifyIntegration(gameId, user) {
@@ -39138,7 +39678,7 @@ var init_timeback_service = __esm(() => {
39138
39678
  await this.deps.validateDeveloperAccess(user, gameId);
39139
39679
  TimebackService.recordIntegrationOperation("verify_integration");
39140
39680
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
39141
- where: eq(gameTimebackIntegrations.gameId, gameId)
39681
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39142
39682
  });
39143
39683
  if (integrations.length === 0) {
39144
39684
  throw new NotFoundError("Timeback integration", gameId);
@@ -39151,7 +39691,7 @@ var init_timeback_service = __esm(() => {
39151
39691
  const errors3 = Object.entries(resources).filter(([_, r]) => !r.found).map(([name3]) => `${name3} not found`);
39152
39692
  const status = allFound ? "success" : "error";
39153
39693
  return {
39154
- integration: this.toGameTimebackIntegration({
39694
+ integration: toGameTimebackIntegration({
39155
39695
  ...integration,
39156
39696
  lastVerifiedAt: now2
39157
39697
  }),
@@ -39160,7 +39700,7 @@ var init_timeback_service = __esm(() => {
39160
39700
  ...errors3.length > 0 && { errors: errors3 }
39161
39701
  };
39162
39702
  }));
39163
- await db2.update(gameTimebackIntegrations).set({ lastVerifiedAt: now2 }).where(eq(gameTimebackIntegrations.gameId, gameId));
39703
+ await db2.update(gameTimebackIntegrations).set({ lastVerifiedAt: now2 }).where(inArray(gameTimebackIntegrations.id, integrations.map((integration) => integration.id)));
39164
39704
  const overallStatus = results.every((r) => r.status === "success") ? "success" : "error";
39165
39705
  const missingResourceCount = results.reduce((count, result) => count + (result.errors?.length ?? 0), 0);
39166
39706
  setAttributes({
@@ -39176,7 +39716,7 @@ var init_timeback_service = __esm(() => {
39176
39716
  const client = this.requireClient();
39177
39717
  await this.deps.validateDeveloperAccess(user, gameId);
39178
39718
  const integration = await this.deps.db.query.gameTimebackIntegrations.findFirst({
39179
- where: eq(gameTimebackIntegrations.gameId, gameId)
39719
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39180
39720
  });
39181
39721
  if (!integration) {
39182
39722
  throw new NotFoundError("Timeback integration", gameId);
@@ -39203,24 +39743,6 @@ var init_timeback_service = __esm(() => {
39203
39743
  await db2.delete(gameTimebackIntegrations).where(eq(gameTimebackIntegrations.gameId, gameId));
39204
39744
  });
39205
39745
  }
39206
- static getMasterableUnitsFromConfig(config2) {
39207
- const playcademyMetadata = config2.resource.metadata?.playcademy;
39208
- if (!isPlaycademyResourceMetadata2(playcademyMetadata)) {
39209
- return null;
39210
- }
39211
- return playcademyMetadata?.mastery?.masterableUnits ?? null;
39212
- }
39213
- static getTotalXpFromConfig(config2) {
39214
- const courseMetadata = isCourseMetadata(config2.course.metadata) ? config2.course.metadata : undefined;
39215
- if (typeof courseMetadata?.metrics?.totalXp === "number") {
39216
- return courseMetadata.metrics.totalXp;
39217
- }
39218
- const resourceMetadata = config2.resource.metadata;
39219
- if (isRecord2(resourceMetadata) && typeof resourceMetadata.xp === "number") {
39220
- return resourceMetadata.xp;
39221
- }
39222
- return null;
39223
- }
39224
39746
  static patchCourseMetadata(metadata2, totalXp, options) {
39225
39747
  const nextMetadata = isRecord2(metadata2) ? { ...metadata2 } : {};
39226
39748
  const currentMetrics = isRecord2(nextMetadata.metrics) ? nextMetadata.metrics : {};
@@ -39343,31 +39865,29 @@ var init_timeback_service = __esm(() => {
39343
39865
  }
39344
39866
  };
39345
39867
  }
39346
- toGameTimebackIntegration(integration) {
39868
+ toRemovedGameTimebackIntegration(integration, config2) {
39869
+ const grade = config2.course.grades[0] ?? integration.grade;
39870
+ if (!isTimebackGrade(grade)) {
39871
+ throw new ValidationError(`Invalid grade "${grade}"`);
39872
+ }
39347
39873
  return {
39348
- id: integration.id,
39349
- gameId: integration.gameId,
39350
- courseId: integration.courseId,
39351
- grade: integration.grade,
39352
- subject: integration.subject,
39353
- totalXp: integration.totalXp ?? null,
39354
- createdAt: integration.createdAt,
39355
- updatedAt: integration.updatedAt,
39356
- lastVerifiedAt: integration.lastVerifiedAt ?? null
39874
+ ...this.toGameTimebackIntegrationConfig(integration, config2),
39875
+ grade,
39876
+ removedAt: integration.deactivatedAt ?? null
39357
39877
  };
39358
39878
  }
39359
39879
  toGameTimebackIntegrationConfig(integration, config2) {
39360
39880
  const subject = config2.course.subjects[0] ?? integration.subject;
39361
- if (!isTimebackSubject3(subject)) {
39881
+ if (!isTimebackSubject(subject)) {
39362
39882
  throw new ValidationError(`Invalid subject "${subject}"`);
39363
39883
  }
39364
39884
  return {
39365
- integration: this.toGameTimebackIntegration(integration),
39885
+ integration: toGameTimebackIntegration(integration),
39366
39886
  title: config2.course.title,
39367
39887
  courseCode: config2.course.courseCode,
39368
39888
  subject,
39369
- totalXp: TimebackService.getTotalXpFromConfig(config2) ?? integration.totalXp ?? null,
39370
- masterableUnits: TimebackService.getMasterableUnitsFromConfig(config2),
39889
+ totalXp: getTotalXpFromTimebackConfig(config2) ?? integration.totalXp ?? null,
39890
+ masterableUnits: getMasterableUnitsFromTimebackConfig(config2),
39371
39891
  metadata: isCourseMetadata(config2.course.metadata) ? config2.course.metadata : null
39372
39892
  };
39373
39893
  }
@@ -39399,7 +39919,7 @@ var init_timeback_service = __esm(() => {
39399
39919
  });
39400
39920
  await this.deps.validateDeveloperAccess(user, gameId);
39401
39921
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39402
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject))
39922
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject), isActiveGameTimebackIntegrationStatus())
39403
39923
  });
39404
39924
  if (!integration) {
39405
39925
  throw new NotFoundError(`Timeback integration for game (grade ${activityData.grade}, subject ${activityData.subject})`);
@@ -39460,9 +39980,7 @@ var init_timeback_service = __esm(() => {
39460
39980
  "app.timeback.xp_awarded": result.xpAwarded,
39461
39981
  "app.timeback.mastered_units_requested": masteredUnits,
39462
39982
  "app.timeback.mastered_units_absolute_requested": masteredUnitsAbsolute,
39463
- "app.timeback.mastered_units_applied": result.masteredUnitsApplied,
39464
- "app.timeback.score_status": result.scoreStatus,
39465
- "app.timeback.in_progress": result.inProgress
39983
+ "app.timeback.mastered_units_applied": result.masteredUnitsApplied
39466
39984
  });
39467
39985
  return {
39468
39986
  status: "ok",
@@ -39470,8 +39988,6 @@ var init_timeback_service = __esm(() => {
39470
39988
  xpAwarded: result.xpAwarded,
39471
39989
  masteredUnits: result.masteredUnitsApplied,
39472
39990
  pctCompleteApp: result.pctCompleteApp,
39473
- scoreStatus: result.scoreStatus,
39474
- inProgress: result.inProgress,
39475
39991
  ...result.warnings ? { warnings: result.warnings } : {}
39476
39992
  };
39477
39993
  }
@@ -39484,7 +40000,7 @@ var init_timeback_service = __esm(() => {
39484
40000
  const client = this.requireClient();
39485
40001
  const db2 = this.deps.db;
39486
40002
  const integrations = await db2.query.gameTimebackIntegrations.findMany({
39487
- where: subject ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.subject, subject)) : eq(gameTimebackIntegrations.gameId, gameId)
40003
+ where: subject ? and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.subject, subject), isActiveGameTimebackIntegrationStatus()) : and(eq(gameTimebackIntegrations.gameId, gameId), isActiveGameTimebackIntegrationStatus())
39488
40004
  });
39489
40005
  if (integrations.length === 0) {
39490
40006
  throw new NotFoundError(subject ? `Timeback integrations for game (subject ${subject})` : "Timeback integrations for game");
@@ -39666,7 +40182,7 @@ var init_timeback_service = __esm(() => {
39666
40182
  }
39667
40183
  const pendingHeartbeat = (async () => {
39668
40184
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39669
- where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject))
40185
+ where: and(eq(gameTimebackIntegrations.gameId, gameId), eq(gameTimebackIntegrations.grade, activityData.grade), eq(gameTimebackIntegrations.subject, activityData.subject), isActiveGameTimebackIntegrationStatus())
39670
40186
  });
39671
40187
  if (!integration) {
39672
40188
  throw new NotFoundError(`Timeback integration for game (grade ${activityData.grade}, subject ${activityData.subject})`);
@@ -39714,7 +40230,10 @@ var init_timeback_service = __esm(() => {
39714
40230
  let courseIds = [];
39715
40231
  if (options?.gameId) {
39716
40232
  await this.deps.validateDeveloperAccess(user, options.gameId);
39717
- const conditions2 = [eq(gameTimebackIntegrations.gameId, options.gameId)];
40233
+ const conditions2 = [
40234
+ eq(gameTimebackIntegrations.gameId, options.gameId),
40235
+ isActiveGameTimebackIntegrationStatus()
40236
+ ];
39718
40237
  if (options.grade !== undefined && options.subject) {
39719
40238
  conditions2.push(eq(gameTimebackIntegrations.grade, options.grade));
39720
40239
  conditions2.push(eq(gameTimebackIntegrations.subject, options.subject));
@@ -39741,7 +40260,10 @@ var init_timeback_service = __esm(() => {
39741
40260
  const client = this.requireClient();
39742
40261
  const db2 = this.deps.db;
39743
40262
  await this.deps.validateDeveloperAccess(user, options.gameId);
39744
- const conditions2 = [eq(gameTimebackIntegrations.gameId, options.gameId)];
40263
+ const conditions2 = [
40264
+ eq(gameTimebackIntegrations.gameId, options.gameId),
40265
+ isActiveGameTimebackIntegrationStatus()
40266
+ ];
39745
40267
  if (options.grade !== undefined && options.subject) {
39746
40268
  conditions2.push(eq(gameTimebackIntegrations.grade, options.grade));
39747
40269
  conditions2.push(eq(gameTimebackIntegrations.subject, options.subject));
@@ -39768,7 +40290,7 @@ var init_timeback_service = __esm(() => {
39768
40290
  const db2 = this.deps.db;
39769
40291
  await this.deps.validateDeveloperAccess(user, options.gameId);
39770
40292
  const integration = await db2.query.gameTimebackIntegrations.findFirst({
39771
- where: and(eq(gameTimebackIntegrations.gameId, options.gameId), eq(gameTimebackIntegrations.subject, options.subject))
40293
+ where: and(eq(gameTimebackIntegrations.gameId, options.gameId), eq(gameTimebackIntegrations.subject, options.subject), isActiveGameTimebackIntegrationStatus())
39772
40294
  });
39773
40295
  if (!integration) {
39774
40296
  throw new ValidationError(`Subject "${options.subject}" is not configured for game ${options.gameId}`);
@@ -40655,7 +41177,7 @@ class UserService {
40655
41177
  return [];
40656
41178
  }
40657
41179
  const integrations = await this.deps.db.query.gameTimebackIntegrations.findMany({
40658
- where: inArray(gameTimebackIntegrations.courseId, courseIds)
41180
+ where: and(inArray(gameTimebackIntegrations.courseId, courseIds), isActiveGameTimebackIntegrationStatus())
40659
41181
  });
40660
41182
  return mapEnrollmentsToUserEnrollments(enrollments, integrations);
40661
41183
  } catch (error) {
@@ -40677,6 +41199,7 @@ class UserService {
40677
41199
  var init_user_service = __esm(() => {
40678
41200
  init_drizzle_orm();
40679
41201
  init_src();
41202
+ init_helpers_index();
40680
41203
  init_tables_index();
40681
41204
  init_spans();
40682
41205
  init_errors();
@@ -56874,7 +57397,7 @@ function extractTablesRelationalConfig2(schema5, configHelpers) {
56874
57397
  return { tables: tablesConfig, tableNamesMap };
56875
57398
  }
56876
57399
  function relations3(table62, relations22) {
56877
- return new Relations2(table62, (helpers) => Object.fromEntries(Object.entries(relations22(helpers)).map(([key, value]) => [
57400
+ return new Relations2(table62, (helpers3) => Object.fromEntries(Object.entries(relations22(helpers3)).map(([key, value]) => [
56878
57401
  key,
56879
57402
  value.withFieldName(key)
56880
57403
  ])));
@@ -58048,7 +58571,7 @@ var __create2, __defProp3, __getOwnPropDesc, __getOwnPropNames2, __getProtoOf2,
58048
58571
  __defProp3(to, key, { get: () => from[key], enumerable: !(desc2 = __getOwnPropDesc(from, key)) || desc2.enumerable });
58049
58572
  }
58050
58573
  return to;
58051
- }, __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) => {
58574
+ }, __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) => {
58052
58575
  const matchers = filters.map((it3) => {
58053
58576
  return new Minimatch(it3);
58054
58577
  });
@@ -61947,7 +62470,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
61947
62470
  en_default2 = errorMap2;
61948
62471
  }
61949
62472
  });
61950
- init_errors5 = __esm7({
62473
+ init_errors8 = __esm7({
61951
62474
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/errors.js"() {
61952
62475
  init_en2();
61953
62476
  overrideErrorMap2 = en_default2;
@@ -61955,7 +62478,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
61955
62478
  });
61956
62479
  init_parseUtil2 = __esm7({
61957
62480
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/helpers/parseUtil.js"() {
61958
- init_errors5();
62481
+ init_errors8();
61959
62482
  init_en2();
61960
62483
  makeIssue2 = (params) => {
61961
62484
  const { data, path: path2, errorMaps, issueData } = params;
@@ -62061,7 +62584,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
62061
62584
  init_types5 = __esm7({
62062
62585
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/types.js"() {
62063
62586
  init_ZodError2();
62064
- init_errors5();
62587
+ init_errors8();
62065
62588
  init_errorUtil2();
62066
62589
  init_parseUtil2();
62067
62590
  init_util2();
@@ -65219,7 +65742,7 @@ See: https://github.com/isaacs/node-glob/issues/167`);
65219
65742
  });
65220
65743
  init_external2 = __esm7({
65221
65744
  "../node_modules/.pnpm/zod@3.25.42/node_modules/zod/dist/esm/v3/external.js"() {
65222
- init_errors5();
65745
+ init_errors8();
65223
65746
  init_parseUtil2();
65224
65747
  init_typeAliases2();
65225
65748
  init_util2();
@@ -95881,7 +96404,7 @@ async function seedTimebackIntegrations(db2, gameId, courses) {
95881
96404
  const courseId = course.courseId || `mock-${course.subject.toLowerCase()}-g${course.grade}`;
95882
96405
  try {
95883
96406
  const existing = await db2.query.gameTimebackIntegrations.findFirst({
95884
- where: (table9, { and: and3, eq: eq3 }) => and3(eq3(table9.gameId, gameId), eq3(table9.grade, course.grade), eq3(table9.subject, course.subject))
96407
+ where: (table9, { and: and3, eq: eq3 }) => and3(eq3(table9.gameId, gameId), eq3(table9.grade, course.grade), eq3(table9.subject, course.subject), isActiveGameTimebackIntegrationStatus(table9.status))
95885
96408
  });
95886
96409
  if (!existing) {
95887
96410
  await db2.insert(gameTimebackIntegrations).values({
@@ -95901,6 +96424,7 @@ async function seedTimebackIntegrations(db2, gameId, courses) {
95901
96424
  return seededCount;
95902
96425
  }
95903
96426
  var init_timeback5 = __esm(() => {
96427
+ init_helpers_index();
95904
96428
  init_tables_index();
95905
96429
  init_config();
95906
96430
  });
@@ -97135,7 +97659,7 @@ var init_game_member_controller = __esm(() => {
97135
97659
  });
97136
97660
 
97137
97661
  // ../api-core/src/controllers/game.controller.ts
97138
- var list2, listAccessible, getSubjects, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove2, games2;
97662
+ var list2, listAccessible, getSubjects, getTimebackSummaries, getById, getBySlug, getManifest, upsertBySlug, patchGameMetadata, remove2, games2;
97139
97663
  var init_game_controller = __esm(() => {
97140
97664
  init_esm();
97141
97665
  init_schemas_index();
@@ -97144,6 +97668,7 @@ var init_game_controller = __esm(() => {
97144
97668
  list2 = requireNonAnonymous(async (ctx) => ctx.services.game.list(ctx.user));
97145
97669
  listAccessible = requireNonAnonymous(async (ctx) => ctx.services.game.listAccessible(ctx.user));
97146
97670
  getSubjects = requireNonAnonymous(async (ctx) => ctx.services.game.getSubjects());
97671
+ getTimebackSummaries = requireGameManagementAccess(async (ctx) => ctx.services.game.getTimebackSummaries(ctx.user));
97147
97672
  getById = requireNonAnonymous(async (ctx) => {
97148
97673
  const gameId = requireGameId(ctx.params.gameId);
97149
97674
  return ctx.services.game.getById(gameId, ctx.user);
@@ -97191,6 +97716,7 @@ var init_game_controller = __esm(() => {
97191
97716
  list: list2,
97192
97717
  listAccessible,
97193
97718
  getSubjects,
97719
+ getTimebackSummaries,
97194
97720
  getById,
97195
97721
  getManifest,
97196
97722
  getBySlug,
@@ -97582,7 +98108,7 @@ var init_session_controller = __esm(() => {
97582
98108
  });
97583
98109
 
97584
98110
  // ../api-core/src/controllers/timeback.controller.ts
97585
- 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;
98111
+ 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;
97586
98112
  var init_timeback_controller = __esm(() => {
97587
98113
  init_esm();
97588
98114
  init_schemas_index();
@@ -97638,6 +98164,27 @@ var init_timeback_controller = __esm(() => {
97638
98164
  }
97639
98165
  return ctx.services.timeback.getIntegrations(gameId, ctx.user);
97640
98166
  });
98167
+ getRemovedIntegrations = requireGameManagementAccess(async (ctx) => {
98168
+ const gameId = ctx.params.gameId;
98169
+ if (!gameId) {
98170
+ throw ApiError.badRequest("Missing gameId");
98171
+ }
98172
+ if (!isValidUUID(gameId)) {
98173
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98174
+ }
98175
+ return ctx.services.timeback.getRemovedIntegrations(gameId, ctx.user);
98176
+ });
98177
+ createIntegration = requireDeveloper(async (ctx) => {
98178
+ const gameId = ctx.params.gameId;
98179
+ if (!gameId) {
98180
+ throw ApiError.badRequest("Missing gameId");
98181
+ }
98182
+ if (!isValidUUID(gameId)) {
98183
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98184
+ }
98185
+ const body2 = await parseRequestBody(ctx.request, CreateGameTimebackIntegrationRequestSchema);
98186
+ return ctx.services.timeback.createIntegration(gameId, ctx.user, body2);
98187
+ });
97641
98188
  updateIntegration = requireDeveloper(async (ctx) => {
97642
98189
  const { gameId, courseId } = ctx.params;
97643
98190
  if (!gameId || !courseId) {
@@ -97649,6 +98196,26 @@ var init_timeback_controller = __esm(() => {
97649
98196
  const body2 = await parseRequestBody(ctx.request, UpdateGameTimebackIntegrationRequestSchema);
97650
98197
  return ctx.services.timeback.updateIntegration(gameId, courseId, ctx.user, body2);
97651
98198
  });
98199
+ deactivateCourse = requireDeveloper(async (ctx) => {
98200
+ const { gameId, courseId } = ctx.params;
98201
+ if (!gameId || !courseId) {
98202
+ throw ApiError.badRequest("Missing gameId or courseId parameter");
98203
+ }
98204
+ if (!isValidUUID(gameId)) {
98205
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98206
+ }
98207
+ return ctx.services.timeback.deactivateCourse(gameId, courseId, ctx.user);
98208
+ });
98209
+ reactivateCourse = requireDeveloper(async (ctx) => {
98210
+ const { gameId, courseId } = ctx.params;
98211
+ if (!gameId || !courseId) {
98212
+ throw ApiError.badRequest("Missing gameId or courseId parameter");
98213
+ }
98214
+ if (!isValidUUID(gameId)) {
98215
+ throw ApiError.unprocessableEntity("Invalid gameId format");
98216
+ }
98217
+ return ctx.services.timeback.reactivateCourse(gameId, courseId, ctx.user);
98218
+ });
97652
98219
  getIntegrationConfig = requireGameManagementAccess(async (ctx) => {
97653
98220
  const { gameId, courseId } = ctx.params;
97654
98221
  if (!gameId || !courseId) {
@@ -97798,11 +98365,11 @@ var init_timeback_controller = __esm(() => {
97798
98365
  let subject;
97799
98366
  if (gradeParam !== null && subjectParam !== null) {
97800
98367
  const parsedGrade = parseInt(gradeParam, 10);
97801
- if (!isTimebackGrade(parsedGrade)) {
98368
+ if (!isTimebackGrade2(parsedGrade)) {
97802
98369
  throw ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
97803
98370
  }
97804
- if (!isTimebackSubject(subjectParam)) {
97805
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98371
+ if (!isTimebackSubject2(subjectParam)) {
98372
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97806
98373
  }
97807
98374
  grade = parsedGrade;
97808
98375
  subject = subjectParam;
@@ -97838,11 +98405,11 @@ var init_timeback_controller = __esm(() => {
97838
98405
  let subject;
97839
98406
  if (gradeParam !== null && subjectParam !== null) {
97840
98407
  const parsedGrade = parseInt(gradeParam, 10);
97841
- if (!isTimebackGrade(parsedGrade)) {
98408
+ if (!isTimebackGrade2(parsedGrade)) {
97842
98409
  throw ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
97843
98410
  }
97844
- if (!isTimebackSubject(subjectParam)) {
97845
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98411
+ if (!isTimebackSubject2(subjectParam)) {
98412
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97846
98413
  }
97847
98414
  grade = parsedGrade;
97848
98415
  subject = subjectParam;
@@ -97872,8 +98439,8 @@ var init_timeback_controller = __esm(() => {
97872
98439
  if (!subjectParam) {
97873
98440
  throw ApiError.badRequest("Missing required subject query parameter");
97874
98441
  }
97875
- if (!isTimebackSubject(subjectParam)) {
97876
- throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
98442
+ if (!isTimebackSubject2(subjectParam)) {
98443
+ throw ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
97877
98444
  }
97878
98445
  return ctx.services.timeback.getStudentHighestGradeMastered(timebackId, ctx.user, {
97879
98446
  gameId,
@@ -98184,7 +98751,11 @@ var init_timeback_controller = __esm(() => {
98184
98751
  getUserById,
98185
98752
  setupIntegration,
98186
98753
  getIntegrations,
98754
+ getRemovedIntegrations,
98755
+ createIntegration,
98187
98756
  updateIntegration,
98757
+ deactivateCourse,
98758
+ reactivateCourse,
98188
98759
  getIntegrationConfig,
98189
98760
  verifyIntegration,
98190
98761
  getConfig,
@@ -99181,12 +99752,12 @@ var init_timeback7 = __esm(() => {
99181
99752
  }
99182
99753
  if (gradeParam !== null && subjectParam !== null) {
99183
99754
  const grade = parseInt(gradeParam, 10);
99184
- if (!Number.isFinite(grade) || !isTimebackGrade(grade)) {
99755
+ if (!Number.isFinite(grade) || !isTimebackGrade2(grade)) {
99185
99756
  const error2 = ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
99186
99757
  return c2.json(createErrorResponse(error2), error2.status);
99187
99758
  }
99188
- if (!isTimebackSubject(subjectParam)) {
99189
- const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99759
+ if (!isTimebackSubject2(subjectParam)) {
99760
+ const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99190
99761
  return c2.json(createErrorResponse(error2), error2.status);
99191
99762
  }
99192
99763
  enrollments = enrollments.filter((e) => e.grade === grade && e.subject === subjectParam);
@@ -99239,12 +99810,12 @@ var init_timeback7 = __esm(() => {
99239
99810
  }
99240
99811
  if (gradeParam !== null && subjectParam !== null) {
99241
99812
  const grade = parseInt(gradeParam, 10);
99242
- if (!Number.isFinite(grade) || !isTimebackGrade(grade)) {
99813
+ if (!Number.isFinite(grade) || !isTimebackGrade2(grade)) {
99243
99814
  const error2 = ApiError.badRequest(`Invalid grade: ${gradeParam}. Valid grades: ${TIMEBACK_GRADES.join(", ")}`);
99244
99815
  return c2.json(createErrorResponse(error2), error2.status);
99245
99816
  }
99246
- if (!isTimebackSubject(subjectParam)) {
99247
- const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99817
+ if (!isTimebackSubject2(subjectParam)) {
99818
+ const error2 = ApiError.badRequest(`Invalid subject: ${subjectParam}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99248
99819
  return c2.json(createErrorResponse(error2), error2.status);
99249
99820
  }
99250
99821
  enrollments = enrollments.filter((e) => e.grade === grade && e.subject === subjectParam);
@@ -99293,8 +99864,8 @@ var init_timeback7 = __esm(() => {
99293
99864
  const error2 = ApiError.badRequest("Missing required gameId query parameter");
99294
99865
  return c2.json(createErrorResponse(error2), error2.status);
99295
99866
  }
99296
- if (!isTimebackSubject(subject)) {
99297
- const error2 = ApiError.badRequest(`Invalid subject: ${subject}. Valid subjects: ${TIMEBACK_SUBJECTS.join(", ")}`);
99867
+ if (!isTimebackSubject2(subject)) {
99868
+ const error2 = ApiError.badRequest(`Invalid subject: ${subject}. Valid subjects: ${TIMEBACK_SUBJECTS2.join(", ")}`);
99298
99869
  return c2.json(createErrorResponse(error2), error2.status);
99299
99870
  }
99300
99871
  const db2 = c2.get("db");