@vue-skuilder/cli 0.1.4 ā 0.1.6
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/CLAUDE.md +84 -0
- package/dist/cli.js +7 -11
- package/dist/cli.js.map +1 -1
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +87 -12
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pack.d.ts +3 -0
- package/dist/commands/pack.d.ts.map +1 -0
- package/dist/commands/pack.js +141 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/types.d.ts +29 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +192 -16
- package/dist/types.js.map +1 -1
- package/dist/utils/pack-courses.d.ts +13 -0
- package/dist/utils/pack-courses.d.ts.map +1 -0
- package/dist/utils/pack-courses.js +54 -0
- package/dist/utils/pack-courses.js.map +1 -0
- package/dist/utils/prompts.d.ts +5 -2
- package/dist/utils/prompts.d.ts.map +1 -1
- package/dist/utils/prompts.js +272 -72
- package/dist/utils/prompts.js.map +1 -1
- package/dist/utils/template.d.ts +4 -0
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +93 -11
- package/dist/utils/template.js.map +1 -1
- package/package.json +5 -3
- package/src/cli.ts +8 -12
- package/src/commands/init.ts +128 -22
- package/src/commands/pack.ts +186 -0
- package/src/types.ts +230 -18
- package/src/utils/pack-courses.ts +77 -0
- package/src/utils/prompts.ts +321 -81
- package/src/utils/template.ts +129 -41
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChD,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;AAE3C;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB;IACxC,8CAA8C;IAC9C,IAAI,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;IAElD,OAAO,UAAU,KAAK,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,CAAC,CAAC;QAChG,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;YAChC,OAAO,eAAe,CAAC;QACzB,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,MAAM,IAAI,KAAK,
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../src/utils/template.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"publishConfig": {
|
|
4
4
|
"access": "public"
|
|
5
5
|
},
|
|
6
|
-
"version": "0.1.
|
|
6
|
+
"version": "0.1.6",
|
|
7
7
|
"type": "module",
|
|
8
8
|
"description": "CLI scaffolding tool for vue-skuilder projects",
|
|
9
9
|
"bin": {
|
|
@@ -33,11 +33,13 @@
|
|
|
33
33
|
"course"
|
|
34
34
|
],
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@vue-skuilder/
|
|
36
|
+
"@vue-skuilder/db": "0.1.6",
|
|
37
|
+
"@vue-skuilder/standalone-ui": "^0.1.6",
|
|
37
38
|
"chalk": "^5.3.0",
|
|
38
39
|
"commander": "^11.0.0",
|
|
39
40
|
"fs-extra": "^11.2.0",
|
|
40
|
-
"inquirer": "^9.2.0"
|
|
41
|
+
"inquirer": "^9.2.0",
|
|
42
|
+
"pouchdb": "^9.0.0"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@types/fs-extra": "^11.0.0",
|
package/src/cli.ts
CHANGED
|
@@ -4,7 +4,8 @@ import { Command } from 'commander';
|
|
|
4
4
|
import { readFileSync } from 'fs';
|
|
5
5
|
import { fileURLToPath } from 'url';
|
|
6
6
|
import { dirname, join } from 'path';
|
|
7
|
-
import {
|
|
7
|
+
import { createInitCommand } from './commands/init.js';
|
|
8
|
+
import { createPackCommand } from './commands/pack.js';
|
|
8
9
|
|
|
9
10
|
const __filename = fileURLToPath(import.meta.url);
|
|
10
11
|
const __dirname = dirname(__filename);
|
|
@@ -20,16 +21,9 @@ program
|
|
|
20
21
|
.description('CLI tool for scaffolding Skuilder course applications')
|
|
21
22
|
.version(packageJson.version);
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
.description('create a new Skuilder course application')
|
|
27
|
-
.option('--data-layer <type>', 'data layer type (static|dynamic)', 'dynamic')
|
|
28
|
-
.option('--theme <name>', 'theme name (default|medical|educational|corporate)', 'default')
|
|
29
|
-
.option('--no-interactive', 'skip interactive prompts')
|
|
30
|
-
.option('--couchdb-url <url>', 'CouchDB server URL (for dynamic data layer)')
|
|
31
|
-
.option('--course-id <id>', 'course ID to import (for dynamic data layer)')
|
|
32
|
-
.action(initCommand);
|
|
24
|
+
// Add commands
|
|
25
|
+
program.addCommand(createInitCommand());
|
|
26
|
+
program.addCommand(createPackCommand());
|
|
33
27
|
|
|
34
28
|
program.on('--help', () => {
|
|
35
29
|
console.log('');
|
|
@@ -37,6 +31,8 @@ program.on('--help', () => {
|
|
|
37
31
|
console.log(' $ skuilder init my-anatomy-course');
|
|
38
32
|
console.log(' $ skuilder init biology-101 --data-layer=static --theme=medical');
|
|
39
33
|
console.log(' $ skuilder init physics --no-interactive --data-layer=dynamic');
|
|
34
|
+
console.log(' $ skuilder pack sample-course-id');
|
|
35
|
+
console.log(' $ skuilder pack biology-101 --server http://localhost:5984 --username admin');
|
|
40
36
|
});
|
|
41
37
|
|
|
42
|
-
program.parse();
|
|
38
|
+
program.parse();
|
package/src/commands/init.ts
CHANGED
|
@@ -1,24 +1,59 @@
|
|
|
1
|
-
import { existsSync } from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
1
|
import chalk from 'chalk';
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { readFileSync } from 'fs';
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { existsSync, readFileSync } from 'fs';
|
|
4
|
+
import path, { dirname, join } from 'path';
|
|
8
5
|
import { fileURLToPath } from 'url';
|
|
9
|
-
import {
|
|
6
|
+
import { CliOptions, PREDEFINED_THEMES } from '../types.js';
|
|
7
|
+
import {
|
|
8
|
+
confirmProjectCreation,
|
|
9
|
+
displayThemePreview,
|
|
10
|
+
gatherProjectConfig,
|
|
11
|
+
} from '../utils/prompts.js';
|
|
12
|
+
import { processTemplate } from '../utils/template.js';
|
|
13
|
+
import { packCourses } from '../utils/pack-courses.js';
|
|
10
14
|
|
|
11
15
|
const __filename = fileURLToPath(import.meta.url);
|
|
12
16
|
const __dirname = dirname(__filename);
|
|
13
17
|
|
|
14
|
-
export
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
export function createInitCommand(): Command {
|
|
19
|
+
return new Command('init')
|
|
20
|
+
.argument('<project-name>', 'name of the project to create')
|
|
21
|
+
.description('create a new Skuilder course application')
|
|
22
|
+
.option('--data-layer <type>', 'data layer type (static|dynamic)', 'dynamic')
|
|
23
|
+
.option('--theme <name>', 'theme name (default|medical|educational|corporate)', 'default')
|
|
24
|
+
.option('--no-interactive', 'skip interactive prompts')
|
|
25
|
+
.option('--couchdb-url <url>', 'CouchDB server URL (for dynamic data layer)')
|
|
26
|
+
.option('--course-id <id>', 'course ID to import (for dynamic data layer)')
|
|
27
|
+
.action(initCommand);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
interface InitOptions {
|
|
31
|
+
dataLayer: string;
|
|
32
|
+
theme: string;
|
|
33
|
+
interactive: boolean;
|
|
34
|
+
couchdbUrl?: string;
|
|
35
|
+
courseId?: string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function initCommand(projectName: string, options: InitOptions): Promise<void> {
|
|
18
39
|
try {
|
|
19
40
|
// Validate project name
|
|
20
41
|
if (!isValidProjectName(projectName)) {
|
|
21
|
-
console.error(
|
|
42
|
+
console.error(
|
|
43
|
+
chalk.red('ā Invalid project name. Use only letters, numbers, hyphens, and underscores.')
|
|
44
|
+
);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// Validate theme option
|
|
49
|
+
const validThemes = Object.keys(PREDEFINED_THEMES);
|
|
50
|
+
if (!validThemes.includes(options.theme)) {
|
|
51
|
+
console.error(
|
|
52
|
+
chalk.red(`ā Invalid theme: "${options.theme}"`)
|
|
53
|
+
);
|
|
54
|
+
console.error(
|
|
55
|
+
chalk.yellow(`Valid themes: ${validThemes.join(', ')}`)
|
|
56
|
+
);
|
|
22
57
|
process.exit(1);
|
|
23
58
|
}
|
|
24
59
|
|
|
@@ -34,11 +69,20 @@ export async function initCommand(
|
|
|
34
69
|
const packageJson = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
35
70
|
const cliVersion = packageJson.version;
|
|
36
71
|
|
|
72
|
+
// Convert options to CliOptions format
|
|
73
|
+
const cliOptions: CliOptions = {
|
|
74
|
+
dataLayer: options.dataLayer as 'static' | 'dynamic',
|
|
75
|
+
theme: options.theme as 'default' | 'medical' | 'educational' | 'corporate',
|
|
76
|
+
interactive: options.interactive,
|
|
77
|
+
couchdbUrl: options.couchdbUrl,
|
|
78
|
+
courseId: options.courseId,
|
|
79
|
+
};
|
|
80
|
+
|
|
37
81
|
// Gather project configuration
|
|
38
|
-
const config = await gatherProjectConfig(projectName,
|
|
82
|
+
const config = await gatherProjectConfig(projectName, cliOptions);
|
|
39
83
|
|
|
40
84
|
// Confirm project creation (only in interactive mode)
|
|
41
|
-
if (
|
|
85
|
+
if (cliOptions.interactive) {
|
|
42
86
|
const confirmed = await confirmProjectCreation(config, projectPath);
|
|
43
87
|
if (!confirmed) {
|
|
44
88
|
console.log(chalk.yellow('Project creation cancelled.'));
|
|
@@ -51,26 +95,88 @@ export async function initCommand(
|
|
|
51
95
|
// Process template and create project
|
|
52
96
|
await processTemplate(projectPath, config, cliVersion);
|
|
53
97
|
|
|
98
|
+
// Import course data if requested for static data layer
|
|
99
|
+
if (config.dataLayerType === 'static' && config.importCourseData && config.importCourseIds && config.importCourseIds.length > 0) {
|
|
100
|
+
console.log(chalk.cyan('\nš¦ Importing course data...\n'));
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
await packCourses({
|
|
104
|
+
server: config.importServerUrl!,
|
|
105
|
+
username: config.importUsername,
|
|
106
|
+
password: config.importPassword,
|
|
107
|
+
courseIds: config.importCourseIds,
|
|
108
|
+
targetProjectDir: projectPath
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
console.log(chalk.green('ā
Course data imported successfully!'));
|
|
112
|
+
} catch (error: unknown) {
|
|
113
|
+
console.error(chalk.red('\nā Failed to import course data:'));
|
|
114
|
+
let errorMessage = 'Unknown error';
|
|
115
|
+
if (error instanceof Error) {
|
|
116
|
+
errorMessage = error.message;
|
|
117
|
+
} else if (typeof error === 'string') {
|
|
118
|
+
errorMessage = error;
|
|
119
|
+
} else if (error && typeof error === 'object' && 'message' in error) {
|
|
120
|
+
errorMessage = String((error as { message: unknown }).message);
|
|
121
|
+
}
|
|
122
|
+
console.error(chalk.red(errorMessage));
|
|
123
|
+
console.log(chalk.yellow('\nā ļø Project created successfully, but without course data.'));
|
|
124
|
+
console.log(chalk.yellow('You can import course data later using the pack command.'));
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
54
128
|
// Success message
|
|
55
129
|
console.log(chalk.green('\nš Project created successfully!\n'));
|
|
56
|
-
|
|
130
|
+
|
|
131
|
+
// Show theme preview
|
|
132
|
+
displayThemePreview(config.theme.name);
|
|
133
|
+
|
|
134
|
+
console.log(chalk.cyan('\nNext steps:'));
|
|
57
135
|
console.log(` ${chalk.white('cd')} ${projectName}`);
|
|
58
136
|
console.log(` ${chalk.white('npm install')}`);
|
|
59
137
|
console.log(` ${chalk.white('npm run dev')}`);
|
|
60
138
|
console.log('');
|
|
61
139
|
|
|
62
140
|
if (config.dataLayerType === 'couch') {
|
|
63
|
-
console.log(
|
|
141
|
+
console.log(
|
|
142
|
+
chalk.yellow('š Note: Make sure your CouchDB server is running and accessible.')
|
|
143
|
+
);
|
|
64
144
|
if (config.course) {
|
|
65
|
-
console.log(
|
|
145
|
+
console.log(
|
|
146
|
+
chalk.yellow(`š Course ID "${config.course}" will be loaded from the database.`)
|
|
147
|
+
);
|
|
66
148
|
}
|
|
67
149
|
} else {
|
|
68
|
-
|
|
150
|
+
if (config.importCourseIds && config.importCourseIds.length > 0) {
|
|
151
|
+
console.log(
|
|
152
|
+
chalk.yellow(
|
|
153
|
+
`š Note: This project uses static data with ${config.importCourseIds.length} imported course(s).`
|
|
154
|
+
)
|
|
155
|
+
);
|
|
156
|
+
console.log(
|
|
157
|
+
chalk.yellow(
|
|
158
|
+
`š Course data is available in the public/static-courses/ directory.`
|
|
159
|
+
)
|
|
160
|
+
);
|
|
161
|
+
} else {
|
|
162
|
+
console.log(
|
|
163
|
+
chalk.yellow(
|
|
164
|
+
'š Note: This project uses static data. No course data has been imported.'
|
|
165
|
+
)
|
|
166
|
+
);
|
|
167
|
+
}
|
|
69
168
|
}
|
|
70
|
-
|
|
71
|
-
} catch (error) {
|
|
169
|
+
} catch (error: unknown) {
|
|
72
170
|
console.error(chalk.red('\nā Failed to create project:'));
|
|
73
|
-
|
|
171
|
+
let errorMessage = 'Unknown error';
|
|
172
|
+
if (error instanceof Error) {
|
|
173
|
+
errorMessage = error.message;
|
|
174
|
+
} else if (typeof error === 'string') {
|
|
175
|
+
errorMessage = error;
|
|
176
|
+
} else if (error && typeof error === 'object' && 'message' in error) {
|
|
177
|
+
errorMessage = String((error as { message: unknown }).message);
|
|
178
|
+
}
|
|
179
|
+
console.error(chalk.red(errorMessage));
|
|
74
180
|
process.exit(1);
|
|
75
181
|
}
|
|
76
182
|
}
|
|
@@ -80,4 +186,4 @@ function isValidProjectName(name: string): boolean {
|
|
|
80
186
|
// Must start with a letter or number
|
|
81
187
|
const validNameRegex = /^[a-zA-Z0-9][a-zA-Z0-9-_]*$/;
|
|
82
188
|
return validNameRegex.test(name) && name.length > 0 && name.length <= 214;
|
|
83
|
-
}
|
|
189
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import PouchDB from 'pouchdb';
|
|
3
|
+
import fs from 'fs-extra';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import chalk from 'chalk';
|
|
6
|
+
import { CouchDBToStaticPacker, AttachmentData } from '@vue-skuilder/db/packer';
|
|
7
|
+
|
|
8
|
+
export function createPackCommand(): Command {
|
|
9
|
+
return new Command('pack')
|
|
10
|
+
.description('Pack a CouchDB course into static files')
|
|
11
|
+
.argument('<courseId>', 'Course ID to pack')
|
|
12
|
+
.option('-s, --server <url>', 'CouchDB server URL', 'http://localhost:5984')
|
|
13
|
+
.option('-u, --username <username>', 'CouchDB username')
|
|
14
|
+
.option('-p, --password <password>', 'CouchDB password')
|
|
15
|
+
.option('-o, --output <dir>', 'Output directory', './static-courses')
|
|
16
|
+
.option('-c, --chunk-size <size>', 'Documents per chunk', '1000')
|
|
17
|
+
.option('--no-attachments', 'Exclude attachments')
|
|
18
|
+
.action(packCourse);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
interface PackOptions {
|
|
22
|
+
server: string;
|
|
23
|
+
username?: string;
|
|
24
|
+
password?: string;
|
|
25
|
+
output: string;
|
|
26
|
+
chunkSize: string;
|
|
27
|
+
noAttachments: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function packCourse(courseId: string, options: PackOptions) {
|
|
31
|
+
try {
|
|
32
|
+
console.log(chalk.cyan(`š§ Packing course: ${courseId}`));
|
|
33
|
+
|
|
34
|
+
// Validate courseId
|
|
35
|
+
if (!courseId || courseId.trim() === '') {
|
|
36
|
+
throw new Error('Course ID is required');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Connect to CouchDB
|
|
40
|
+
const dbUrl = `${options.server}/coursedb-${courseId}`;
|
|
41
|
+
const dbOptions: Record<string, unknown> = {};
|
|
42
|
+
|
|
43
|
+
if (options.username && options.password) {
|
|
44
|
+
dbOptions.auth = {
|
|
45
|
+
username: options.username,
|
|
46
|
+
password: options.password,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
console.log(chalk.gray(`š” Connecting to: ${dbUrl}`));
|
|
51
|
+
const sourceDB = new PouchDB(dbUrl, dbOptions);
|
|
52
|
+
|
|
53
|
+
// Test connection
|
|
54
|
+
try {
|
|
55
|
+
await sourceDB.info();
|
|
56
|
+
console.log(chalk.green('ā
Connected to database'));
|
|
57
|
+
} catch (error: unknown) {
|
|
58
|
+
let errorMessage = 'Unknown error';
|
|
59
|
+
if (error instanceof Error) {
|
|
60
|
+
errorMessage = error.message;
|
|
61
|
+
} else if (typeof error === 'string') {
|
|
62
|
+
errorMessage = error;
|
|
63
|
+
} else if (error && typeof error === 'object' && 'message' in error) {
|
|
64
|
+
errorMessage = String((error as { message: unknown }).message);
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Failed to connect to database: ${errorMessage}`);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Configure packer (data transformation only)
|
|
70
|
+
const packerConfig = {
|
|
71
|
+
chunkSize: parseInt(options.chunkSize),
|
|
72
|
+
includeAttachments: !options.noAttachments,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
console.log(chalk.gray(`š¦ Chunk size: ${packerConfig.chunkSize} documents`));
|
|
76
|
+
console.log(chalk.gray(`š Include attachments: ${packerConfig.includeAttachments}`));
|
|
77
|
+
|
|
78
|
+
// Pack the course (data transformation)
|
|
79
|
+
console.log(chalk.cyan('š Processing course data...'));
|
|
80
|
+
const packer = new CouchDBToStaticPacker(packerConfig);
|
|
81
|
+
const packedData = await packer.packCourse(sourceDB, courseId);
|
|
82
|
+
|
|
83
|
+
// Create output directory
|
|
84
|
+
const outputDir = path.resolve(options.output, courseId);
|
|
85
|
+
await fs.ensureDir(outputDir);
|
|
86
|
+
console.log(chalk.gray(`š Output directory: ${outputDir}`));
|
|
87
|
+
|
|
88
|
+
// Write files
|
|
89
|
+
await writePackedData(packedData, outputDir);
|
|
90
|
+
|
|
91
|
+
// Success summary
|
|
92
|
+
console.log(chalk.green('\nā
Successfully packed course!'));
|
|
93
|
+
console.log(chalk.white(`š Course: ${packedData.manifest.courseName}`));
|
|
94
|
+
console.log(chalk.white(`š Documents: ${packedData.manifest.documentCount}`));
|
|
95
|
+
console.log(chalk.white(`šļø Chunks: ${packedData.manifest.chunks.length}`));
|
|
96
|
+
console.log(chalk.white(`šļø Indices: ${packedData.manifest.indices.length}`));
|
|
97
|
+
if (packedData.attachments && packedData.attachments.size > 0) {
|
|
98
|
+
console.log(chalk.white(`š Attachments: ${packedData.attachments.size}`));
|
|
99
|
+
}
|
|
100
|
+
console.log(chalk.white(`š Location: ${outputDir}`));
|
|
101
|
+
|
|
102
|
+
} catch (error: unknown) {
|
|
103
|
+
console.error(chalk.red('\nā Packing failed:'));
|
|
104
|
+
let errorMessage = 'Unknown error';
|
|
105
|
+
if (error instanceof Error) {
|
|
106
|
+
errorMessage = error.message;
|
|
107
|
+
} else if (typeof error === 'string') {
|
|
108
|
+
errorMessage = error;
|
|
109
|
+
} else if (error && typeof error === 'object' && 'message' in error) {
|
|
110
|
+
errorMessage = String((error as { message: unknown }).message);
|
|
111
|
+
}
|
|
112
|
+
console.error(chalk.red(errorMessage));
|
|
113
|
+
process.exit(1);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface PackedData {
|
|
118
|
+
manifest: {
|
|
119
|
+
version: string;
|
|
120
|
+
courseId: string;
|
|
121
|
+
courseName: string;
|
|
122
|
+
lastUpdated: string;
|
|
123
|
+
documentCount: number;
|
|
124
|
+
chunks: unknown[];
|
|
125
|
+
indices: unknown[];
|
|
126
|
+
designDocs: unknown[];
|
|
127
|
+
};
|
|
128
|
+
chunks: Map<string, unknown[]>;
|
|
129
|
+
indices: Map<string, unknown>;
|
|
130
|
+
attachments?: Map<string, AttachmentData>;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
async function writePackedData(
|
|
134
|
+
packedData: PackedData,
|
|
135
|
+
outputDir: string
|
|
136
|
+
) {
|
|
137
|
+
console.log(chalk.cyan('š¾ Writing files...'));
|
|
138
|
+
|
|
139
|
+
// Write manifest
|
|
140
|
+
const manifestPath = path.join(outputDir, 'manifest.json');
|
|
141
|
+
await fs.writeJson(manifestPath, packedData.manifest, { spaces: 2 });
|
|
142
|
+
console.log(chalk.gray(`š Wrote manifest: ${manifestPath}`));
|
|
143
|
+
|
|
144
|
+
// Create directories
|
|
145
|
+
const chunksDir = path.join(outputDir, 'chunks');
|
|
146
|
+
const indicesDir = path.join(outputDir, 'indices');
|
|
147
|
+
await fs.ensureDir(chunksDir);
|
|
148
|
+
await fs.ensureDir(indicesDir);
|
|
149
|
+
|
|
150
|
+
// Write chunks
|
|
151
|
+
let chunkCount = 0;
|
|
152
|
+
for (const [chunkId, chunkData] of packedData.chunks) {
|
|
153
|
+
const chunkPath = path.join(chunksDir, `${chunkId}.json`);
|
|
154
|
+
await fs.writeJson(chunkPath, chunkData);
|
|
155
|
+
chunkCount++;
|
|
156
|
+
}
|
|
157
|
+
console.log(chalk.gray(`š¦ Wrote ${chunkCount} chunks`));
|
|
158
|
+
|
|
159
|
+
// Write indices
|
|
160
|
+
let indexCount = 0;
|
|
161
|
+
for (const [indexName, indexData] of packedData.indices) {
|
|
162
|
+
const indexPath = path.join(indicesDir, `${indexName}.json`);
|
|
163
|
+
await fs.writeJson(indexPath, indexData, { spaces: 2 });
|
|
164
|
+
indexCount++;
|
|
165
|
+
}
|
|
166
|
+
console.log(chalk.gray(`šļø Wrote ${indexCount} indices`));
|
|
167
|
+
|
|
168
|
+
// Write attachments
|
|
169
|
+
if (packedData.attachments && packedData.attachments.size > 0) {
|
|
170
|
+
console.log(chalk.cyan('š Writing attachments...'));
|
|
171
|
+
|
|
172
|
+
let attachmentCount = 0;
|
|
173
|
+
for (const [attachmentPath, attachmentData] of packedData.attachments) {
|
|
174
|
+
const fullAttachmentPath = path.join(outputDir, attachmentPath);
|
|
175
|
+
|
|
176
|
+
// Ensure directory exists
|
|
177
|
+
await fs.ensureDir(path.dirname(fullAttachmentPath));
|
|
178
|
+
|
|
179
|
+
// Write binary file
|
|
180
|
+
await fs.writeFile(fullAttachmentPath, attachmentData.buffer);
|
|
181
|
+
attachmentCount++;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
console.log(chalk.gray(`š Wrote ${attachmentCount} attachment files`));
|
|
185
|
+
}
|
|
186
|
+
}
|