-
Notifications
You must be signed in to change notification settings - Fork 66
Expand file tree
/
Copy pathbuild.mjs
More file actions
195 lines (183 loc) · 6.41 KB
/
build.mjs
File metadata and controls
195 lines (183 loc) · 6.41 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
import * as esbuild from 'esbuild';
import {copyFileSync, existsSync, mkdirSync} from 'fs';
import {builtinModules} from 'module';
import {resolve} from 'path';
// Plugin to stub out optional dependencies
const stubPlugin = {
name: 'stub',
setup(build) {
build.onResolve({filter: /^react-devtools-core$/}, () => ({
path: 'react-devtools-core',
namespace: 'stub-ns',
}));
build.onResolve({filter: /^@napi-rs\/canvas$/}, () => ({
path: '@napi-rs/canvas',
namespace: 'stub-ns',
}));
build.onLoad({filter: /.*/, namespace: 'stub-ns'}, () => ({
contents: 'export default {}',
}));
},
};
// Create bundle directory
if (!existsSync('bundle')) {
mkdirSync('bundle');
}
await esbuild.build({
entryPoints: ['dist/cli.js'],
bundle: true,
platform: 'node',
target: 'node16',
format: 'esm',
outfile: 'bundle/cli.mjs',
banner: {
js: `import { createRequire as _createRequire } from 'module';
import { fileURLToPath as _fileURLToPath } from 'url';
const __snow_raw_require = _createRequire(import.meta.url);
const require = Object.assign((moduleName) => {
const moduleValue = __snow_raw_require(moduleName);
if (moduleName === 'fetch-cookie' && typeof moduleValue !== 'function' && typeof moduleValue?.default === 'function') {
return moduleValue.default;
}
return moduleValue;
}, __snow_raw_require);
const __filename = _fileURLToPath(import.meta.url);
const __dirname = _fileURLToPath(new URL('.', import.meta.url));
// Pre-load @microsoft/signalr runtime dependencies into require.cache.
// SignalR uses dynamic require() which esbuild cannot bundle statically.
// Avoid eager-loading node-fetch on Node 18+, because that triggers
// DEP0040 through node-fetch -> whatwg-url -> tr46 -> punycode even though
// SignalR will use the native fetch implementation when it already exists.
const __signalr_deps = {
'abort-controller': require('abort-controller'),
'eventsource': require('eventsource'),
'fetch-cookie': require('fetch-cookie'),
'tough-cookie': require('tough-cookie'),
'ws': require('ws')
};
if (typeof globalThis.fetch === 'undefined') {
__signalr_deps['node-fetch'] = require('node-fetch');
}
// Polyfill for @microsoft/signalr dynamic require
// SignalR uses: const requireFunc = typeof __webpack_require__ === "function" ? __non_webpack_require__ : require;
// Keep __non_webpack_require__ aligned with our wrapped require for both branches.
const __non_webpack_require__ = require;
if (typeof globalThis.__non_webpack_require__ === 'undefined') {
globalThis.__non_webpack_require__ = require;
}
// Polyfill for undici's web API dependencies
// undici uses File, Blob, etc. which are only available in Node.js 20+
// For Node.js 16-18, we provide minimal polyfills
if (typeof globalThis.File === 'undefined') {
globalThis.File = class File {
constructor(bits, name, options) {
this.bits = bits;
this.name = name;
this.options = options;
}
};
}
if (typeof globalThis.FormData === 'undefined') {
globalThis.FormData = class FormData {
constructor() {
this._data = new Map();
}
append(key, value) {
this._data.set(key, value);
}
get(key) {
return this._data.get(key);
}
};
}
// Polyfill browser APIs required by pdfjs-dist in Node.js environment.
// pdfjs-dist uses DOMMatrix/ImageData/Path2D at module level, so these must
// exist before any bundled pdfjs code executes.
// Only stubs are needed — we only do text extraction, not rendering.
if (typeof globalThis.DOMMatrix === 'undefined') {
globalThis.DOMMatrix = class DOMMatrix {
constructor(init) {
this.a = 1; this.b = 0; this.c = 0; this.d = 1; this.e = 0; this.f = 0;
this.m11 = 1; this.m12 = 0; this.m13 = 0; this.m14 = 0;
this.m21 = 0; this.m22 = 1; this.m23 = 0; this.m24 = 0;
this.m31 = 0; this.m32 = 0; this.m33 = 1; this.m34 = 0;
this.m41 = 0; this.m42 = 0; this.m43 = 0; this.m44 = 1;
this.is2D = true; this.isIdentity = true;
if (Array.isArray(init) && init.length === 6) {
this.a = init[0]; this.b = init[1]; this.c = init[2];
this.d = init[3]; this.e = init[4]; this.f = init[5];
this.m11 = this.a; this.m12 = this.b;
this.m21 = this.c; this.m22 = this.d;
this.m41 = this.e; this.m42 = this.f;
}
}
inverse() { return new DOMMatrix(); }
multiply() { return new DOMMatrix(); }
translate() { return new DOMMatrix(); }
scale() { return new DOMMatrix(); }
rotate() { return new DOMMatrix(); }
scaleSelf() { return this; }
translateSelf() { return this; }
transformPoint() { return { x: 0, y: 0, z: 0, w: 1 }; }
};
}
if (typeof globalThis.ImageData === 'undefined') {
globalThis.ImageData = class ImageData {
constructor(sw, sh) {
if (sw instanceof Uint8ClampedArray) {
this.data = sw; this.width = sh; this.height = sw.length / (4 * sh);
} else {
this.width = sw; this.height = sh;
this.data = new Uint8ClampedArray(sw * sh * 4);
}
}
};
}
if (typeof globalThis.Path2D === 'undefined') {
globalThis.Path2D = class Path2D {
constructor() {}
addPath() {} closePath() {} moveTo() {} lineTo() {}
bezierCurveTo() {} quadraticCurveTo() {} arc() {} arcTo() {}
ellipse() {} rect() {}
};
}`,
},
external: [
// Only Node.js built-in modules should be external
...builtinModules,
...builtinModules.map(m => `node:${m}`),
// Optional native dependencies (dynamically imported in code)
'sharp',
// SSH2 includes native .node addons that cannot be bundled by esbuild
'ssh2',
'cpu-features',
// Note: katex and markdown-it-math are bundled (not external)
// Note: @microsoft/signalr dependencies (abort-controller, eventsource, fetch-cookie, node-fetch, tough-cookie) are NOT bundled
// They are dynamically required at runtime and must be in package.json dependencies
],
alias: {
'ink': resolve('source/vendor/ink/src/index.ts'),
},
plugins: [stubPlugin],
minify: false,
sourcemap: false,
metafile: true,
logLevel: 'info',
});
// Copy WASM files
copyFileSync(
'node_modules/sql.js/dist/sql-wasm.wasm',
'bundle/sql-wasm.wasm',
);
copyFileSync(
'node_modules/tiktoken/tiktoken_bg.wasm',
'bundle/tiktoken_bg.wasm',
);
// Copy PDF.js worker file for PDF parsing
copyFileSync(
'node_modules/pdfjs-dist/build/pdf.worker.mjs',
'bundle/pdf.worker.mjs',
);
// Copy package.json to bundle directory for version reading
copyFileSync('package.json', 'bundle/package.json');
console.log('✓ Bundle created successfully');