@vue-skuilder/db 0.1.21 → 0.1.23

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/index.d.cts CHANGED
@@ -1,11 +1,11 @@
1
- import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource } from './contentSource-DsJadoBU.cjs';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, C as CourseDBInterface, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, V as DocumentUpdater, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview, X as newInterval } from './contentSource-DsJadoBU.cjs';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-DsJadoBU.cjs';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, V as DocumentUpdater, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview, X as newInterval } from './contentSource-DsJadoBU.cjs';
3
3
  import { D as DataLayerProvider } from './dataLayerProvider-CHYrQ5pB.cjs';
4
4
  import { C as CardHistory, c as CardRecord } from './types-legacy-DDY4N-Uq.cjs';
5
5
  export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-DDY4N-Uq.cjs';
6
6
  import { Loggable } from './core/index.cjs';
7
7
  export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, GeneratorContext, ImportResult, StrategyStateDoc, StrategyStateId, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig } from './core/index.cjs';
8
- import { TagFilter } from '@vue-skuilder/common';
8
+ import { TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
9
9
  import { S as StaticCourseManifest } from './types-Bn0itutr.cjs';
10
10
  export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-Bn0itutr.cjs';
11
11
  import { F as FileSystemAdapter } from './index-B_j6u5E4.cjs';
@@ -529,6 +529,119 @@ declare class CourseLookup {
529
529
  static isCourse(courseID: string): Promise<boolean>;
530
530
  }
531
531
 
532
+ /**
533
+ * Interface for custom questions data structure returned by allCustomQuestions()
534
+ */
535
+ interface CustomQuestionsData {
536
+ courses: {
537
+ name: string;
538
+ }[];
539
+ questionClasses: {
540
+ name: string;
541
+ dataShapes?: DataShape[];
542
+ views?: {
543
+ name?: string;
544
+ }[];
545
+ seedData?: unknown[];
546
+ }[];
547
+ dataShapes: DataShape[];
548
+ views: {
549
+ name?: string;
550
+ }[];
551
+ meta: {
552
+ questionCount: number;
553
+ dataShapeCount: number;
554
+ viewCount: number;
555
+ courseCount: number;
556
+ packageName: string;
557
+ sourceDirectory: string;
558
+ };
559
+ }
560
+ /**
561
+ * Interface for processed question data for registration
562
+ */
563
+ interface ProcessedQuestionData {
564
+ name: string;
565
+ course: string;
566
+ questionClass: {
567
+ name: string;
568
+ dataShapes?: DataShape[];
569
+ views?: {
570
+ name?: string;
571
+ }[];
572
+ seedData?: unknown[];
573
+ };
574
+ dataShapes: DataShape[];
575
+ views: {
576
+ name?: string;
577
+ }[];
578
+ }
579
+ /**
580
+ * Interface for processed data shape for registration
581
+ */
582
+ interface ProcessedDataShape {
583
+ name: string;
584
+ course: string;
585
+ dataShape: DataShape;
586
+ }
587
+ /**
588
+ * Check if a data shape is already registered in the course config with valid schema
589
+ */
590
+ declare function isDataShapeRegistered(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
591
+ declare function isDataShapeSchemaAvailable(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
592
+ /**
593
+ * Check if a question type is already registered in the course config
594
+ */
595
+ declare function isQuestionTypeRegistered(question: ProcessedQuestionData, courseConfig: CourseConfig): boolean;
596
+ /**
597
+ * Process custom questions data into registration-ready format
598
+ */
599
+ declare function processCustomQuestionsData(customQuestions: CustomQuestionsData): {
600
+ dataShapes: ProcessedDataShape[];
601
+ questions: ProcessedQuestionData[];
602
+ };
603
+ /**
604
+ * Register a data shape in the course config
605
+ */
606
+ declare function registerDataShape(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
607
+ /**
608
+ * Register a question type in the course config
609
+ */
610
+ declare function registerQuestionType(question: ProcessedQuestionData, courseConfig: CourseConfig): boolean;
611
+ /**
612
+ * Register seed data for a question type
613
+ *
614
+ * @param question - The processed question data
615
+ * @param courseDB - The course database interface
616
+ * @param username - The username to attribute seed data to
617
+ */
618
+ declare function registerSeedData(question: ProcessedQuestionData, courseDB: CourseDBInterface, username: string): Promise<void>;
619
+ /**
620
+ * Register BlanksCard (markdown fillIn) question type specifically
621
+ */
622
+ declare function registerBlanksCard(BlanksCard: {
623
+ name: string;
624
+ views?: {
625
+ name?: string;
626
+ }[];
627
+ }, BlanksCardDataShapes: DataShape[], courseConfig: CourseConfig, courseDB: CourseDBInterface, username?: string): Promise<{
628
+ success: boolean;
629
+ errorMessage?: string;
630
+ }>;
631
+ /**
632
+ * Main function to register all custom question types and data shapes
633
+ *
634
+ * @param customQuestions - The custom questions data from allCustomQuestions()
635
+ * @param courseConfig - The course configuration object
636
+ * @param courseDB - The course database interface
637
+ * @param username - The username to attribute seed data to
638
+ */
639
+ declare function registerCustomQuestionTypes(customQuestions: CustomQuestionsData, courseConfig: CourseConfig, courseDB: CourseDBInterface, username?: string): Promise<{
640
+ success: boolean;
641
+ registeredCount: number;
642
+ errorMessage?: string;
643
+ }>;
644
+
532
645
  declare const NOT_SET: "NOT_SET";
533
646
  interface DBEnv {
534
647
  COUCHDB_SERVER_URL: string;
@@ -585,4 +698,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
585
698
  entitlements: UserEntitlements;
586
699
  }
587
700
 
588
- export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, CardRecord, type CouchDbUserDoc, CourseLookup, CourseRegistrationDoc, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, NOT_SET, QuotaRoundRobinMixer, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SourceBatch, type SourceMixer, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, validateMigration, validateStaticCourse };
701
+ export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, QuotaRoundRobinMixer, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SourceBatch, type SourceMixer, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, processCustomQuestionsData, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, validateMigration, validateStaticCourse };
package/dist/index.d.ts CHANGED
@@ -1,11 +1,11 @@
1
- import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource } from './contentSource-BP9hznNV.js';
2
- export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, C as CourseDBInterface, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, V as DocumentUpdater, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview, X as newInterval } from './contentSource-BP9hznNV.js';
1
+ import { U as UserDBInterface, s as CourseRegistrationDoc, S as StudySessionItem, W as WeightedCard, h as StudyContentSource, C as CourseDBInterface } from './contentSource-BP9hznNV.js';
2
+ export { J as ActivityRecord, A as AdminDBInterface, v as AssignedCard, g as AssignedContent, u as AssignedCourse, t as AssignedTag, c as ClassroomDBInterface, F as ClassroomRegistration, E as ClassroomRegistrationDesignation, G as ClassroomRegistrationDoc, f as ContentNavigator, q as ContentSourceID, d as CourseInfo, K as CourseRegistration, b as CoursesDBInterface, V as DocumentUpdater, O as NavigatorRole, P as NavigatorRoles, N as Navigators, j as ScheduledCard, H as SessionTrackingData, L as StrategyContribution, i as StudentClassroomDBInterface, k as StudySessionFailedItem, l as StudySessionFailedNewItem, m as StudySessionFailedReviewItem, n as StudySessionNewItem, o as StudySessionReviewItem, T as TeacherClassroomDBInterface, I as UserConfig, z as UserCourseSetting, y as UserCourseSettings, x as UserDBAuthenticator, a as UserDBReader, w as UserDBWriter, B as UsrCrsDataInterface, M as getCardOrigin, r as getStudySource, R as isFilter, Q as isGenerator, p as isReview, X as newInterval } from './contentSource-BP9hznNV.js';
3
3
  import { D as DataLayerProvider } from './dataLayerProvider-MDTxXq2l.js';
4
4
  import { C as CardHistory, c as CardRecord } from './types-legacy-DDY4N-Uq.js';
5
5
  export { d as CardData, e as CourseListData, g as DataShapeData, f as DisplayableData, D as DocType, b as DocTypePrefixes, F as Field, G as GuestUsername, Q as QualifiedCardID, h as QuestionData, i as QuestionRecord, S as SkuilderCourseData, a as Tag, T as TagStub, l as log } from './types-legacy-DDY4N-Uq.js';
6
6
  import { Loggable } from './core/index.js';
7
7
  export { BulkCardProcessorConfig, CardFilter, CardFilterFactory, CardGenerator, CardGeneratorFactory, FilterContext, GeneratorContext, ImportResult, StrategyStateDoc, StrategyStateId, areQuestionRecords, buildStrategyStateId, docIsDeleted, getCardHistoryID, importParsedCards, isQuestionRecord, parseCardHistoryID, validateProcessorConfig } from './core/index.js';
8
- import { TagFilter } from '@vue-skuilder/common';
8
+ import { TagFilter, DataShape, CourseConfig } from '@vue-skuilder/common';
9
9
  import { S as StaticCourseManifest } from './types-DQaXnuoc.js';
10
10
  export { A as AttachmentData, C as ChunkMetadata, D as DesignDocument, I as IndexMetadata, a as PackedCourseData, P as PackerConfig } from './types-DQaXnuoc.js';
11
11
  import { F as FileSystemAdapter } from './index-Dj0SEgk3.js';
@@ -529,6 +529,119 @@ declare class CourseLookup {
529
529
  static isCourse(courseID: string): Promise<boolean>;
530
530
  }
531
531
 
532
+ /**
533
+ * Interface for custom questions data structure returned by allCustomQuestions()
534
+ */
535
+ interface CustomQuestionsData {
536
+ courses: {
537
+ name: string;
538
+ }[];
539
+ questionClasses: {
540
+ name: string;
541
+ dataShapes?: DataShape[];
542
+ views?: {
543
+ name?: string;
544
+ }[];
545
+ seedData?: unknown[];
546
+ }[];
547
+ dataShapes: DataShape[];
548
+ views: {
549
+ name?: string;
550
+ }[];
551
+ meta: {
552
+ questionCount: number;
553
+ dataShapeCount: number;
554
+ viewCount: number;
555
+ courseCount: number;
556
+ packageName: string;
557
+ sourceDirectory: string;
558
+ };
559
+ }
560
+ /**
561
+ * Interface for processed question data for registration
562
+ */
563
+ interface ProcessedQuestionData {
564
+ name: string;
565
+ course: string;
566
+ questionClass: {
567
+ name: string;
568
+ dataShapes?: DataShape[];
569
+ views?: {
570
+ name?: string;
571
+ }[];
572
+ seedData?: unknown[];
573
+ };
574
+ dataShapes: DataShape[];
575
+ views: {
576
+ name?: string;
577
+ }[];
578
+ }
579
+ /**
580
+ * Interface for processed data shape for registration
581
+ */
582
+ interface ProcessedDataShape {
583
+ name: string;
584
+ course: string;
585
+ dataShape: DataShape;
586
+ }
587
+ /**
588
+ * Check if a data shape is already registered in the course config with valid schema
589
+ */
590
+ declare function isDataShapeRegistered(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
591
+ declare function isDataShapeSchemaAvailable(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
592
+ /**
593
+ * Check if a question type is already registered in the course config
594
+ */
595
+ declare function isQuestionTypeRegistered(question: ProcessedQuestionData, courseConfig: CourseConfig): boolean;
596
+ /**
597
+ * Process custom questions data into registration-ready format
598
+ */
599
+ declare function processCustomQuestionsData(customQuestions: CustomQuestionsData): {
600
+ dataShapes: ProcessedDataShape[];
601
+ questions: ProcessedQuestionData[];
602
+ };
603
+ /**
604
+ * Register a data shape in the course config
605
+ */
606
+ declare function registerDataShape(dataShape: ProcessedDataShape, courseConfig: CourseConfig): boolean;
607
+ /**
608
+ * Register a question type in the course config
609
+ */
610
+ declare function registerQuestionType(question: ProcessedQuestionData, courseConfig: CourseConfig): boolean;
611
+ /**
612
+ * Register seed data for a question type
613
+ *
614
+ * @param question - The processed question data
615
+ * @param courseDB - The course database interface
616
+ * @param username - The username to attribute seed data to
617
+ */
618
+ declare function registerSeedData(question: ProcessedQuestionData, courseDB: CourseDBInterface, username: string): Promise<void>;
619
+ /**
620
+ * Register BlanksCard (markdown fillIn) question type specifically
621
+ */
622
+ declare function registerBlanksCard(BlanksCard: {
623
+ name: string;
624
+ views?: {
625
+ name?: string;
626
+ }[];
627
+ }, BlanksCardDataShapes: DataShape[], courseConfig: CourseConfig, courseDB: CourseDBInterface, username?: string): Promise<{
628
+ success: boolean;
629
+ errorMessage?: string;
630
+ }>;
631
+ /**
632
+ * Main function to register all custom question types and data shapes
633
+ *
634
+ * @param customQuestions - The custom questions data from allCustomQuestions()
635
+ * @param courseConfig - The course configuration object
636
+ * @param courseDB - The course database interface
637
+ * @param username - The username to attribute seed data to
638
+ */
639
+ declare function registerCustomQuestionTypes(customQuestions: CustomQuestionsData, courseConfig: CourseConfig, courseDB: CourseDBInterface, username?: string): Promise<{
640
+ success: boolean;
641
+ registeredCount: number;
642
+ errorMessage?: string;
643
+ }>;
644
+
532
645
  declare const NOT_SET: "NOT_SET";
533
646
  interface DBEnv {
534
647
  COUCHDB_SERVER_URL: string;
@@ -585,4 +698,4 @@ interface CouchDbUserDoc extends PouchDB.Authentication.User {
585
698
  entitlements: UserEntitlements;
586
699
  }
587
700
 
588
- export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, CardRecord, type CouchDbUserDoc, CourseLookup, CourseRegistrationDoc, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, NOT_SET, QuotaRoundRobinMixer, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SourceBatch, type SourceMixer, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, validateMigration, validateStaticCourse };
701
+ export { type AggregatedDocument, type AttachmentUploadResult, CardHistory, CardRecord, type CouchDbUserDoc, CourseDBInterface, CourseLookup, CourseRegistrationDoc, type CustomQuestionsData, DEFAULT_MIGRATION_OPTIONS, type DataLayerConfig, DataLayerProvider, type DocumentCounts, ENV, type Entitlement, FileSystemAdapter, Loggable, type MigrationOptions, type MigrationResult, NOT_SET, type ProcessedDataShape, type ProcessedQuestionData, QuotaRoundRobinMixer, type ResponseResult, type RestoreProgress, type SessionAction, SessionController, type SourceBatch, type SourceMixer, StaticCourseManifest, type StaticCourseValidation, StaticToCouchDBMigrator, StudyContentSource, StudySessionItem, type StudySessionRecord, TagFilteredContentSource, type UserAccountStatus, UserDBInterface, type UserEntitlements, type ValidationIssue, type ValidationResult, WeightedCard, _resetDataLayer, ensureAppDataDirectory, getAppDataDirectory, getDataLayer, getDbPath, initializeDataDirectory, initializeDataLayer, isDataShapeRegistered, isDataShapeSchemaAvailable, isQuestionTypeRegistered, processCustomQuestionsData, registerBlanksCard, registerCustomQuestionTypes, registerDataShape, registerQuestionType, registerSeedData, validateMigration, validateStaticCourse };
package/dist/index.js CHANGED
@@ -5758,13 +5758,22 @@ __export(index_exports, {
5758
5758
  importParsedCards: () => importParsedCards,
5759
5759
  initializeDataDirectory: () => initializeDataDirectory,
5760
5760
  initializeDataLayer: () => initializeDataLayer,
5761
+ isDataShapeRegistered: () => isDataShapeRegistered,
5762
+ isDataShapeSchemaAvailable: () => isDataShapeSchemaAvailable,
5761
5763
  isFilter: () => isFilter,
5762
5764
  isGenerator: () => isGenerator,
5763
5765
  isQuestionRecord: () => isQuestionRecord,
5766
+ isQuestionTypeRegistered: () => isQuestionTypeRegistered,
5764
5767
  isReview: () => isReview,
5765
5768
  log: () => log,
5766
5769
  newInterval: () => newInterval,
5767
5770
  parseCardHistoryID: () => parseCardHistoryID,
5771
+ processCustomQuestionsData: () => processCustomQuestionsData,
5772
+ registerBlanksCard: () => registerBlanksCard,
5773
+ registerCustomQuestionTypes: () => registerCustomQuestionTypes,
5774
+ registerDataShape: () => registerDataShape,
5775
+ registerQuestionType: () => registerQuestionType,
5776
+ registerSeedData: () => registerSeedData,
5768
5777
  validateMigration: () => validateMigration,
5769
5778
  validateProcessorConfig: () => validateProcessorConfig,
5770
5779
  validateStaticCourse: () => validateStaticCourse
@@ -5773,6 +5782,251 @@ module.exports = __toCommonJS(index_exports);
5773
5782
  init_core();
5774
5783
  init_courseLookupDB();
5775
5784
 
5785
+ // src/courseConfigRegistration.ts
5786
+ var import_common19 = require("@vue-skuilder/common");
5787
+ init_logger();
5788
+ function isDataShapeRegistered(dataShape, courseConfig) {
5789
+ const namespacedName = import_common19.NameSpacer.getDataShapeString({
5790
+ dataShape: dataShape.name,
5791
+ course: dataShape.course
5792
+ });
5793
+ const existingDataShape = courseConfig.dataShapes.find((ds) => ds.name === namespacedName);
5794
+ return existingDataShape !== void 0;
5795
+ }
5796
+ function isDataShapeSchemaAvailable(dataShape, courseConfig) {
5797
+ const namespacedName = import_common19.NameSpacer.getDataShapeString({
5798
+ dataShape: dataShape.name,
5799
+ course: dataShape.course
5800
+ });
5801
+ const existingDataShape = courseConfig.dataShapes.find((ds) => ds.name === namespacedName);
5802
+ return existingDataShape !== void 0 && existingDataShape.serializedZodSchema !== void 0;
5803
+ }
5804
+ function isQuestionTypeRegistered(question, courseConfig) {
5805
+ const namespacedName = import_common19.NameSpacer.getQuestionString({
5806
+ course: question.course,
5807
+ questionType: question.name
5808
+ });
5809
+ return courseConfig.questionTypes.some((qt) => qt.name === namespacedName);
5810
+ }
5811
+ function processCustomQuestionsData(customQuestions) {
5812
+ const processedDataShapes = [];
5813
+ const processedQuestions = [];
5814
+ const courseNames = customQuestions.courses.map((course) => course.name);
5815
+ customQuestions.questionClasses.forEach((questionClass) => {
5816
+ const courseName = courseNames.length > 0 ? courseNames[0] : customQuestions.meta.packageName;
5817
+ if (questionClass.dataShapes && Array.isArray(questionClass.dataShapes)) {
5818
+ questionClass.dataShapes.forEach((dataShape) => {
5819
+ processedDataShapes.push({
5820
+ name: dataShape.name,
5821
+ course: courseName,
5822
+ dataShape
5823
+ });
5824
+ });
5825
+ }
5826
+ processedQuestions.push({
5827
+ name: questionClass.name,
5828
+ course: courseName,
5829
+ questionClass,
5830
+ dataShapes: questionClass.dataShapes || [],
5831
+ views: questionClass.views || []
5832
+ });
5833
+ });
5834
+ return { dataShapes: processedDataShapes, questions: processedQuestions };
5835
+ }
5836
+ function registerDataShape(dataShape, courseConfig) {
5837
+ const namespacedName = import_common19.NameSpacer.getDataShapeString({
5838
+ dataShape: dataShape.name,
5839
+ course: dataShape.course
5840
+ });
5841
+ let serializedZodSchema;
5842
+ try {
5843
+ serializedZodSchema = (0, import_common19.toZodJSON)(dataShape.dataShape);
5844
+ } catch (error) {
5845
+ logger.warn(`Failed to generate schema for ${namespacedName}:`, error);
5846
+ serializedZodSchema = void 0;
5847
+ }
5848
+ const existingIndex = courseConfig.dataShapes.findIndex((ds) => ds.name === namespacedName);
5849
+ if (existingIndex !== -1) {
5850
+ const existingDataShape = courseConfig.dataShapes[existingIndex];
5851
+ if (existingDataShape.serializedZodSchema === serializedZodSchema) {
5852
+ logger.info(
5853
+ `DataShape '${dataShape.name}' from '${dataShape.course}' already registered with identical schema`
5854
+ );
5855
+ return false;
5856
+ }
5857
+ if (existingDataShape.serializedZodSchema) {
5858
+ logger.info(
5859
+ `DataShape '${dataShape.name}' from '${dataShape.course}' schema has changed, updating...`
5860
+ );
5861
+ } else {
5862
+ logger.info(
5863
+ `DataShape '${dataShape.name}' from '${dataShape.course}' already registered, but with no schema. Adding schema to existing entry`
5864
+ );
5865
+ }
5866
+ courseConfig.dataShapes[existingIndex] = {
5867
+ name: namespacedName,
5868
+ questionTypes: existingDataShape.questionTypes,
5869
+ // Preserve existing question type associations
5870
+ serializedZodSchema
5871
+ };
5872
+ logger.info(`Updated DataShape: ${namespacedName}`);
5873
+ return true;
5874
+ }
5875
+ courseConfig.dataShapes.push({
5876
+ name: namespacedName,
5877
+ questionTypes: [],
5878
+ serializedZodSchema
5879
+ });
5880
+ logger.info(`Registered DataShape: ${namespacedName}`);
5881
+ return true;
5882
+ }
5883
+ function registerQuestionType(question, courseConfig) {
5884
+ if (isQuestionTypeRegistered(question, courseConfig)) {
5885
+ logger.info(`QuestionType '${question.name}' from '${question.course}' already registered`);
5886
+ return false;
5887
+ }
5888
+ const namespacedQuestionName = import_common19.NameSpacer.getQuestionString({
5889
+ course: question.course,
5890
+ questionType: question.name
5891
+ });
5892
+ const viewList = question.views.map((view) => {
5893
+ if (view.name) {
5894
+ return view.name;
5895
+ } else {
5896
+ return "unnamedComponent";
5897
+ }
5898
+ });
5899
+ const dataShapeList = question.dataShapes.map(
5900
+ (dataShape) => import_common19.NameSpacer.getDataShapeString({
5901
+ course: question.course,
5902
+ dataShape: dataShape.name
5903
+ })
5904
+ );
5905
+ courseConfig.questionTypes.push({
5906
+ name: namespacedQuestionName,
5907
+ viewList,
5908
+ dataShapeList
5909
+ });
5910
+ question.dataShapes.forEach((dataShape) => {
5911
+ const namespacedDataShapeName = import_common19.NameSpacer.getDataShapeString({
5912
+ course: question.course,
5913
+ dataShape: dataShape.name
5914
+ });
5915
+ for (const ds of courseConfig.dataShapes) {
5916
+ if (ds.name === namespacedDataShapeName) {
5917
+ ds.questionTypes.push(namespacedQuestionName);
5918
+ }
5919
+ }
5920
+ });
5921
+ logger.info(`Registered QuestionType: ${namespacedQuestionName}`);
5922
+ return true;
5923
+ }
5924
+ async function registerSeedData(question, courseDB, username) {
5925
+ if (question.questionClass.seedData && Array.isArray(question.questionClass.seedData)) {
5926
+ logger.info(`Registering seed data for question: ${question.name}`);
5927
+ try {
5928
+ const seedDataPromises = question.questionClass.seedData.filter(() => question.dataShapes.length > 0).map(
5929
+ (seedDataItem) => courseDB.addNote(
5930
+ question.course,
5931
+ question.dataShapes[0],
5932
+ seedDataItem,
5933
+ username,
5934
+ []
5935
+ )
5936
+ );
5937
+ await Promise.all(seedDataPromises);
5938
+ logger.info(`Seed data registered for question: ${question.name}`);
5939
+ } catch (error) {
5940
+ logger.warn(
5941
+ `Failed to register seed data for question '${question.name}': ${error instanceof Error ? error.message : String(error)}`
5942
+ );
5943
+ }
5944
+ }
5945
+ }
5946
+ async function registerBlanksCard(BlanksCard, BlanksCardDataShapes, courseConfig, courseDB, username) {
5947
+ try {
5948
+ logger.info("Registering BlanksCard data shapes and question type...");
5949
+ let registeredCount = 0;
5950
+ const courseName = "default";
5951
+ for (const dataShapeClass of BlanksCardDataShapes) {
5952
+ const processedDataShape = {
5953
+ name: dataShapeClass.name,
5954
+ course: courseName,
5955
+ dataShape: dataShapeClass
5956
+ };
5957
+ if (registerDataShape(processedDataShape, courseConfig)) {
5958
+ registeredCount++;
5959
+ }
5960
+ }
5961
+ const processedQuestion = {
5962
+ name: BlanksCard.name,
5963
+ course: courseName,
5964
+ questionClass: {
5965
+ name: BlanksCard.name,
5966
+ dataShapes: BlanksCardDataShapes,
5967
+ views: BlanksCard.views || []
5968
+ },
5969
+ dataShapes: BlanksCardDataShapes,
5970
+ views: BlanksCard.views || []
5971
+ };
5972
+ if (registerQuestionType(processedQuestion, courseConfig)) {
5973
+ registeredCount++;
5974
+ }
5975
+ logger.info("Updating course configuration with BlanksCard...");
5976
+ const updateResult = await courseDB.updateCourseConfig(courseConfig);
5977
+ if (!updateResult.ok) {
5978
+ throw new Error(`Failed to update course config: ${JSON.stringify(updateResult)}`);
5979
+ }
5980
+ if (username) {
5981
+ await registerSeedData(processedQuestion, courseDB, username);
5982
+ }
5983
+ logger.info(`BlanksCard registration complete: ${registeredCount} items registered`);
5984
+ return { success: true };
5985
+ } catch (error) {
5986
+ const errorMessage = error instanceof Error ? error.message : String(error);
5987
+ logger.error(`BlanksCard registration failed: ${errorMessage}`);
5988
+ return { success: false, errorMessage };
5989
+ }
5990
+ }
5991
+ async function registerCustomQuestionTypes(customQuestions, courseConfig, courseDB, username) {
5992
+ try {
5993
+ logger.info("Beginning custom question registration");
5994
+ logger.info(`Processing ${customQuestions.questionClasses.length} question classes`);
5995
+ const { dataShapes, questions } = processCustomQuestionsData(customQuestions);
5996
+ logger.info(`Found ${dataShapes.length} data shapes and ${questions.length} questions`);
5997
+ let registeredCount = 0;
5998
+ logger.info("Registering data shapes...");
5999
+ for (const dataShape of dataShapes) {
6000
+ if (registerDataShape(dataShape, courseConfig)) {
6001
+ registeredCount++;
6002
+ }
6003
+ }
6004
+ logger.info("Registering question types...");
6005
+ for (const question of questions) {
6006
+ if (registerQuestionType(question, courseConfig)) {
6007
+ registeredCount++;
6008
+ }
6009
+ }
6010
+ logger.info("Updating course configuration...");
6011
+ const updateResult = await courseDB.updateCourseConfig(courseConfig);
6012
+ if (!updateResult.ok) {
6013
+ throw new Error(`Failed to update course config: ${JSON.stringify(updateResult)}`);
6014
+ }
6015
+ if (username) {
6016
+ logger.info("Registering seed data...");
6017
+ for (const question of questions) {
6018
+ await registerSeedData(question, courseDB, username);
6019
+ }
6020
+ }
6021
+ logger.info(`Custom question registration complete: ${registeredCount} items registered`);
6022
+ return { success: true, registeredCount };
6023
+ } catch (error) {
6024
+ const errorMessage = error instanceof Error ? error.message : String(error);
6025
+ logger.error(`Custom question registration failed: ${errorMessage}`);
6026
+ return { success: false, registeredCount: 0, errorMessage };
6027
+ }
6028
+ }
6029
+
5776
6030
  // src/study/services/SrsService.ts
5777
6031
  var import_moment8 = __toESM(require("moment"), 1);
5778
6032
  init_couch();
@@ -5883,7 +6137,7 @@ var SrsService = class {
5883
6137
  };
5884
6138
 
5885
6139
  // src/study/services/EloService.ts
5886
- var import_common19 = require("@vue-skuilder/common");
6140
+ var import_common20 = require("@vue-skuilder/common");
5887
6141
  init_logger();
5888
6142
  var EloService = class {
5889
6143
  dataLayer;
@@ -5906,10 +6160,10 @@ var EloService = class {
5906
6160
  logger.warn(`k value interpretation not currently implemented`);
5907
6161
  }
5908
6162
  const courseDB = this.dataLayer.getCourseDB(currentCard.card.course_id);
5909
- const userElo = (0, import_common19.toCourseElo)(userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo);
6163
+ const userElo = (0, import_common20.toCourseElo)(userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo);
5910
6164
  const cardElo = (await courseDB.getCardEloData([currentCard.card.card_id]))[0];
5911
6165
  if (cardElo && userElo) {
5912
- const eloUpdate = (0, import_common19.adjustCourseScores)(userElo, cardElo, userScore);
6166
+ const eloUpdate = (0, import_common20.adjustCourseScores)(userElo, cardElo, userScore);
5913
6167
  userCourseRegDoc.courses.find((c) => c.courseID === course_id).elo = eloUpdate.userElo;
5914
6168
  const results = await Promise.allSettled([
5915
6169
  this.user.updateUserElo(course_id, eloUpdate.userElo),
@@ -6111,7 +6365,7 @@ var ResponseProcessor = class {
6111
6365
  };
6112
6366
 
6113
6367
  // src/study/services/CardHydrationService.ts
6114
- var import_common20 = require("@vue-skuilder/common");
6368
+ var import_common21 = require("@vue-skuilder/common");
6115
6369
  init_logger();
6116
6370
  function parseAudioURIs(data) {
6117
6371
  if (typeof data !== "string") return [];
@@ -6246,8 +6500,8 @@ var CardHydrationService = class {
6246
6500
  try {
6247
6501
  const courseDB = this.getCourseDB(item.courseID);
6248
6502
  const cardData = await courseDB.getCourseDoc(item.cardID);
6249
- if (!(0, import_common20.isCourseElo)(cardData.elo)) {
6250
- cardData.elo = (0, import_common20.toCourseElo)(cardData.elo);
6503
+ if (!(0, import_common21.isCourseElo)(cardData.elo)) {
6504
+ cardData.elo = (0, import_common21.toCourseElo)(cardData.elo);
6251
6505
  }
6252
6506
  const view = this.getViewComponent(cardData.id_view);
6253
6507
  const dataDocs = await Promise.all(
@@ -6271,7 +6525,7 @@ var CardHydrationService = class {
6271
6525
  );
6272
6526
  await Promise.allSettled(uniqueAudioUrls.map(prefetchAudio));
6273
6527
  }
6274
- const data = dataDocs.map(import_common20.displayableDataToViewData).reverse();
6528
+ const data = dataDocs.map(import_common21.displayableDataToViewData).reverse();
6275
6529
  this.hydratedCards.set(item.cardID, {
6276
6530
  item,
6277
6531
  view,
@@ -8219,13 +8473,22 @@ init_factory();
8219
8473
  importParsedCards,
8220
8474
  initializeDataDirectory,
8221
8475
  initializeDataLayer,
8476
+ isDataShapeRegistered,
8477
+ isDataShapeSchemaAvailable,
8222
8478
  isFilter,
8223
8479
  isGenerator,
8224
8480
  isQuestionRecord,
8481
+ isQuestionTypeRegistered,
8225
8482
  isReview,
8226
8483
  log,
8227
8484
  newInterval,
8228
8485
  parseCardHistoryID,
8486
+ processCustomQuestionsData,
8487
+ registerBlanksCard,
8488
+ registerCustomQuestionTypes,
8489
+ registerDataShape,
8490
+ registerQuestionType,
8491
+ registerSeedData,
8229
8492
  validateMigration,
8230
8493
  validateProcessorConfig,
8231
8494
  validateStaticCourse