@edpire/sdk 0.6.5 → 0.6.7
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/README.md +2 -2
- package/bin/create.js +0 -0
- package/dist/core.d.mts +149 -0
- package/dist/core.mjs +1 -0
- package/dist/index.mjs +8 -8
- package/dist/react.mjs +9 -9
- package/dist/umd/index.global.js +1 -1
- package/package.json +15 -10
- package/src/styles/shell.css +1 -1
- /package/dist/{dist-3D2JPDV3.mjs → dist-UCCG7PHU.mjs} +0 -0
package/README.md
CHANGED
|
@@ -90,7 +90,7 @@ embed.unmount()
|
|
|
90
90
|
**CDN (no bundler):**
|
|
91
91
|
|
|
92
92
|
```html
|
|
93
|
-
<script src="https://cdn.jsdelivr.net/npm/@edpire/sdk@0.6.
|
|
93
|
+
<script src="https://cdn.jsdelivr.net/npm/@edpire/sdk@0.6.7/dist/umd/index.global.js"></script>
|
|
94
94
|
<script>
|
|
95
95
|
EdpireSDK.EdpireAssessment.mount({ token, container: "#root", onComplete: handleDone })
|
|
96
96
|
</script>
|
|
@@ -310,7 +310,7 @@ The integration uses two parts:
|
|
|
310
310
|
</head>
|
|
311
311
|
<body>
|
|
312
312
|
<div id="root"></div>
|
|
313
|
-
<script src="https://cdn.jsdelivr.net/npm/@edpire/sdk@0.6.
|
|
313
|
+
<script src="https://cdn.jsdelivr.net/npm/@edpire/sdk@0.6.7/dist/umd/index.global.js"></script>
|
|
314
314
|
<script>
|
|
315
315
|
EdpireSDK.EdpireAssessment.mount({
|
|
316
316
|
token: "{{EMBED_TOKEN}}", // replace server-side before loading
|
package/bin/create.js
CHANGED
|
File without changes
|
package/dist/core.d.mts
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
import { RuntimeAnswer } from '@youssefalmia/edpire-runtime';
|
|
2
|
+
|
|
3
|
+
/** Flat per-question answer collected during a custom player session. */
|
|
4
|
+
interface StoredAnswer {
|
|
5
|
+
/** Exercise ID — from the `exerciseId` field on each `FlatStep`. */
|
|
6
|
+
exerciseId: string;
|
|
7
|
+
/** Question ID — from the `questionId` field on each `FlatStep`. */
|
|
8
|
+
questionId: string;
|
|
9
|
+
/** Answers collected from `EdpireQuestion`'s `onAnswersChange` callback. */
|
|
10
|
+
answers: RuntimeAnswer[];
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Convert a flat array of per-question answers into the nested structure
|
|
14
|
+
* expected by `EdpireClient.submit()` and `POST /api/v1/assessments/{id}/submit`.
|
|
15
|
+
*
|
|
16
|
+
* This is the bridge between the simple flat collection pattern used in custom
|
|
17
|
+
* players and the grouped format the API requires.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { flattenAssessment, buildSubmitPayload } from "@edpire/sdk"
|
|
22
|
+
* import type { StoredAnswer } from "@edpire/sdk"
|
|
23
|
+
*
|
|
24
|
+
* const stored: StoredAnswer[] = []
|
|
25
|
+
*
|
|
26
|
+
* // During the session, after each question:
|
|
27
|
+
* stored.push({ exerciseId: step.exerciseId, questionId: step.questionId, answers })
|
|
28
|
+
*
|
|
29
|
+
* // At the end, submit:
|
|
30
|
+
* const payload = buildSubmitPayload(stored)
|
|
31
|
+
* await client.submit(assessmentId, { learner_ref: userId, answers: payload })
|
|
32
|
+
*
|
|
33
|
+
* // Or pass the flat array directly — client.submit() accepts both formats:
|
|
34
|
+
* await client.submit(assessmentId, { learner_ref: userId, answers: stored })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function buildSubmitPayload(stored: StoredAnswer[]): {
|
|
38
|
+
exerciseAnswers: Array<{
|
|
39
|
+
exerciseId: string;
|
|
40
|
+
questionAnswers: Array<{
|
|
41
|
+
questionId: string;
|
|
42
|
+
answers: RuntimeAnswer[];
|
|
43
|
+
}>;
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* @edpire/sdk/client — Server-side API client for Edpire.
|
|
49
|
+
*
|
|
50
|
+
* Node.js only. Zero browser dependencies. Uses native fetch (Node 18+).
|
|
51
|
+
*
|
|
52
|
+
* @example
|
|
53
|
+
* ```typescript
|
|
54
|
+
* import { EdpireClient } from "@edpire/sdk/client"
|
|
55
|
+
*
|
|
56
|
+
* const client = new EdpireClient({
|
|
57
|
+
* apiKey: process.env.EDPIRE_API_KEY!,
|
|
58
|
+
* baseUrl: "https://edpire.com",
|
|
59
|
+
* })
|
|
60
|
+
*
|
|
61
|
+
* const assessments = await client.getAssessments({ status: "published" })
|
|
62
|
+
* const result = await client.submit("assessment-id", {
|
|
63
|
+
* learner_ref: "user-123",
|
|
64
|
+
* answers: { exerciseAnswers: [...] },
|
|
65
|
+
* })
|
|
66
|
+
* ```
|
|
67
|
+
*/
|
|
68
|
+
|
|
69
|
+
/** Assessment summary returned by getAssessments() (list). Does not include exercises. */
|
|
70
|
+
interface AssessmentSummary {
|
|
71
|
+
id: string;
|
|
72
|
+
title: string;
|
|
73
|
+
description: string | null;
|
|
74
|
+
/**
|
|
75
|
+
* Free-form label (max 80 chars), set by the author. Replaces the old
|
|
76
|
+
* `type: "quiz" | "exam" | "practice"` enum, which the API never returned.
|
|
77
|
+
*/
|
|
78
|
+
category: string | null;
|
|
79
|
+
status: string;
|
|
80
|
+
share_code: string | null;
|
|
81
|
+
settings: Record<string, unknown>;
|
|
82
|
+
/** Sum of answer-key max scores. Use this to normalize scores, not the sum of `points`. */
|
|
83
|
+
max_score?: number;
|
|
84
|
+
/** Present on the list endpoint only, not on a single-assessment fetch. */
|
|
85
|
+
exercise_count?: number;
|
|
86
|
+
created_at: string;
|
|
87
|
+
updated_at: string;
|
|
88
|
+
}
|
|
89
|
+
/** Full assessment returned by getAssessment() (single fetch). Always includes exercises. */
|
|
90
|
+
interface Assessment extends AssessmentSummary {
|
|
91
|
+
exercises: AssessmentExercise[];
|
|
92
|
+
}
|
|
93
|
+
interface AssessmentExercise {
|
|
94
|
+
id: string;
|
|
95
|
+
shared_context: unknown | null;
|
|
96
|
+
questions: AssessmentQuestion[];
|
|
97
|
+
}
|
|
98
|
+
interface AssessmentQuestion {
|
|
99
|
+
id: string;
|
|
100
|
+
content_ast: unknown;
|
|
101
|
+
points: number;
|
|
102
|
+
sequence_number: number;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* flattenAssessment — convert an assessment API response into a linear
|
|
107
|
+
* sequence of steps, one per question.
|
|
108
|
+
*
|
|
109
|
+
* Useful for Duolingo-style flows where you present questions one at a time
|
|
110
|
+
* and need to know the exercise context of each step (for POST /check).
|
|
111
|
+
*
|
|
112
|
+
* @example
|
|
113
|
+
* const res = await fetch(`/api/v1/assessments/${id}`, { headers: { Authorization: `Bearer ${key}` } })
|
|
114
|
+
* const { data: assessment } = await res.json()
|
|
115
|
+
*
|
|
116
|
+
* const steps = flattenAssessment(assessment)
|
|
117
|
+
* // steps[0] = { exerciseId, questionId, content, points, sequenceNumber, index: 0 }
|
|
118
|
+
*
|
|
119
|
+
* // Render step:
|
|
120
|
+
* <EdpireQuestion content={steps[currentIndex].content} ... />
|
|
121
|
+
*
|
|
122
|
+
* // Check step:
|
|
123
|
+
* POST /api/v1/assessments/{id}/check { exercise_id: steps[i].exerciseId, question_id: steps[i].questionId, ... }
|
|
124
|
+
*/
|
|
125
|
+
|
|
126
|
+
interface FlatStep {
|
|
127
|
+
/** The exercise this question belongs to — required for POST /check */
|
|
128
|
+
exerciseId: string;
|
|
129
|
+
/** The question ID — required for POST /check */
|
|
130
|
+
questionId: string;
|
|
131
|
+
/** ContentAST — pass directly to EdpireQuestion's `content` prop */
|
|
132
|
+
content: unknown;
|
|
133
|
+
/** Point value of this question */
|
|
134
|
+
points: number;
|
|
135
|
+
/** Original sequence number within its exercise */
|
|
136
|
+
sequenceNumber: number;
|
|
137
|
+
/** 0-based index in the flattened sequence — use for progress bar */
|
|
138
|
+
index: number;
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Flatten an assessment from getAssessment() / GET /api/v1/assessments/{id}
|
|
142
|
+
* into an ordered array of steps, preserving exercise and position information.
|
|
143
|
+
*
|
|
144
|
+
* The order follows the assessment's exercise order, then question order
|
|
145
|
+
* within each exercise — the same order a learner would see them.
|
|
146
|
+
*/
|
|
147
|
+
declare function flattenAssessment(assessment: Assessment): FlatStep[];
|
|
148
|
+
|
|
149
|
+
export { type FlatStep, type StoredAnswer, buildSubmitPayload, flattenAssessment };
|
package/dist/core.mjs
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function i(r){let s=[],e=0;for(let t of r.exercises)for(let n of t.questions)s.push({exerciseId:t.id,questionId:n.id,content:n.content_ast,points:n.points,sequenceNumber:n.sequence_number,index:e++});return s}function o(r){let s=new Map;for(let e of r)s.has(e.exerciseId)||s.set(e.exerciseId,[]),s.get(e.exerciseId).push({questionId:e.questionId,answers:e.answers});return{exerciseAnswers:Array.from(s.entries()).map(([e,t])=>({exerciseId:e,questionAnswers:t}))}}export{o as buildSubmitPayload,i as flattenAssessment};
|