@digimakers/core 0.1.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.
Files changed (45) hide show
  1. package/dist/index.d.ts +10 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +16 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/logger.d.ts +3 -0
  6. package/dist/logger.d.ts.map +1 -0
  7. package/dist/logger.js +15 -0
  8. package/dist/logger.js.map +1 -0
  9. package/dist/parsing/docx-parser.d.ts +7 -0
  10. package/dist/parsing/docx-parser.d.ts.map +1 -0
  11. package/dist/parsing/docx-parser.js +75 -0
  12. package/dist/parsing/docx-parser.js.map +1 -0
  13. package/dist/parsing/file-discovery.d.ts +9 -0
  14. package/dist/parsing/file-discovery.d.ts.map +1 -0
  15. package/dist/parsing/file-discovery.js +35 -0
  16. package/dist/parsing/file-discovery.js.map +1 -0
  17. package/dist/parsing/index.d.ts +5 -0
  18. package/dist/parsing/index.d.ts.map +1 -0
  19. package/dist/parsing/index.js +3 -0
  20. package/dist/parsing/index.js.map +1 -0
  21. package/dist/pdf-generator.d.ts +13 -0
  22. package/dist/pdf-generator.d.ts.map +1 -0
  23. package/dist/pdf-generator.js +110 -0
  24. package/dist/pdf-generator.js.map +1 -0
  25. package/dist/sample-data.d.ts +3 -0
  26. package/dist/sample-data.d.ts.map +1 -0
  27. package/dist/sample-data.js +51 -0
  28. package/dist/sample-data.js.map +1 -0
  29. package/dist/schemas/generation.d.ts +8 -0
  30. package/dist/schemas/generation.d.ts.map +1 -0
  31. package/dist/schemas/generation.js +6 -0
  32. package/dist/schemas/generation.js.map +1 -0
  33. package/dist/schemas/index.d.ts +3 -0
  34. package/dist/schemas/index.d.ts.map +1 -0
  35. package/dist/schemas/index.js +3 -0
  36. package/dist/schemas/index.js.map +1 -0
  37. package/dist/schemas/lesson.d.ts +70 -0
  38. package/dist/schemas/lesson.d.ts.map +1 -0
  39. package/dist/schemas/lesson.js +77 -0
  40. package/dist/schemas/lesson.js.map +1 -0
  41. package/dist/server.d.ts +11 -0
  42. package/dist/server.d.ts.map +1 -0
  43. package/dist/server.js +89 -0
  44. package/dist/server.js.map +1 -0
  45. package/package.json +58 -0
@@ -0,0 +1,10 @@
1
+ export { StepWithImageSchema, StepsWithCodeBlockSchema, ChallengeSchema, NewProjectSchema, ParsedLessonSchema, GenerateOptionsSchema, type StepWithImage, type StepsWithCodeBlock, type Challenge, type NewProject, type ParsedLesson, type GenerateOptions, } from './schemas/index.js';
2
+ export { createPdfGenerator } from './pdf-generator.js';
3
+ export type { PdfGeneratorInstance } from './pdf-generator.js';
4
+ export { startServer, stopServer } from './server.js';
5
+ export type { ServerInstance } from './server.js';
6
+ export { logger } from './logger.js';
7
+ export { findDocxFiles, parseDocx } from './parsing/index.js';
8
+ export type { DiscoveryOptions, DiscoveredFile, ParseResult } from './parsing/index.js';
9
+ export { sampleLessonData } from './sample-data.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,EAErB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,EACjB,KAAK,eAAe,GACrB,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAG/D,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACtD,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGlD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAGrC,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGxF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ // Public API for @digimakers/core
2
+ // Schemas and types (single source of truth)
3
+ export {
4
+ // Schemas
5
+ StepWithImageSchema, StepsWithCodeBlockSchema, ChallengeSchema, NewProjectSchema, ParsedLessonSchema, GenerateOptionsSchema, } from './schemas/index.js';
6
+ // PDF generation
7
+ export { createPdfGenerator } from './pdf-generator.js';
8
+ // Server
9
+ export { startServer, stopServer } from './server.js';
10
+ // Logger
11
+ export { logger } from './logger.js';
12
+ // Parsing
13
+ export { findDocxFiles, parseDocx } from './parsing/index.js';
14
+ // Sample data (for testing)
15
+ export { sampleLessonData } from './sample-data.js';
16
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kCAAkC;AAElC,6CAA6C;AAC7C,OAAO;AACL,UAAU;AACV,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,qBAAqB,GAQtB,MAAM,oBAAoB,CAAC;AAE5B,iBAAiB;AACjB,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAGxD,SAAS;AACT,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAGtD,SAAS;AACT,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAG9D,4BAA4B;AAC5B,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ import pino from 'pino';
2
+ export declare const logger: pino.Logger<never, boolean>;
3
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,eAAO,MAAM,MAAM,6BAYjB,CAAC"}
package/dist/logger.js ADDED
@@ -0,0 +1,15 @@
1
+ import pino from 'pino';
2
+ export const logger = pino({
3
+ level: process.env.LOG_LEVEL || 'info',
4
+ transport: {
5
+ target: 'pino-pretty',
6
+ options: {
7
+ colorize: true,
8
+ translateTime: 'HH:MM:ss',
9
+ ignore: 'pid,hostname',
10
+ singleLine: false,
11
+ messageFormat: '{msg}',
12
+ },
13
+ },
14
+ });
15
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM;IACtC,SAAS,EAAE;QACT,MAAM,EAAE,aAAa;QACrB,OAAO,EAAE;YACP,QAAQ,EAAE,IAAI;YACd,aAAa,EAAE,UAAU;YACzB,MAAM,EAAE,cAAc;YACtB,UAAU,EAAE,KAAK;YACjB,aAAa,EAAE,OAAO;SACvB;KACF;CACF,CAAC,CAAC"}
@@ -0,0 +1,7 @@
1
+ import { ParsedLesson } from '../schemas/index.js';
2
+ export interface ParseResult {
3
+ data: ParsedLesson;
4
+ sourcePath: string;
5
+ }
6
+ export declare function parseDocx(filePath: string): Promise<ParseResult>;
7
+ //# sourceMappingURL=docx-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx-parser.d.ts","sourceRoot":"","sources":["../../src/parsing/docx-parser.ts"],"names":[],"mappings":"AAIA,OAAO,EAAsB,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAGvE,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,YAAY,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AA4BD,wBAAsB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA4DtE"}
@@ -0,0 +1,75 @@
1
+ import fs from 'fs/promises';
2
+ import mammoth from 'mammoth';
3
+ import { generateText, Output } from 'ai';
4
+ import { createGoogleGenerativeAI } from '@ai-sdk/google';
5
+ import { ParsedLessonSchema } from '../schemas/index.js';
6
+ import { logger } from '../logger.js';
7
+ // Setup google generative ai
8
+ const google = createGoogleGenerativeAI({
9
+ apiKey: process.env.GEMINI_API_KEY,
10
+ });
11
+ // Extract images from docx as base64 data URIs
12
+ async function extractImages(buffer) {
13
+ const images = [];
14
+ await mammoth.convertToHtml({ buffer }, {
15
+ convertImage: mammoth.images.imgElement(async (image) => {
16
+ const imageBuffer = await image.read();
17
+ const base64 = imageBuffer.toString('base64');
18
+ const dataUri = `data:${image.contentType};base64,${base64}`;
19
+ images.push(dataUri);
20
+ return { src: dataUri };
21
+ }),
22
+ });
23
+ return images;
24
+ }
25
+ // Parse a .docx file and extract lesson data
26
+ export async function parseDocx(filePath) {
27
+ logger.info(`Parsing: ${filePath}`);
28
+ const buffer = await fs.readFile(filePath);
29
+ // Extract text and images in parallel
30
+ const [{ value: text }, allImages] = await Promise.all([
31
+ mammoth.extractRawText({ buffer }),
32
+ extractImages(buffer),
33
+ ]);
34
+ logger.info(text);
35
+ logger.info(allImages);
36
+ logger.debug(`Extracted ${text.length} characters and ${allImages.length} images`);
37
+ // First image is project cover, rest are for code steps
38
+ const projectImage = allImages.length > 0 ? allImages[0] : null;
39
+ const stepImages = allImages.slice(1);
40
+ logger.info(`Found ${stepImages.length} step images, projectImage: ${projectImage ? 'yes' : 'no'}`);
41
+ // Use LLM to extract structured data
42
+ const { output } = await generateText({
43
+ model: google('gemini-2.0-flash'),
44
+ output: Output.object({
45
+ schema: ParsedLessonSchema,
46
+ }),
47
+ prompt: `Extract structured lesson data from this educational document.
48
+
49
+ This is a programming lesson sheet for students. Extract all the relevant sections and content.
50
+
51
+ If a section is not present in the document, use empty arrays for array fields, empty strings for required string fields, and null for nullable fields.
52
+
53
+ For the addYourCodeSection, each step should be a clear instruction. Set image to null for all steps (images will be added separately).
54
+
55
+ Document content:
56
+ ${text}`,
57
+ });
58
+ logger.info(output);
59
+ logger.info(`Successfully extracted lesson: ${output.topic} - ${output.project}`);
60
+ // Post-process: assign images to the extracted data
61
+ const data = output;
62
+ data.projectImage = projectImage;
63
+ // Assign step images in order
64
+ if (stepImages.length > 0 && Array.isArray(data.addYourCodeSection)) {
65
+ data.addYourCodeSection.forEach((step, index) => {
66
+ step.image = stepImages[index] ?? null;
67
+ });
68
+ }
69
+ logger.info(data);
70
+ return {
71
+ data,
72
+ sourcePath: filePath,
73
+ };
74
+ }
75
+ //# sourceMappingURL=docx-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx-parser.js","sourceRoot":"","sources":["../../src/parsing/docx-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ export interface DiscoveryOptions {
2
+ recursive?: boolean;
3
+ }
4
+ export interface DiscoveredFile {
5
+ path: string;
6
+ name: string;
7
+ }
8
+ export declare function findDocxFiles(target: string, options?: DiscoveryOptions): Promise<DiscoveredFile[]>;
9
+ //# sourceMappingURL=file-discovery.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-discovery.d.ts","sourceRoot":"","sources":["../../src/parsing/file-discovery.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,gBAAgB;IAC/B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,aAAa,CACjC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,cAAc,EAAE,CAAC,CAkB3B"}
@@ -0,0 +1,35 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ import { logger } from '../logger.js';
4
+ export async function findDocxFiles(target, options = {}) {
5
+ const { recursive = false } = options;
6
+ const resolvedPath = path.resolve(target);
7
+ const stat = await fs.stat(resolvedPath);
8
+ if (stat.isFile()) {
9
+ if (!resolvedPath.endsWith('.docx')) {
10
+ throw new Error(`File is not a .docx: ${resolvedPath}`);
11
+ }
12
+ return [{ path: resolvedPath, name: path.basename(resolvedPath, '.docx') }];
13
+ }
14
+ if (stat.isDirectory()) {
15
+ return scanDirectory(resolvedPath, recursive);
16
+ }
17
+ throw new Error(`Invalid path: ${resolvedPath}`);
18
+ }
19
+ async function scanDirectory(dir, recursive) {
20
+ const files = [];
21
+ const entries = await fs.readdir(dir, { withFileTypes: true });
22
+ for (const entry of entries) {
23
+ const fullPath = path.join(dir, entry.name);
24
+ if (entry.isFile() && entry.name.endsWith('.docx')) {
25
+ files.push({ path: fullPath, name: path.basename(entry.name, '.docx') });
26
+ }
27
+ else if (entry.isDirectory() && recursive) {
28
+ const nested = await scanDirectory(fullPath, recursive);
29
+ files.push(...nested);
30
+ }
31
+ }
32
+ logger.info(`Found ${files.length} .docx file(s) in ${dir}`);
33
+ return files;
34
+ }
35
+ //# sourceMappingURL=file-discovery.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-discovery.js","sourceRoot":"","sources":["../../src/parsing/file-discovery.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,aAAa,CAAC;AAC7B,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AAWtC,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,MAAc,EACd,UAA4B,EAAE;IAE9B,MAAM,EAAE,SAAS,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAE1C,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAEzC,IAAI,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IAC9E,CAAC;IAED,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACvB,OAAO,aAAa,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,iBAAiB,YAAY,EAAE,CAAC,CAAC;AACnD,CAAC;AAED,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,SAAkB;IAC1D,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE5C,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;aAAM,IAAI,KAAK,CAAC,WAAW,EAAE,IAAI,SAAS,EAAE,CAAC;YAC5C,MAAM,MAAM,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;YACxD,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QACxB,CAAC;IACH,CAAC;IAED,MAAM,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,qBAAqB,GAAG,EAAE,CAAC,CAAC;IAC7D,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { findDocxFiles } from './file-discovery.js';
2
+ export type { DiscoveryOptions, DiscoveredFile } from './file-discovery.js';
3
+ export { parseDocx } from './docx-parser.js';
4
+ export type { ParseResult } from './docx-parser.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/parsing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE5E,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,YAAY,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { findDocxFiles } from './file-discovery.js';
2
+ export { parseDocx } from './docx-parser.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/parsing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGpD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { Browser } from 'puppeteer';
2
+ import { ParsedLesson, GenerateOptions } from './schemas/index.js';
3
+ export interface PdfGeneratorInstance {
4
+ browser: Browser;
5
+ generatePdf: (data: ParsedLesson, options?: GenerateOptions) => Promise<string>;
6
+ generateBatch: (items: {
7
+ data: ParsedLesson;
8
+ options: GenerateOptions;
9
+ }[]) => Promise<string[]>;
10
+ close: () => Promise<void>;
11
+ }
12
+ export declare function createPdfGenerator(serverUrl: string): Promise<PdfGeneratorInstance>;
13
+ //# sourceMappingURL=pdf-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-generator.d.ts","sourceRoot":"","sources":["../src/pdf-generator.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAE,OAAO,EAAQ,MAAM,WAAW,CAAC;AAGrD,OAAO,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGnE,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,CAAC,EAAE,eAAe,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAChF,aAAa,EAAE,CAAC,KAAK,EAAE;QAAE,IAAI,EAAE,YAAY,CAAC;QAAC,OAAO,EAAE,eAAe,CAAA;KAAE,EAAE,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChG,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAWD,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAkIzF"}
@@ -0,0 +1,110 @@
1
+ import puppeteer from 'puppeteer';
2
+ import path from 'path';
3
+ import fs from 'fs/promises';
4
+ import { logger } from './logger.js';
5
+ const POOL_SIZE = 4;
6
+ const RENDER_DELAY = 100;
7
+ const PAGE_WAIT_MS = 30_000;
8
+ export async function createPdfGenerator(serverUrl) {
9
+ logger.info('[PDF] Launching browser...');
10
+ const browser = await puppeteer.launch({
11
+ headless: true,
12
+ args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
13
+ });
14
+ const pool = [];
15
+ async function initPage() {
16
+ const page = await browser.newPage();
17
+ await page.setViewport({ width: 794, height: 1123, deviceScaleFactor: 2 });
18
+ const printUrl = serverUrl.endsWith('/') ? `${serverUrl}print` : `${serverUrl}/print`;
19
+ await page.goto(printUrl, { waitUntil: 'networkidle0' });
20
+ return page;
21
+ }
22
+ async function getAvailablePage() {
23
+ let pooledPage = pool.find((p) => !p.busy);
24
+ if (!pooledPage && pool.length < POOL_SIZE) {
25
+ const page = await initPage();
26
+ pooledPage = { page, busy: false };
27
+ pool.push(pooledPage);
28
+ }
29
+ if (!pooledPage) {
30
+ await new Promise((resolve) => {
31
+ const check = () => {
32
+ pooledPage = pool.find((p) => !p.busy);
33
+ if (pooledPage)
34
+ resolve();
35
+ else
36
+ setTimeout(check, 10);
37
+ };
38
+ check();
39
+ });
40
+ }
41
+ pooledPage.busy = true;
42
+ return pooledPage;
43
+ }
44
+ async function generateOnPage(page, data, options) {
45
+ const { outputDir = './output', filename = 'output' } = options;
46
+ await fs.mkdir(outputDir, { recursive: true });
47
+ // Clear previous data
48
+ await page.evaluate(() => {
49
+ window['PDF_DATA'] = null;
50
+ });
51
+ // Small delay to ensure Angular detects the null value
52
+ await new Promise((resolve) => setTimeout(resolve, 50));
53
+ // Set new data
54
+ await page.evaluate((lessonData) => {
55
+ window['PDF_DATA'] = lessonData;
56
+ }, data);
57
+ // Wait for Paged.js to fully complete pagination
58
+ // The LessonPreviewComponent sets window.PAGED_READY = true when done
59
+ await page.waitForFunction(() => window['PAGED_READY'] === true, {
60
+ timeout: PAGE_WAIT_MS,
61
+ polling: 100,
62
+ });
63
+ // Wait for all images to be fully loaded
64
+ await page.waitForFunction(() => {
65
+ const images = Array.from(document.querySelectorAll('img'));
66
+ return images.every((img) => img.complete && img.naturalHeight > 0);
67
+ }, { timeout: PAGE_WAIT_MS, polling: 100 });
68
+ // Small delay for any final paint operations
69
+ await new Promise((resolve) => setTimeout(resolve, RENDER_DELAY));
70
+ const pdfPath = path.join(outputDir, `${filename}.pdf`);
71
+ await page.pdf({
72
+ path: pdfPath,
73
+ printBackground: true,
74
+ width: '210mm', // A4 width
75
+ height: '297mm', // A4 height
76
+ });
77
+ return pdfPath;
78
+ }
79
+ async function generatePdf(data, options = {}) {
80
+ const pooledPage = await getAvailablePage();
81
+ try {
82
+ const result = await generateOnPage(pooledPage.page, data, options);
83
+ logger.info(`[PDF] Saved: ${result}`);
84
+ return result;
85
+ }
86
+ finally {
87
+ pooledPage.busy = false;
88
+ }
89
+ }
90
+ async function generateBatch(items) {
91
+ logger.info(`[PDF] Processing ${items.length} files with ${POOL_SIZE} parallel workers...`);
92
+ const results = [];
93
+ const promises = items.map(async (item, index) => {
94
+ const result = await generatePdf(item.data, item.options);
95
+ results[index] = result;
96
+ });
97
+ await Promise.all(promises);
98
+ return results;
99
+ }
100
+ async function close() {
101
+ for (const pooledPage of pool) {
102
+ await pooledPage.page.close();
103
+ }
104
+ await browser.close();
105
+ logger.info('[PDF] Browser closed');
106
+ }
107
+ logger.info('[PDF] Browser launched');
108
+ return { browser, generatePdf, generateBatch, close };
109
+ }
110
+ //# sourceMappingURL=pdf-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-generator.js","sourceRoot":"","sources":["../src/pdf-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { ParsedLesson } from './schemas/lesson.js';
2
+ export declare const sampleLessonData: ParsedLesson;
3
+ //# sourceMappingURL=sample-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-data.d.ts","sourceRoot":"","sources":["../src/sample-data.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,eAAO,MAAM,gBAAgB,EAAE,YAoD9B,CAAC"}
@@ -0,0 +1,51 @@
1
+ export const sampleLessonData = {
2
+ topic: 'Decisions',
3
+ project: 'Crossy Road',
4
+ description: 'Decision making is important when there will be situations with multiple options and an option needs to be selected based on the given conditions.',
5
+ projectExplainer: 'In this lesson, we will create a Crossy Road style game where a penguin needs to cross the road and get to the other side without being hit by cars.',
6
+ projectImage: null,
7
+ getReadySection: ['Add Backdrop "street"', 'Add Sprites: Car and Penguin (set sizes to 40)'],
8
+ addYourCodeSection: [
9
+ {
10
+ step: 'Car: When green flag is clicked, set Rotation style left-right, size 40%. Forever, move 5 steps, if on edge, bounce.',
11
+ image: null,
12
+ },
13
+ {
14
+ step: 'Penguin: When green flag is clicked, Forever: if UP arrow key is pressed, change y by 10.',
15
+ image: null,
16
+ },
17
+ {
18
+ step: 'Penguin: Inside Forever; If DOWN arrow key is pressed, change y by -10.',
19
+ image: null,
20
+ },
21
+ {
22
+ step: 'Penguin: Inside Forever; If RIGHT arrow key is pressed, change x by 10.',
23
+ image: null,
24
+ },
25
+ {
26
+ step: 'Penguin: Inside Forever; If LEFT arrow key is pressed, change x by -10.',
27
+ image: null,
28
+ },
29
+ {
30
+ step: 'Penguin: Inside Forever; If Penguin touches the car, say "Ouch!" and go back to its start position.',
31
+ image: null,
32
+ },
33
+ ],
34
+ tryItOutSection: [
35
+ 'Click the green flag and test your game',
36
+ 'Make sure the penguin can move in all directions',
37
+ 'Check if the car bounces at the edges',
38
+ ],
39
+ challengeSection: [
40
+ { name: 'Bruise Penguin', task: 'Add sound effects when the penguin gets hit' },
41
+ { name: 'Add more cars', task: 'Add more cars moving at different speeds' },
42
+ { name: 'Multiple Levels', task: 'Create multiple levels with increasing difficulty' },
43
+ ],
44
+ newProject: {
45
+ name: 'Energy Boost',
46
+ task: 'Try creating a similar game with different sprites and backgrounds',
47
+ },
48
+ testYourself: 'http://youtube.com',
49
+ funFact: 'The original Crossy Road game was inspired by the classic arcade game Frogger from 1981!',
50
+ };
51
+ //# sourceMappingURL=sample-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sample-data.js","sourceRoot":"","sources":["../src/sample-data.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,gBAAgB,GAAiB;IAC5C,KAAK,EAAE,WAAW;IAClB,OAAO,EAAE,aAAa;IACtB,WAAW,EACT,oJAAoJ;IACtJ,gBAAgB,EACd,sJAAsJ;IACxJ,YAAY,EAAE,IAAI;IAClB,eAAe,EAAE,CAAC,uBAAuB,EAAE,gDAAgD,CAAC;IAC5F,kBAAkB,EAAE;QAClB;YACE,IAAI,EAAE,sHAAsH;YAC5H,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,2FAA2F;YACjG,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,yEAAyE;YAC/E,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,yEAAyE;YAC/E,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,yEAAyE;YAC/E,KAAK,EAAE,IAAI;SACZ;QACD;YACE,IAAI,EAAE,qGAAqG;YAC3G,KAAK,EAAE,IAAI;SACZ;KACF;IACD,eAAe,EAAE;QACf,yCAAyC;QACzC,kDAAkD;QAClD,uCAAuC;KACxC;IACD,gBAAgB,EAAE;QAChB,EAAE,IAAI,EAAE,gBAAgB,EAAE,IAAI,EAAE,6CAA6C,EAAE;QAC/E,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,0CAA0C,EAAE;QAC3E,EAAE,IAAI,EAAE,iBAAiB,EAAE,IAAI,EAAE,mDAAmD,EAAE;KACvF;IACD,UAAU,EAAE;QACV,IAAI,EAAE,cAAc;QACpB,IAAI,EAAE,oEAAoE;KAC3E;IACD,YAAY,EAAE,oBAAoB;IAClC,OAAO,EACL,0FAA0F;CAC7F,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { z } from 'zod';
2
+ export declare const GenerateOptionsSchema: z.ZodObject<{
3
+ outputDir: z.ZodOptional<z.ZodString>;
4
+ filename: z.ZodOptional<z.ZodString>;
5
+ }, z.core.$strip>;
6
+ export interface GenerateOptions extends z.infer<typeof GenerateOptionsSchema> {
7
+ }
8
+ //# sourceMappingURL=generation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.d.ts","sourceRoot":"","sources":["../../src/schemas/generation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,qBAAqB;;;iBAGhC,CAAC;AAEH,MAAM,WAAW,eAAgB,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC;CAAG"}
@@ -0,0 +1,6 @@
1
+ import { z } from 'zod';
2
+ export const GenerateOptionsSchema = z.object({
3
+ outputDir: z.string().optional(),
4
+ filename: z.string().optional(),
5
+ });
6
+ //# sourceMappingURL=generation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generation.js","sourceRoot":"","sources":["../../src/schemas/generation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,qBAAqB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC5C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;IAChC,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAChC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { StepWithImageSchema, StepsWithCodeBlockSchema, ChallengeSchema, NewProjectSchema, ParsedLessonSchema, type StepWithImage, type StepsWithCodeBlock, type Challenge, type NewProject, type ParsedLesson, } from './lesson.js';
2
+ export { GenerateOptionsSchema, type GenerateOptions } from './generation.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,EAClB,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,KAAK,SAAS,EACd,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAE,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { StepWithImageSchema, StepsWithCodeBlockSchema, ChallengeSchema, NewProjectSchema, ParsedLessonSchema, } from './lesson.js';
2
+ export { GenerateOptionsSchema } from './generation.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,wBAAwB,EACxB,eAAe,EACf,gBAAgB,EAChB,kBAAkB,GAMnB,MAAM,aAAa,CAAC;AAErB,OAAO,EAAE,qBAAqB,EAAwB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,70 @@
1
+ import { z } from 'zod';
2
+ export declare const StepWithImageSchema: z.ZodObject<{
3
+ step: z.ZodString;
4
+ image: z.ZodDefault<z.ZodNullable<z.ZodString>>;
5
+ }, z.core.$strip>;
6
+ export declare const StepsWithCodeBlockSchema: z.ZodObject<{
7
+ codeBlock: z.ZodString;
8
+ codeBlockLanguage: z.ZodDefault<z.ZodEnum<{
9
+ none: "none";
10
+ "small-basic": "small-basic";
11
+ "javascript or html or css": "javascript or html or css";
12
+ python: "python";
13
+ java: "java";
14
+ c: "c";
15
+ }>>;
16
+ steps: z.ZodArray<z.ZodString>;
17
+ }, z.core.$strip>;
18
+ export declare const ChallengeSchema: z.ZodObject<{
19
+ name: z.ZodString;
20
+ task: z.ZodString;
21
+ }, z.core.$strip>;
22
+ export declare const NewProjectSchema: z.ZodObject<{
23
+ name: z.ZodString;
24
+ task: z.ZodString;
25
+ }, z.core.$strip>;
26
+ export declare const ParsedLessonSchema: z.ZodObject<{
27
+ topic: z.ZodString;
28
+ project: z.ZodString;
29
+ description: z.ZodString;
30
+ projectExplainer: z.ZodString;
31
+ projectImage: z.ZodDefault<z.ZodNullable<z.ZodString>>;
32
+ getReadySection: z.ZodArray<z.ZodString>;
33
+ addYourCodeSection: z.ZodUnion<readonly [z.ZodArray<z.ZodObject<{
34
+ step: z.ZodString;
35
+ image: z.ZodDefault<z.ZodNullable<z.ZodString>>;
36
+ }, z.core.$strip>>, z.ZodObject<{
37
+ codeBlock: z.ZodString;
38
+ codeBlockLanguage: z.ZodDefault<z.ZodEnum<{
39
+ none: "none";
40
+ "small-basic": "small-basic";
41
+ "javascript or html or css": "javascript or html or css";
42
+ python: "python";
43
+ java: "java";
44
+ c: "c";
45
+ }>>;
46
+ steps: z.ZodArray<z.ZodString>;
47
+ }, z.core.$strip>]>;
48
+ tryItOutSection: z.ZodDefault<z.ZodNullable<z.ZodArray<z.ZodString>>>;
49
+ challengeSection: z.ZodArray<z.ZodObject<{
50
+ name: z.ZodString;
51
+ task: z.ZodString;
52
+ }, z.core.$strip>>;
53
+ newProject: z.ZodObject<{
54
+ name: z.ZodString;
55
+ task: z.ZodString;
56
+ }, z.core.$strip>;
57
+ testYourself: z.ZodDefault<z.ZodNullable<z.ZodString>>;
58
+ funFact: z.ZodDefault<z.ZodNullable<z.ZodString>>;
59
+ }, z.core.$strip>;
60
+ export interface StepWithImage extends z.infer<typeof StepWithImageSchema> {
61
+ }
62
+ export interface StepsWithCodeBlock extends z.infer<typeof StepsWithCodeBlockSchema> {
63
+ }
64
+ export interface Challenge extends z.infer<typeof ChallengeSchema> {
65
+ }
66
+ export interface NewProject extends z.infer<typeof NewProjectSchema> {
67
+ }
68
+ export interface ParsedLesson extends z.infer<typeof ParsedLessonSchema> {
69
+ }
70
+ //# sourceMappingURL=lesson.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lesson.d.ts","sourceRoot":"","sources":["../../src/schemas/lesson.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,mBAAmB;;;iBAG9B,CAAC;AAEH,eAAO,MAAM,wBAAwB;;;;;;;;;;;iBAanC,CAAC;AAEH,eAAO,MAAM,eAAe;;;iBAO1B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;iBAS3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA4C7B,CAAC;AAGH,MAAM,WAAW,aAAc,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC;CAAG;AAC7E,MAAM,WAAW,kBAAmB,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,wBAAwB,CAAC;CAAG;AACvF,MAAM,WAAW,SAAU,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC;CAAG;AACrE,MAAM,WAAW,UAAW,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC;CAAG;AACvE,MAAM,WAAW,YAAa,SAAQ,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC;CAAG"}
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod';
2
+ export const StepWithImageSchema = z.object({
3
+ step: z.string().describe('The instruction text for this step'),
4
+ image: z.string().nullable().default(null).describe('Image reference if present, otherwise null'),
5
+ });
6
+ export const StepsWithCodeBlockSchema = z.object({
7
+ codeBlock: z.string().describe('The code block that students have to write to get started'),
8
+ codeBlockLanguage: z
9
+ .enum(['none', 'small-basic', 'javascript or html or css', 'python', 'java', 'c'])
10
+ .default('small-basic')
11
+ .describe('The programming language used in the code block. Detect from syntax, "none" if unsure'),
12
+ steps: z
13
+ .array(z.string())
14
+ .describe('The steps listed above the code block but below the "Add your code header", says "Main Program"'),
15
+ });
16
+ export const ChallengeSchema = z.object({
17
+ name: z
18
+ .string()
19
+ .describe('The name of the specific challenge, excluding the "- New Project" text'),
20
+ task: z
21
+ .string()
22
+ .describe('The task for the challenge, explained as a requirement or feature to add'),
23
+ });
24
+ export const NewProjectSchema = z.object({
25
+ name: z
26
+ .string()
27
+ .describe('The name of the new project, usually shown in the header title next to "New Project"'),
28
+ task: z
29
+ .string()
30
+ .describe('The task for the new project, explained as a requirement or new feature to add'),
31
+ });
32
+ export const ParsedLessonSchema = z.object({
33
+ topic: z
34
+ .string()
35
+ .describe('The main topic/category of the lesson (e.g., "Decisions", "Loops", "Variables")'),
36
+ project: z
37
+ .string()
38
+ .describe('The name of the project being built (e.g., "Crossy Road", "Space Invaders")'),
39
+ description: z
40
+ .string()
41
+ .describe('A brief description explaining the programming concept being taught'),
42
+ projectExplainer: z.string().describe('Explanation of what will be built in this lesson'),
43
+ projectImage: z
44
+ .string()
45
+ .nullable()
46
+ .default(null)
47
+ .describe('Reference to the main project image if present'),
48
+ getReadySection: z
49
+ .array(z.string())
50
+ .describe('List of setup steps to prepare for the project (adding sprites, backdrops, etc.)'),
51
+ addYourCodeSection: z.union([
52
+ z
53
+ .array(StepWithImageSchema)
54
+ .describe('Step-by-step coding instructions, each step may have an associated image'),
55
+ StepsWithCodeBlockSchema.describe('A block of code given with steps on what it does'),
56
+ ]),
57
+ tryItOutSection: z
58
+ .array(z.string())
59
+ .nullable()
60
+ .default(null)
61
+ .describe('Steps to test the project after coding'),
62
+ challengeSection: z
63
+ .array(ChallengeSchema)
64
+ .describe('Challenge tasks for students to extend the project'),
65
+ newProject: NewProjectSchema.describe('Suggestion for a new project or extension activity'),
66
+ testYourself: z
67
+ .string()
68
+ .nullable()
69
+ .default(null)
70
+ .describe('A link to the quiz, found under the "Test Yourself" header'),
71
+ funFact: z
72
+ .string()
73
+ .nullable()
74
+ .default(null)
75
+ .describe('An interesting fact related to the lesson topic'),
76
+ });
77
+ //# sourceMappingURL=lesson.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lesson.js","sourceRoot":"","sources":["../../src/schemas/lesson.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { Express } from 'express';
2
+ import { Server } from 'http';
3
+ export interface ServerInstance {
4
+ app: Express;
5
+ server: Server;
6
+ port: number;
7
+ url: string;
8
+ }
9
+ export declare function startServer(): Promise<ServerInstance>;
10
+ export declare function stopServer(instance: ServerInstance): Promise<void>;
11
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAgB,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAE3C,OAAO,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AA4D9B,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,wBAAsB,WAAW,IAAI,OAAO,CAAC,cAAc,CAAC,CA0B3D;AAED,wBAAsB,UAAU,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE"}
package/dist/server.js ADDED
@@ -0,0 +1,89 @@
1
+ import express from 'express';
2
+ import fs from 'fs';
3
+ import path from 'path';
4
+ import { fileURLToPath } from 'url';
5
+ import { logger } from './logger.js';
6
+ const __filename = fileURLToPath(import.meta.url);
7
+ const __dirname = path.dirname(__filename);
8
+ // Resolve the frontend dist path
9
+ // Priority order:
10
+ // 1. DIGIMAKER_FRONTEND_PATH env var (for custom setups)
11
+ // 2. Bundled with CLI package (npm global install): @digimakers/cli/dist/frontend/browser
12
+ // 3. Monorepo sibling (development): packages/frontend/dist/frontend/browser
13
+ function resolveFrontendPath() {
14
+ // 1. Check for environment variable override
15
+ if (process.env.DIGIMAKER_FRONTEND_PATH) {
16
+ const envPath = process.env.DIGIMAKER_FRONTEND_PATH;
17
+ if (fs.existsSync(envPath)) {
18
+ logger.debug(`[Server] Using frontend from DIGIMAKER_FRONTEND_PATH: ${envPath}`);
19
+ return envPath;
20
+ }
21
+ logger.warn(`[Server] DIGIMAKER_FRONTEND_PATH set but path not found: ${envPath}`);
22
+ }
23
+ // 2. Check if running from CLI package (npm global install)
24
+ // When installed globally, the structure can vary based on npm hoisting
25
+ // Frontend is bundled at @digimakers/cli/dist/frontend/browser
26
+ const cliModulePaths = [
27
+ // npm global install (hoisted): @digimakers/core and @digimakers/cli are siblings
28
+ path.resolve(__dirname, '../cli/dist/frontend/browser'),
29
+ path.resolve(__dirname, '../../cli/dist/frontend/browser'),
30
+ // npm global install (nested): core is inside cli's node_modules
31
+ path.resolve(__dirname, '../../../../dist/frontend/browser'),
32
+ path.resolve(__dirname, '../../../dist/frontend/browser'),
33
+ // Same directory (if frontend is bundled with core)
34
+ path.resolve(__dirname, './frontend/browser'),
35
+ path.resolve(__dirname, '../frontend/browser'),
36
+ ];
37
+ for (const cliPath of cliModulePaths) {
38
+ if (fs.existsSync(cliPath)) {
39
+ logger.debug(`[Server] Using bundled frontend from CLI package: ${cliPath}`);
40
+ return cliPath;
41
+ }
42
+ }
43
+ // 3. Monorepo development: sibling frontend package
44
+ const monorepoPath = path.resolve(__dirname, '../../frontend/dist/frontend/browser');
45
+ if (fs.existsSync(monorepoPath)) {
46
+ logger.debug(`[Server] Using frontend from monorepo: ${monorepoPath}`);
47
+ return monorepoPath;
48
+ }
49
+ // Fallback: return monorepo path and let it fail with a clear error
50
+ logger.error(`[Server] Frontend assets not found. Checked paths:`);
51
+ logger.error(` - ${cliModulePaths.join('\n - ')}`);
52
+ logger.error(` - ${monorepoPath}`);
53
+ return monorepoPath;
54
+ }
55
+ export async function startServer() {
56
+ const app = express();
57
+ const frontendPath = resolveFrontendPath();
58
+ app.use(express.static(frontendPath));
59
+ app.get('/{*path}', (req, res) => {
60
+ res.sendFile(path.join(frontendPath, 'index.html'));
61
+ });
62
+ return new Promise((resolve, reject) => {
63
+ const server = app.listen(0, () => {
64
+ const address = server.address();
65
+ if (!address || typeof address === 'string') {
66
+ reject(new Error('Failed to get server address'));
67
+ return;
68
+ }
69
+ const port = address.port;
70
+ const url = `http://localhost:${port}`;
71
+ logger.info(`[Server] Running at ${url}`);
72
+ resolve({ app, server, port, url });
73
+ });
74
+ server.on('error', reject);
75
+ });
76
+ }
77
+ export async function stopServer(instance) {
78
+ return new Promise((resolve, reject) => {
79
+ instance.server.close((err) => {
80
+ if (err)
81
+ reject(err);
82
+ else {
83
+ logger.info('[Server] Stopped');
84
+ resolve();
85
+ }
86
+ });
87
+ });
88
+ }
89
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,58 @@
1
+ {
2
+ "name": "@digimakers/core",
3
+ "version": "0.1.4",
4
+ "description": "Core library for Digimaker - docx to PDF conversion",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./schemas": {
14
+ "types": "./dist/schemas/index.d.ts",
15
+ "import": "./dist/schemas/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist"
22
+ },
23
+ "dependencies": {
24
+ "@ai-sdk/google": "^3.0.10",
25
+ "ai": "6.0.39",
26
+ "dotenv": "^17.2.3",
27
+ "express": "5.2.1",
28
+ "mammoth": "^1.8.0",
29
+ "pino": "^10.2.0",
30
+ "pino-pretty": "^13.1.3",
31
+ "puppeteer": "24.35.0",
32
+ "zod": "4.3.5"
33
+ },
34
+ "devDependencies": {
35
+ "@types/express": "5.0.6",
36
+ "@types/node": "24.0.0",
37
+ "typescript": "^5.5.0"
38
+ },
39
+ "files": [
40
+ "dist/**/*"
41
+ ],
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "git+https://github.com/jenul-ferdinand/digimaker.git",
46
+ "directory": "packages/core"
47
+ },
48
+ "bugs": {
49
+ "url": "https://github.com/jenul-ferdinand/digimaker/issues"
50
+ },
51
+ "homepage": "https://github.com/jenul-ferdinand/digimaker#readme",
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "engines": {
56
+ "node": ">=18.0.0"
57
+ }
58
+ }