@memizy/oqse 0.1.0 → 0.1.2
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 +15 -8
- package/dist/index.cjs +2 -2
- package/dist/index.d.ts +8 -1
- package/dist/index.js +514 -415
- package/dist/src/index.d.ts +1 -0
- package/dist/src/manifest.d.ts +9 -5
- package/dist/src/manifestValidation.d.ts +6 -5
- package/dist/src/oqse.d.ts +0 -28
- package/dist/src/oqseValidation.d.ts +3 -44
- package/dist/src/richTextProcessor.d.ts +46 -0
- package/dist/src/richTextProcessor.test.d.ts +1 -0
- package/dist/src/utils.d.ts +9 -0
- package/package.json +6 -3
- package/schemas/oqse-manifest-v0.1.json +3 -6
- package/schemas/oqse-v0.1.json +3 -34
- package/SPECIFICATION.md +0 -2444
package/dist/src/index.d.ts
CHANGED
package/dist/src/manifest.d.ts
CHANGED
|
@@ -9,7 +9,8 @@ export type { FeatureProfile } from './oqse';
|
|
|
9
9
|
* - `import` - Data ingestion: parses OQSE data into an internal system.
|
|
10
10
|
* - `export` - Data generation: serializes internal data into OQSE format.
|
|
11
11
|
*/
|
|
12
|
-
export
|
|
12
|
+
export declare const OFFICIAL_ACTIONS: readonly ["render", "edit", "validate", "import", "export"];
|
|
13
|
+
export type OfficialAction = typeof OFFICIAL_ACTIONS[number];
|
|
13
14
|
/**
|
|
14
15
|
* Custom action using the required `x-` prefix (e.g., `"x-preview"`, `"x-sync"`).
|
|
15
16
|
* Host environments that do not recognize a custom action MUST ignore it.
|
|
@@ -47,11 +48,12 @@ export type OQSEQuestionDensity = 'low' | 'medium' | 'high';
|
|
|
47
48
|
* `meta.requirements.features` (Study Set) to signal support/requirement.
|
|
48
49
|
*
|
|
49
50
|
* Dependency notes:
|
|
50
|
-
* - `syntax-highlighting`, `mermaid`, `smiles`, `abc-notation`, `html
|
|
51
|
+
* - `syntax-highlighting`, `mermaid`, `smiles`, `abc-notation`, `html`
|
|
51
52
|
* are only meaningful when `markdown` is also declared.
|
|
52
53
|
* - `latexPackages` (in FeatureProfile) is only meaningful when `math` is declared.
|
|
53
54
|
*/
|
|
54
|
-
export
|
|
55
|
+
export declare const OFFICIAL_FEATURE_KEYS: readonly ["markdown", "math", "rtl", "html", "syntax-highlighting", "mermaid", "smiles", "abc-notation", "text-to-speech", "voice-input", "handwriting-recognition"];
|
|
56
|
+
export type OfficialFeatureKey = typeof OFFICIAL_FEATURE_KEYS[number];
|
|
55
57
|
/**
|
|
56
58
|
* A custom feature using the required `x-` prefix (e.g., `"x-memizy-3d-voxel"`).
|
|
57
59
|
* MUST NOT collide with current or future official registry entries.
|
|
@@ -68,7 +70,8 @@ export type FeatureFlag = OfficialFeatureKey | CustomFeatureKey;
|
|
|
68
70
|
* Declared in `capabilities.itemProperties` (app support) and
|
|
69
71
|
* `meta.requirements.itemProperties` (set requirement).
|
|
70
72
|
*/
|
|
71
|
-
export
|
|
73
|
+
export declare const OFFICIAL_ITEM_PROPERTIES: readonly ["hints", "explanation", "incorrectFeedback", "sources", "relatedItems", "dependencyItems", "timeLimit", "lang", "topic", "pedagogy"];
|
|
74
|
+
export type OfficialItemProperty = typeof OFFICIAL_ITEM_PROPERTIES[number];
|
|
72
75
|
/**
|
|
73
76
|
* A custom item property using the `x-` prefix.
|
|
74
77
|
*/
|
|
@@ -83,7 +86,8 @@ export type ItemPropertyKey = OfficialItemProperty | CustomItemProperty;
|
|
|
83
86
|
* Declared in `capabilities.metaProperties` (app support) and
|
|
84
87
|
* `meta.requirements.metaProperties` (set requirement).
|
|
85
88
|
*/
|
|
86
|
-
export
|
|
89
|
+
export declare const OFFICIAL_META_PROPERTIES: readonly ["description", "thumbnail", "subject", "language", "author", "contributors", "license", "ageRestriction", "tags", "tagDefinitions", "sourceMaterials", "estimatedTime", "prerequisites", "translations", "relatedSets"];
|
|
90
|
+
export type OfficialMetaProperty = typeof OFFICIAL_META_PROPERTIES[number];
|
|
87
91
|
/**
|
|
88
92
|
* A custom meta property using the `x-` prefix.
|
|
89
93
|
*/
|
|
@@ -64,10 +64,10 @@ export declare const ManifestCapabilitiesSchema: z.ZodObject<{
|
|
|
64
64
|
}, z.core.$strip>>;
|
|
65
65
|
}, z.core.$strip>;
|
|
66
66
|
/**
|
|
67
|
-
* Full OQSE Application Manifest schema (
|
|
67
|
+
* Full OQSE Application Manifest schema (Table 2.1.1).
|
|
68
68
|
*
|
|
69
69
|
* Validated constraints beyond syntax:
|
|
70
|
-
* - `minOqseVersion`
|
|
70
|
+
* - `minOqseVersion` <= `maxOqseVersion` when both are present
|
|
71
71
|
* - `version` adheres to MAJOR.MINOR format
|
|
72
72
|
* - `capabilities.actions` is non-empty (enforced by inner schema)
|
|
73
73
|
*/
|
|
@@ -151,15 +151,16 @@ export declare function safeValidateManifest(data: unknown): ReturnType<typeof O
|
|
|
151
151
|
* @example
|
|
152
152
|
* ```ts
|
|
153
153
|
* console.error(formatManifestErrors(result.error));
|
|
154
|
-
* //
|
|
155
|
-
* //
|
|
154
|
+
* // Example output:
|
|
155
|
+
* // "id: ID must be in reverse-domain format (e.g. \"com.acme.app\")"
|
|
156
|
+
* // "capabilities.actions: Application must support at least one action"
|
|
156
157
|
* ```
|
|
157
158
|
*/
|
|
158
159
|
export declare function formatManifestErrors(error: z.ZodError): string;
|
|
159
160
|
/**
|
|
160
161
|
* Checks whether a plain object looks like an OQSE Manifest (duck-typing).
|
|
161
162
|
*
|
|
162
|
-
* This is a fast pre-check
|
|
163
|
+
* This is a fast pre-check - use `validateManifest` for full validation.
|
|
163
164
|
*
|
|
164
165
|
* @param data - Any value.
|
|
165
166
|
* @returns `true` if `data` has the minimum required shape.
|
package/dist/src/oqse.d.ts
CHANGED
|
@@ -203,29 +203,6 @@ export interface FeatureProfile {
|
|
|
203
203
|
*/
|
|
204
204
|
metaProperties?: string[];
|
|
205
205
|
}
|
|
206
|
-
/**
|
|
207
|
-
* Feature requirement type
|
|
208
|
-
* @deprecated Use FeatureProfile instead for spec-compliant requirements.
|
|
209
|
-
*/
|
|
210
|
-
export type FeatureType = 'official' | 'experimental' | 'proprietary';
|
|
211
|
-
/**
|
|
212
|
-
* Official feature names
|
|
213
|
-
*/
|
|
214
|
-
export type OfficialFeatureName = 'math' | 'media-image' | 'media-audio' | 'media-video' | 'hotspots' | 'complex-pairing' | 'open-text';
|
|
215
|
-
/**
|
|
216
|
-
* Feature requirement object
|
|
217
|
-
*/
|
|
218
|
-
export interface FeatureRequirement {
|
|
219
|
-
/** Feature name */
|
|
220
|
-
name: string;
|
|
221
|
-
/** Feature type */
|
|
222
|
-
type: FeatureType;
|
|
223
|
-
/**
|
|
224
|
-
* For proprietary features: Domain name of the provider (e.g., "memizy.com").
|
|
225
|
-
* MUST be present for type: "proprietary", ignored for other types.
|
|
226
|
-
*/
|
|
227
|
-
vendor?: string;
|
|
228
|
-
}
|
|
229
206
|
/**
|
|
230
207
|
* Translation object defining reference to translated version of this set
|
|
231
208
|
*/
|
|
@@ -340,11 +317,6 @@ export interface OQSEMeta {
|
|
|
340
317
|
* @see FeatureProfile
|
|
341
318
|
*/
|
|
342
319
|
requirements?: FeatureProfile;
|
|
343
|
-
/**
|
|
344
|
-
* @deprecated Use `requirements` (FeatureProfile) instead.
|
|
345
|
-
* This field used a non-spec-compliant structure.
|
|
346
|
-
*/
|
|
347
|
-
requiredFeatures?: FeatureRequirement[];
|
|
348
320
|
/** Array of text labels (tags) for the entire set */
|
|
349
321
|
tags?: string[];
|
|
350
322
|
/** Dictionary of tag definitions */
|
|
@@ -181,29 +181,6 @@ export declare const FeatureProfileSchema: z.ZodObject<{
|
|
|
181
181
|
itemProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
182
182
|
metaProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
183
183
|
}, z.core.$strip>;
|
|
184
|
-
export declare const FeatureTypeSchema: z.ZodEnum<{
|
|
185
|
-
official: "official";
|
|
186
|
-
experimental: "experimental";
|
|
187
|
-
proprietary: "proprietary";
|
|
188
|
-
}>;
|
|
189
|
-
export declare const OfficialFeatureNameSchema: z.ZodEnum<{
|
|
190
|
-
math: "math";
|
|
191
|
-
"media-image": "media-image";
|
|
192
|
-
"media-audio": "media-audio";
|
|
193
|
-
"media-video": "media-video";
|
|
194
|
-
hotspots: "hotspots";
|
|
195
|
-
"complex-pairing": "complex-pairing";
|
|
196
|
-
"open-text": "open-text";
|
|
197
|
-
}>;
|
|
198
|
-
export declare const FeatureRequirementSchema: z.ZodObject<{
|
|
199
|
-
name: z.ZodString;
|
|
200
|
-
type: z.ZodEnum<{
|
|
201
|
-
official: "official";
|
|
202
|
-
experimental: "experimental";
|
|
203
|
-
proprietary: "proprietary";
|
|
204
|
-
}>;
|
|
205
|
-
vendor: z.ZodOptional<z.ZodString>;
|
|
206
|
-
}, z.core.$strip>;
|
|
207
184
|
export declare const TranslationObjectSchema: z.ZodObject<{
|
|
208
185
|
lang: z.ZodString;
|
|
209
186
|
id: z.ZodString;
|
|
@@ -322,15 +299,6 @@ export declare const OQSEMetaSchema: z.ZodObject<{
|
|
|
322
299
|
itemProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
323
300
|
metaProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
324
301
|
}, z.core.$strip>>;
|
|
325
|
-
requiredFeatures: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
326
|
-
name: z.ZodString;
|
|
327
|
-
type: z.ZodEnum<{
|
|
328
|
-
official: "official";
|
|
329
|
-
experimental: "experimental";
|
|
330
|
-
proprietary: "proprietary";
|
|
331
|
-
}>;
|
|
332
|
-
vendor: z.ZodOptional<z.ZodString>;
|
|
333
|
-
}, z.core.$strip>>>;
|
|
334
302
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
335
303
|
tagDefinitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
336
304
|
wikidataId: z.ZodOptional<z.ZodString>;
|
|
@@ -491,7 +459,7 @@ export declare const PolygonHotspotSchema: z.ZodObject<{
|
|
|
491
459
|
}, z.core.$strip>>;
|
|
492
460
|
}, z.core.$strip>;
|
|
493
461
|
/**
|
|
494
|
-
* Mesh hotspot
|
|
462
|
+
* Mesh hotspot references a named node/mesh in a 3D glTF scene.
|
|
495
463
|
* Used exclusively in `pin-on-model` items.
|
|
496
464
|
*/
|
|
497
465
|
export declare const MeshHotspotSchema: z.ZodObject<{
|
|
@@ -550,7 +518,7 @@ export declare const CameraSetupSchema: z.ZodObject<{
|
|
|
550
518
|
/**
|
|
551
519
|
* Categorize item
|
|
552
520
|
*/
|
|
553
|
-
export declare const
|
|
521
|
+
export declare const CategorizeItemObjectSchema: z.ZodObject<{
|
|
554
522
|
id: z.ZodString;
|
|
555
523
|
text: z.ZodString;
|
|
556
524
|
correctCategoryIndex: z.ZodNumber;
|
|
@@ -1683,7 +1651,7 @@ export declare const PinOnImageItemSchema: z.ZodObject<{
|
|
|
1683
1651
|
/**
|
|
1684
1652
|
* Categorize Item
|
|
1685
1653
|
*/
|
|
1686
|
-
export declare const
|
|
1654
|
+
export declare const CategorizeItemSchema: z.ZodObject<{
|
|
1687
1655
|
id: z.ZodString;
|
|
1688
1656
|
assets: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
1689
1657
|
type: z.ZodEnum<{
|
|
@@ -4280,15 +4248,6 @@ export declare const OQSEFileSchema: z.ZodObject<{
|
|
|
4280
4248
|
itemProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
4281
4249
|
metaProperties: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
4282
4250
|
}, z.core.$strip>>;
|
|
4283
|
-
requiredFeatures: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
4284
|
-
name: z.ZodString;
|
|
4285
|
-
type: z.ZodEnum<{
|
|
4286
|
-
official: "official";
|
|
4287
|
-
experimental: "experimental";
|
|
4288
|
-
proprietary: "proprietary";
|
|
4289
|
-
}>;
|
|
4290
|
-
vendor: z.ZodOptional<z.ZodString>;
|
|
4291
|
-
}, z.core.$strip>>>;
|
|
4292
4251
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
4293
4252
|
tagDefinitions: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
4294
4253
|
wikidataId: z.ZodOptional<z.ZodString>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { FeatureProfile } from './oqse';
|
|
2
|
+
export interface TokenMap {
|
|
3
|
+
[tokenId: string]: {
|
|
4
|
+
type: 'asset' | 'blank';
|
|
5
|
+
key: string;
|
|
6
|
+
originalTag: string;
|
|
7
|
+
};
|
|
8
|
+
}
|
|
9
|
+
export interface RichTextProcessingOptions {
|
|
10
|
+
/** * Function to parse Markdown to HTML (e.g., `marked.parse`).
|
|
11
|
+
* For Tier 1, this should ideally be configured to escape raw HTML.
|
|
12
|
+
*/
|
|
13
|
+
markdownParser: (markdown: string) => string;
|
|
14
|
+
/** * Function to sanitize HTML (e.g., `DOMPurify.sanitize`).
|
|
15
|
+
* REQUIRED if the set declares the 'html' feature (Tier 2).
|
|
16
|
+
*/
|
|
17
|
+
htmlSanitizer?: (html: string) => string;
|
|
18
|
+
/** Callback to render an <asset:key /> tag into HTML (e.g., <img src="...">) */
|
|
19
|
+
assetReplacer?: (key: string) => string;
|
|
20
|
+
/** Callback to render a <blank:key /> tag into HTML (e.g., <input type="text">) */
|
|
21
|
+
blankReplacer?: (key: string) => string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Step 1: Tokenization.
|
|
25
|
+
* Temporarily replaces <asset:key /> and <blank:key /> with cryptographically safe
|
|
26
|
+
* text tokens so they survive Markdown parsing and HTML sanitization.
|
|
27
|
+
*/
|
|
28
|
+
export declare function tokenizeOqseTags(rawText: string): {
|
|
29
|
+
text: string;
|
|
30
|
+
tokens: TokenMap;
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* Step 2 (Tier 1): Strict HTML Validation.
|
|
34
|
+
* If 'html' is not allowed, any raw HTML tags written by the user must cause a validation error.
|
|
35
|
+
*/
|
|
36
|
+
export declare function validateTier1Markdown(textWithoutOqseTags: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Step 4: Detokenization.
|
|
39
|
+
* Replaces the safe tokens back with the final interactive HTML elements.
|
|
40
|
+
*/
|
|
41
|
+
export declare function detokenizeOqseTags(safeHtml: string, tokens: TokenMap, options: Pick<RichTextProcessingOptions, 'assetReplacer' | 'blankReplacer'>): string;
|
|
42
|
+
/**
|
|
43
|
+
* Main Facade for rendering OQSE Rich Content securely.
|
|
44
|
+
* Executes the complete Tokenization -> Validation -> Parsing -> Sanitization -> Detokenization pipeline.
|
|
45
|
+
*/
|
|
46
|
+
export declare function prepareRichTextForDisplay(rawContent: string, requirements: FeatureProfile | undefined, options: RichTextProcessingOptions): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/src/utils.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
1
|
export type UUID = string;
|
|
2
|
+
/**
|
|
3
|
+
* Validates if the given string is a syntactically valid UUID (any version).
|
|
4
|
+
* Uses the robust validator from the 'uuid' package.
|
|
5
|
+
*/
|
|
2
6
|
export declare function isValidUUID(id: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* Generates a new UUIDv7.
|
|
9
|
+
* UUIDv7 is required by the OQSE specification for new items
|
|
10
|
+
* because it is time-sortable and optimized for database indexing.
|
|
11
|
+
*/
|
|
3
12
|
export declare function generateUUID(): UUID;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@memizy/oqse",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "TypeScript SDK and Zod validators for the OQSE specification.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -17,17 +17,19 @@
|
|
|
17
17
|
"dist",
|
|
18
18
|
"schemas",
|
|
19
19
|
"README.md",
|
|
20
|
-
"SPECIFICATION.md"
|
|
20
|
+
"SPECIFICATION.md",
|
|
21
|
+
"LICENSE"
|
|
21
22
|
],
|
|
22
23
|
"scripts": {
|
|
23
24
|
"dev": "vite build --watch",
|
|
24
25
|
"generate:schemas": "tsx scripts/generate-schemas.ts",
|
|
25
|
-
"build": "npm run generate:schemas && tsc && vite build",
|
|
26
|
+
"build": "npm run generate:schemas && tsc && vite build && tsx scripts/fix-types-entry.ts",
|
|
26
27
|
"test": "vitest run",
|
|
27
28
|
"test:watch": "vitest",
|
|
28
29
|
"prepublishOnly": "npm run build"
|
|
29
30
|
},
|
|
30
31
|
"devDependencies": {
|
|
32
|
+
"@types/uuid": "^10.0.0",
|
|
31
33
|
"tsx": "^4.21.0",
|
|
32
34
|
"typescript": "~6.0.2",
|
|
33
35
|
"vite": "^8.0.4",
|
|
@@ -35,6 +37,7 @@
|
|
|
35
37
|
"vitest": "^4.1.4"
|
|
36
38
|
},
|
|
37
39
|
"dependencies": {
|
|
40
|
+
"uuid": "^13.0.0",
|
|
38
41
|
"zod": "^4.3.6"
|
|
39
42
|
}
|
|
40
43
|
}
|
|
@@ -38,8 +38,7 @@
|
|
|
38
38
|
"features": {
|
|
39
39
|
"type": "array",
|
|
40
40
|
"items": {
|
|
41
|
-
"type": "string"
|
|
42
|
-
"minLength": 1
|
|
41
|
+
"type": "string"
|
|
43
42
|
}
|
|
44
43
|
},
|
|
45
44
|
"latexPackages": {
|
|
@@ -52,15 +51,13 @@
|
|
|
52
51
|
"itemProperties": {
|
|
53
52
|
"type": "array",
|
|
54
53
|
"items": {
|
|
55
|
-
"type": "string"
|
|
56
|
-
"minLength": 1
|
|
54
|
+
"type": "string"
|
|
57
55
|
}
|
|
58
56
|
},
|
|
59
57
|
"metaProperties": {
|
|
60
58
|
"type": "array",
|
|
61
59
|
"items": {
|
|
62
|
-
"type": "string"
|
|
63
|
-
"minLength": 1
|
|
60
|
+
"type": "string"
|
|
64
61
|
}
|
|
65
62
|
},
|
|
66
63
|
"actions": {
|
package/schemas/oqse-v0.1.json
CHANGED
|
@@ -239,8 +239,7 @@
|
|
|
239
239
|
"features": {
|
|
240
240
|
"type": "array",
|
|
241
241
|
"items": {
|
|
242
|
-
"type": "string"
|
|
243
|
-
"minLength": 1
|
|
242
|
+
"type": "string"
|
|
244
243
|
}
|
|
245
244
|
},
|
|
246
245
|
"latexPackages": {
|
|
@@ -253,48 +252,18 @@
|
|
|
253
252
|
"itemProperties": {
|
|
254
253
|
"type": "array",
|
|
255
254
|
"items": {
|
|
256
|
-
"type": "string"
|
|
257
|
-
"minLength": 1
|
|
255
|
+
"type": "string"
|
|
258
256
|
}
|
|
259
257
|
},
|
|
260
258
|
"metaProperties": {
|
|
261
259
|
"type": "array",
|
|
262
260
|
"items": {
|
|
263
|
-
"type": "string"
|
|
264
|
-
"minLength": 1
|
|
261
|
+
"type": "string"
|
|
265
262
|
}
|
|
266
263
|
}
|
|
267
264
|
},
|
|
268
265
|
"additionalProperties": false
|
|
269
266
|
},
|
|
270
|
-
"requiredFeatures": {
|
|
271
|
-
"type": "array",
|
|
272
|
-
"items": {
|
|
273
|
-
"type": "object",
|
|
274
|
-
"properties": {
|
|
275
|
-
"name": {
|
|
276
|
-
"type": "string",
|
|
277
|
-
"minLength": 1
|
|
278
|
-
},
|
|
279
|
-
"type": {
|
|
280
|
-
"type": "string",
|
|
281
|
-
"enum": [
|
|
282
|
-
"official",
|
|
283
|
-
"experimental",
|
|
284
|
-
"proprietary"
|
|
285
|
-
]
|
|
286
|
-
},
|
|
287
|
-
"vendor": {
|
|
288
|
-
"type": "string"
|
|
289
|
-
}
|
|
290
|
-
},
|
|
291
|
-
"required": [
|
|
292
|
-
"name",
|
|
293
|
-
"type"
|
|
294
|
-
],
|
|
295
|
-
"additionalProperties": false
|
|
296
|
-
}
|
|
297
|
-
},
|
|
298
267
|
"tags": {
|
|
299
268
|
"type": "array",
|
|
300
269
|
"items": {
|