@absolutejs/absolute 0.19.0-beta.211 → 0.19.0-beta.213

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/scripts/build.ts CHANGED
@@ -1,316 +1,329 @@
1
- import { $ } from "bun";
2
- import { rm, cp, mkdir, readdir, writeFile } from "node:fs/promises";
3
- import { join, dirname, basename, resolve, relative } from "node:path";
4
- import ts from "typescript";
1
+ import { $ } from 'bun';
2
+ import { rm, cp, mkdir, readdir, writeFile } from 'node:fs/promises';
3
+ import { join, dirname, basename, resolve, relative } from 'node:path';
4
+ import ts from 'typescript';
5
5
 
6
- const DIST = "dist";
6
+ const DIST = 'dist';
7
7
 
8
8
  const SERVER_ENTRY_POINTS = [
9
- "src/index.ts",
10
- "src/build.ts",
11
- "src/angular/index.ts",
12
- "src/react/index.ts",
13
- "src/react/components/index.ts",
14
- "src/react/hooks/index.ts",
15
- "src/svelte/index.ts",
16
- "src/vue/index.ts",
17
- "src/vue/components/index.ts",
9
+ 'src/index.ts',
10
+ 'src/build.ts',
11
+ 'src/angular/index.ts',
12
+ 'src/react/index.ts',
13
+ 'src/react/components/index.ts',
14
+ 'src/react/hooks/index.ts',
15
+ 'src/svelte/index.ts',
16
+ 'src/vue/index.ts',
17
+ 'src/vue/components/index.ts'
18
18
  ];
19
19
 
20
20
  const EXTERNALS = [
21
- "react",
22
- "react-dom",
23
- "vue",
24
- "@vue/compiler-sfc",
25
- "vue/server-renderer",
26
- "svelte",
27
- "svelte/compiler",
28
- "svelte/server",
29
- "elysia",
30
- "@elysiajs/static",
31
- "@angular/compiler-cli",
32
- "@angular/core",
33
- "@angular/common",
34
- "@angular/platform-browser",
35
- "@angular/platform-server",
36
- "@angular/ssr",
37
- "zone.js",
38
- "debug",
39
- "sharp",
40
- "@absolutejs/native-linux-x64",
41
- "@absolutejs/native-linux-arm64",
42
- "@absolutejs/native-darwin-x64",
43
- "@absolutejs/native-darwin-arm64",
21
+ 'react',
22
+ 'react-dom',
23
+ 'vue',
24
+ '@vue/compiler-sfc',
25
+ 'vue/server-renderer',
26
+ 'svelte',
27
+ 'svelte/compiler',
28
+ 'svelte/server',
29
+ 'elysia',
30
+ '@elysiajs/static',
31
+ '@angular/compiler-cli',
32
+ '@angular/core',
33
+ '@angular/common',
34
+ '@angular/platform-browser',
35
+ '@angular/platform-server',
36
+ '@angular/ssr',
37
+ 'zone.js',
38
+ 'debug',
39
+ 'sharp',
40
+ '@absolutejs/native-linux-x64',
41
+ '@absolutejs/native-linux-arm64',
42
+ '@absolutejs/native-darwin-x64',
43
+ '@absolutejs/native-darwin-arm64'
44
44
  ];
45
45
 
46
46
  async function build() {
47
- console.log("Cleaning dist/...");
48
- await rm(DIST, { recursive: true, force: true });
49
-
50
- console.log("Building server entry points...");
51
- const serverBuild = await Bun.build({
52
- entrypoints: SERVER_ENTRY_POINTS,
53
- outdir: DIST,
54
- sourcemap: "linked",
55
- target: "bun",
56
- external: EXTERNALS,
57
- root: "src",
58
- });
59
-
60
- if (!serverBuild.success) {
61
- console.error("Server build failed:");
62
- for (const log of serverBuild.logs) console.error(log);
63
- process.exit(1);
64
- }
65
-
66
- console.log("Building image client (browser target)...");
67
- const imageBuild = await Bun.build({
68
- entrypoints: ["src/utils/imageClient.ts"],
69
- outdir: join(DIST, "image-client"),
70
- target: "browser",
71
- });
72
-
73
- if (!imageBuild.success) {
74
- console.error("Image client build failed:");
75
- for (const log of imageBuild.logs) console.error(log);
76
- process.exit(1);
77
- }
78
-
79
- console.log("Building React components (browser target)...");
80
- const reactBrowserBuild = await Bun.build({
81
- entrypoints: ["src/react/components/index.ts"],
82
- outdir: join(DIST, "react", "components", "browser"),
83
- target: "browser",
84
- root: "src/react/components",
85
- external: ["react", "react-dom", "react/jsx-runtime", "react/jsx-dev-runtime"],
86
- });
87
-
88
- if (!reactBrowserBuild.success) {
89
- console.error("React browser build failed:");
90
- for (const log of reactBrowserBuild.logs) console.error(log);
91
- process.exit(1);
92
- }
93
-
94
- console.log("Building CLI...");
95
- const cliBuild = await Bun.build({
96
- entrypoints: ["src/cli/index.ts"],
97
- outdir: join(DIST, "cli"),
98
- target: "bun",
99
- });
100
-
101
- if (!cliBuild.success) {
102
- console.error("CLI build failed:");
103
- for (const log of cliBuild.logs) console.error(log);
104
- process.exit(1);
105
- }
106
-
107
- console.log("Generating type declarations...");
108
- await $`tsc --emitDeclarationOnly --project tsconfig.build.json`;
109
-
110
- console.log("Copying static assets...");
111
-
112
- await mkdir(join(DIST, "dev"), { recursive: true });
113
- await cp("src/dev/client", join(DIST, "dev", "client"), { recursive: true });
114
-
115
- await mkdir(join(DIST, "svelte", "components"), { recursive: true });
116
- const svelteFiles = await readdir("src/svelte/components");
117
- for (const file of svelteFiles.filter((f) => f.endsWith(".svelte"))) {
118
- await cp(
119
- join("src", "svelte", "components", file),
120
- join(DIST, "svelte", "components", file),
121
- );
122
- }
123
-
124
- await mkdir(join(DIST, "vue", "components"), { recursive: true });
125
- const vueFiles = await readdir("src/vue/components");
126
- for (const file of vueFiles.filter((f) => f.endsWith(".vue"))) {
127
- await cp(
128
- join("src", "vue", "components", file),
129
- join(DIST, "vue", "components", file),
130
- );
131
- }
132
-
133
- // Generate .d.ts files for SFC components so consumers get type safety
134
- console.log("Generating SFC type declarations...");
135
- await generateSfcDeclarations();
136
-
137
- // Compile Angular components with partial compilation (ɵɵngDeclareComponent)
138
- // so they work in both AOT (via linker) and JIT (via runtime fallback)
139
- console.log("Compiling Angular components (partial)...");
140
- await compileAngularComponentsPartial();
141
-
142
- console.log("Verifying exports...");
143
- await verifyExports();
144
-
145
- console.log("Build complete.");
47
+ console.log('Cleaning dist/...');
48
+ await rm(DIST, { recursive: true, force: true });
49
+
50
+ console.log('Building server entry points...');
51
+ const serverBuild = await Bun.build({
52
+ entrypoints: SERVER_ENTRY_POINTS,
53
+ outdir: DIST,
54
+ sourcemap: 'linked',
55
+ target: 'bun',
56
+ external: EXTERNALS,
57
+ root: 'src'
58
+ });
59
+
60
+ if (!serverBuild.success) {
61
+ console.error('Server build failed:');
62
+ for (const log of serverBuild.logs) console.error(log);
63
+ process.exit(1);
64
+ }
65
+
66
+ console.log('Building image client (browser target)...');
67
+ const imageBuild = await Bun.build({
68
+ entrypoints: ['src/utils/imageClient.ts'],
69
+ outdir: join(DIST, 'image-client'),
70
+ target: 'browser'
71
+ });
72
+
73
+ if (!imageBuild.success) {
74
+ console.error('Image client build failed:');
75
+ for (const log of imageBuild.logs) console.error(log);
76
+ process.exit(1);
77
+ }
78
+
79
+ console.log('Building React components (browser target)...');
80
+ const reactBrowserBuild = await Bun.build({
81
+ entrypoints: ['src/react/components/index.ts'],
82
+ outdir: join(DIST, 'react', 'components', 'browser'),
83
+ target: 'browser',
84
+ root: 'src/react/components',
85
+ external: [
86
+ 'react',
87
+ 'react-dom',
88
+ 'react/jsx-runtime',
89
+ 'react/jsx-dev-runtime'
90
+ ]
91
+ });
92
+
93
+ if (!reactBrowserBuild.success) {
94
+ console.error('React browser build failed:');
95
+ for (const log of reactBrowserBuild.logs) console.error(log);
96
+ process.exit(1);
97
+ }
98
+
99
+ console.log('Building CLI...');
100
+ const cliBuild = await Bun.build({
101
+ entrypoints: ['src/cli/index.ts'],
102
+ outdir: join(DIST, 'cli'),
103
+ target: 'bun'
104
+ });
105
+
106
+ if (!cliBuild.success) {
107
+ console.error('CLI build failed:');
108
+ for (const log of cliBuild.logs) console.error(log);
109
+ process.exit(1);
110
+ }
111
+
112
+ console.log('Generating type declarations...');
113
+ await $`tsc --emitDeclarationOnly --project tsconfig.build.json`;
114
+
115
+ console.log('Copying static assets...');
116
+
117
+ await mkdir(join(DIST, 'dev'), { recursive: true });
118
+ await cp('src/dev/client', join(DIST, 'dev', 'client'), {
119
+ recursive: true
120
+ });
121
+
122
+ await mkdir(join(DIST, 'svelte', 'components'), { recursive: true });
123
+ const svelteFiles = await readdir('src/svelte/components');
124
+ for (const file of svelteFiles.filter((f) => f.endsWith('.svelte'))) {
125
+ await cp(
126
+ join('src', 'svelte', 'components', file),
127
+ join(DIST, 'svelte', 'components', file)
128
+ );
129
+ }
130
+
131
+ await mkdir(join(DIST, 'vue', 'components'), { recursive: true });
132
+ const vueFiles = await readdir('src/vue/components');
133
+ for (const file of vueFiles.filter((f) => f.endsWith('.vue'))) {
134
+ await cp(
135
+ join('src', 'vue', 'components', file),
136
+ join(DIST, 'vue', 'components', file)
137
+ );
138
+ }
139
+
140
+ // Generate .d.ts files for SFC components so consumers get type safety
141
+ console.log('Generating SFC type declarations...');
142
+ await generateSfcDeclarations();
143
+
144
+ // Compile Angular components with partial compilation (ɵɵngDeclareComponent)
145
+ // so they work in both AOT (via linker) and JIT (via runtime fallback)
146
+ console.log('Compiling Angular components (partial)...');
147
+ await compileAngularComponentsPartial();
148
+
149
+ console.log('Verifying exports...');
150
+ await verifyExports();
151
+
152
+ console.log('Build complete.');
146
153
  }
147
154
 
148
155
  async function generateSfcDeclarations() {
149
- // Svelte component declarations
150
- const svelteComponentDir = join(DIST, "svelte", "components");
151
- const svelteFiles = await readdir(svelteComponentDir);
152
- for (const file of svelteFiles.filter((f) => f.endsWith(".svelte"))) {
153
- const content = await Bun.file(join(svelteComponentDir, file)).text();
154
- const propsMatch = content.match(/\}:\s*(\w+)\s*=\s*\$props\(\)/);
155
- const propsType = propsMatch?.[1];
156
- const name = file.replace(/\.svelte$/, "");
157
-
158
- let dts: string;
159
- if (propsType === "ImageProps") {
160
- dts = `import type { ImageProps } from '../../types/image';\nimport { SvelteComponent } from 'svelte';\ndeclare const __propDef: { props: ImageProps };\ntype Props = typeof __propDef.props;\nexport default class ${name} extends SvelteComponent<Props> {}\n`;
161
- } else if (propsType) {
162
- dts = `import type { ${propsType} } from '../../types/metadata';\nimport { SvelteComponent } from 'svelte';\ndeclare const __propDef: { props: ${propsType} };\ntype Props = typeof __propDef.props;\nexport default class ${name} extends SvelteComponent<Props> {}\n`;
163
- } else {
164
- dts = `import { SvelteComponent } from 'svelte';\nexport default class ${name} extends SvelteComponent {}\n`;
165
- }
166
- await writeFile(join(svelteComponentDir, `${file}.d.ts`), dts);
167
- }
168
-
169
- // Vue component declarations
170
- const vueComponentDir = join(DIST, "vue", "components");
171
- const vueFiles = await readdir(vueComponentDir);
172
- for (const file of vueFiles.filter((f) => f.endsWith(".vue"))) {
173
- const content = await Bun.file(join(vueComponentDir, file)).text();
174
- const name = file.replace(/\.vue$/, "");
175
-
176
- // Check if it uses defineProps<ImageProps> or inline props
177
- const hasImageProps = content.includes("ImageProps") || content.includes("defineProps<{");
178
- let dts: string;
179
- if (name === "Image" || hasImageProps) {
180
- dts = `import type { ImageProps } from '../../types/image';\nimport { DefineComponent } from 'vue';\ndeclare const _default: DefineComponent<ImageProps>;\nexport default _default;\n`;
181
- } else {
182
- dts = `import { DefineComponent } from 'vue';\ndeclare const _default: DefineComponent;\nexport default _default;\n`;
183
- }
184
- await writeFile(join(vueComponentDir, `${file}.d.ts`), dts);
185
- }
156
+ // Svelte component declarations
157
+ const svelteComponentDir = join(DIST, 'svelte', 'components');
158
+ const svelteFiles = await readdir(svelteComponentDir);
159
+ for (const file of svelteFiles.filter((f) => f.endsWith('.svelte'))) {
160
+ const content = await Bun.file(join(svelteComponentDir, file)).text();
161
+ const propsMatch = content.match(/\}:\s*(\w+)\s*=\s*\$props\(\)/);
162
+ const propsType = propsMatch?.[1];
163
+ const name = file.replace(/\.svelte$/, '');
164
+
165
+ let dts: string;
166
+ if (propsType === 'ImageProps') {
167
+ dts = `import type { ImageProps } from '../../types/image';\nimport { SvelteComponent } from 'svelte';\ndeclare const __propDef: { props: ImageProps };\ntype Props = typeof __propDef.props;\nexport default class ${name} extends SvelteComponent<Props> {}\n`;
168
+ } else if (propsType) {
169
+ dts = `import type { ${propsType} } from '../../types/metadata';\nimport { SvelteComponent } from 'svelte';\ndeclare const __propDef: { props: ${propsType} };\ntype Props = typeof __propDef.props;\nexport default class ${name} extends SvelteComponent<Props> {}\n`;
170
+ } else {
171
+ dts = `import { SvelteComponent } from 'svelte';\nexport default class ${name} extends SvelteComponent {}\n`;
172
+ }
173
+ await writeFile(join(svelteComponentDir, `${file}.d.ts`), dts);
174
+ }
175
+
176
+ // Vue component declarations
177
+ const vueComponentDir = join(DIST, 'vue', 'components');
178
+ const vueFiles = await readdir(vueComponentDir);
179
+ for (const file of vueFiles.filter((f) => f.endsWith('.vue'))) {
180
+ const content = await Bun.file(join(vueComponentDir, file)).text();
181
+ const name = file.replace(/\.vue$/, '');
182
+
183
+ // Check if it uses defineProps<ImageProps> or inline props
184
+ const hasImageProps =
185
+ content.includes('ImageProps') || content.includes('defineProps<{');
186
+ let dts: string;
187
+ if (name === 'Image' || hasImageProps) {
188
+ dts = `import type { ImageProps } from '../../types/image';\nimport { DefineComponent } from 'vue';\ndeclare const _default: DefineComponent<ImageProps>;\nexport default _default;\n`;
189
+ } else {
190
+ dts = `import { DefineComponent } from 'vue';\ndeclare const _default: DefineComponent;\nexport default _default;\n`;
191
+ }
192
+ await writeFile(join(vueComponentDir, `${file}.d.ts`), dts);
193
+ }
186
194
  }
187
195
 
188
196
  async function compileAngularComponentsPartial() {
189
- const { readConfiguration, performCompilation, EmitFlags } = await import(
190
- "@angular/compiler-cli"
191
- );
192
-
193
- const finalDir = join(DIST, "angular", "components");
194
- await mkdir(finalDir, { recursive: true });
195
-
196
- // Use a temp output dir outside dist/ to avoid conflicts with existing compiled files
197
- const tmpDir = ".angular-partial-tmp";
198
- const outDir = join(tmpDir, "out");
199
- const srcDir = join(tmpDir, "src");
200
- await mkdir(outDir, { recursive: true });
201
- await mkdir(srcDir, { recursive: true });
202
-
203
- const srcFiles = await readdir("src/angular/components");
204
- for (const file of srcFiles.filter((f) => f.endsWith(".ts"))) {
205
- let content = await Bun.file(join("src", "angular", "components", file)).text();
206
- content = content.replace(
207
- /from\s+(['"])\.\.\/\.\.\/utils\/imageProcessing['"]/g,
208
- "from $1@absolutejs/absolute/image$1",
209
- );
210
- await Bun.write(join(srcDir, file), content);
211
- }
212
-
213
- const config = readConfiguration("./tsconfig.json");
214
- const options = {
215
- ...config.options,
216
- compilationMode: "partial" as const,
217
- declaration: false,
218
- emitDecoratorMetadata: true,
219
- experimentalDecorators: true,
220
- module: ts.ModuleKind.ESNext,
221
- moduleResolution: ts.ModuleResolutionKind.Bundler,
222
- newLine: ts.NewLineKind.LineFeed,
223
- outDir,
224
- rootDir: resolve("."),
225
- skipLibCheck: true,
226
- suppressOutputPathCheck: true,
227
- target: ts.ScriptTarget.ES2022,
228
- };
229
-
230
- const host = ts.createCompilerHost(options);
231
-
232
- // Capture only files emitted from our source dir (not external deps like imageClient)
233
- const emitted: Record<string, string> = {};
234
- const resolvedSrcInOut = resolve(outDir, relative(resolve("."), resolve(srcDir)));
235
- host.writeFile = (fileName, text) => {
236
- const absFileName = resolve(fileName);
237
- if (!absFileName.startsWith(resolvedSrcInOut)) return;
238
- const rel = absFileName.substring(resolvedSrcInOut.length + 1);
239
- emitted[rel] = text;
240
- };
241
-
242
- const rootNames = srcFiles
243
- .filter((f) => f.endsWith(".ts"))
244
- .map((f) => resolve(srcDir, f));
245
-
246
- const { diagnostics } = performCompilation({
247
- emitFlags: EmitFlags.Default,
248
- host,
249
- options,
250
- rootNames,
251
- });
252
-
253
- const errors = diagnostics.filter(
254
- (d: ts.Diagnostic) => d.category === ts.DiagnosticCategory.Error,
255
- );
256
- if (errors.length > 0) {
257
- console.error("Angular partial compilation errors:");
258
- for (const d of errors) {
259
- console.error(ts.flattenDiagnosticMessageText(d.messageText, "\n"));
260
- }
261
- process.exit(1);
262
- }
263
-
264
- // Copy emitted JS files to final dir, adding .js extensions to relative imports
265
- for (const [fileName, content] of Object.entries(emitted)) {
266
- if (!fileName.endsWith(".js")) continue;
267
- const processed = content.replace(
268
- /from\s+(['"])(\.\.?\/[^'"]+)(\1)/g,
269
- (match, quote, path) => {
270
- if (!path.match(/\.(js|ts|mjs|cjs)$/)) {
271
- return `from ${quote}${path}.js${quote}`;
272
- }
273
- return match;
274
- },
275
- );
276
- await writeFile(join(finalDir, fileName), processed);
277
- }
278
-
279
- // Clean up temp dir
280
- await rm(tmpDir, { recursive: true, force: true });
197
+ const { readConfiguration, performCompilation, EmitFlags } = await import(
198
+ '@angular/compiler-cli'
199
+ );
200
+
201
+ const finalDir = join(DIST, 'angular', 'components');
202
+ await mkdir(finalDir, { recursive: true });
203
+
204
+ // Use a temp output dir outside dist/ to avoid conflicts with existing compiled files
205
+ const tmpDir = '.angular-partial-tmp';
206
+ const outDir = join(tmpDir, 'out');
207
+ const srcDir = join(tmpDir, 'src');
208
+ await mkdir(outDir, { recursive: true });
209
+ await mkdir(srcDir, { recursive: true });
210
+
211
+ const srcFiles = await readdir('src/angular/components');
212
+ for (const file of srcFiles.filter((f) => f.endsWith('.ts'))) {
213
+ let content = await Bun.file(
214
+ join('src', 'angular', 'components', file)
215
+ ).text();
216
+ content = content.replace(
217
+ /from\s+(['"])\.\.\/\.\.\/utils\/imageProcessing['"]/g,
218
+ 'from $1@absolutejs/absolute/image$1'
219
+ );
220
+ await Bun.write(join(srcDir, file), content);
221
+ }
222
+
223
+ const config = readConfiguration('./tsconfig.json');
224
+ const options = {
225
+ ...config.options,
226
+ compilationMode: 'partial' as const,
227
+ declaration: false,
228
+ emitDecoratorMetadata: true,
229
+ experimentalDecorators: true,
230
+ module: ts.ModuleKind.ESNext,
231
+ moduleResolution: ts.ModuleResolutionKind.Bundler,
232
+ newLine: ts.NewLineKind.LineFeed,
233
+ outDir,
234
+ rootDir: resolve('.'),
235
+ skipLibCheck: true,
236
+ suppressOutputPathCheck: true,
237
+ target: ts.ScriptTarget.ES2022
238
+ };
239
+
240
+ const host = ts.createCompilerHost(options);
241
+
242
+ // Capture only files emitted from our source dir (not external deps like imageClient)
243
+ const emitted: Record<string, string> = {};
244
+ const resolvedSrcInOut = resolve(
245
+ outDir,
246
+ relative(resolve('.'), resolve(srcDir))
247
+ );
248
+ host.writeFile = (fileName, text) => {
249
+ const absFileName = resolve(fileName);
250
+ if (!absFileName.startsWith(resolvedSrcInOut)) return;
251
+ const rel = absFileName.substring(resolvedSrcInOut.length + 1);
252
+ emitted[rel] = text;
253
+ };
254
+
255
+ const rootNames = srcFiles
256
+ .filter((f) => f.endsWith('.ts'))
257
+ .map((f) => resolve(srcDir, f));
258
+
259
+ const { diagnostics } = performCompilation({
260
+ emitFlags: EmitFlags.Default,
261
+ host,
262
+ options,
263
+ rootNames
264
+ });
265
+
266
+ const errors = diagnostics.filter(
267
+ (d: ts.Diagnostic) => d.category === ts.DiagnosticCategory.Error
268
+ );
269
+ if (errors.length > 0) {
270
+ console.error('Angular partial compilation errors:');
271
+ for (const d of errors) {
272
+ console.error(ts.flattenDiagnosticMessageText(d.messageText, '\n'));
273
+ }
274
+ process.exit(1);
275
+ }
276
+
277
+ // Copy emitted JS files to final dir, adding .js extensions to relative imports
278
+ for (const [fileName, content] of Object.entries(emitted)) {
279
+ if (!fileName.endsWith('.js')) continue;
280
+ const processed = content.replace(
281
+ /from\s+(['"])(\.\.?\/[^'"]+)(\1)/g,
282
+ (match, quote, path) => {
283
+ if (!path.match(/\.(js|ts|mjs|cjs)$/)) {
284
+ return `from ${quote}${path}.js${quote}`;
285
+ }
286
+ return match;
287
+ }
288
+ );
289
+ await writeFile(join(finalDir, fileName), processed);
290
+ }
291
+
292
+ // Clean up temp dir
293
+ await rm(tmpDir, { recursive: true, force: true });
281
294
  }
282
295
 
283
296
  async function verifyExports() {
284
- const pkg = await Bun.file("package.json").json();
285
- const exports = pkg.exports as Record<
286
- string,
287
- { import?: string; types?: string }
288
- >;
289
- const missing: string[] = [];
290
-
291
- for (const [key, value] of Object.entries(exports)) {
292
- if (value.import) {
293
- const path = value.import.replace("./", "");
294
- const file = Bun.file(path);
295
- if (!(await file.exists())) {
296
- missing.push(`${key} → ${value.import}`);
297
- }
298
- }
299
- }
300
-
301
- if (pkg.main) {
302
- const mainPath = pkg.main.replace("./", "");
303
- const file = Bun.file(mainPath);
304
- if (!(await file.exists())) {
305
- missing.push(`main → ${pkg.main}`);
306
- }
307
- }
308
-
309
- if (missing.length > 0) {
310
- console.error("\nExport verification failed! Missing files:");
311
- for (const m of missing) console.error(` ${m}`);
312
- process.exit(1);
313
- }
297
+ const pkg = await Bun.file('package.json').json();
298
+ const exports = pkg.exports as Record<
299
+ string,
300
+ { import?: string; types?: string }
301
+ >;
302
+ const missing: string[] = [];
303
+
304
+ for (const [key, value] of Object.entries(exports)) {
305
+ if (value.import) {
306
+ const path = value.import.replace('./', '');
307
+ const file = Bun.file(path);
308
+ if (!(await file.exists())) {
309
+ missing.push(`${key} → ${value.import}`);
310
+ }
311
+ }
312
+ }
313
+
314
+ if (pkg.main) {
315
+ const mainPath = pkg.main.replace('./', '');
316
+ const file = Bun.file(mainPath);
317
+ if (!(await file.exists())) {
318
+ missing.push(`main → ${pkg.main}`);
319
+ }
320
+ }
321
+
322
+ if (missing.length > 0) {
323
+ console.error('\nExport verification failed! Missing files:');
324
+ for (const m of missing) console.error(` ${m}`);
325
+ process.exit(1);
326
+ }
314
327
  }
315
328
 
316
329
  build();
package/types/metadata.ts CHANGED
@@ -35,7 +35,13 @@ export type RobotsDirective = {
35
35
  export type MetaTag = {
36
36
  name?: string;
37
37
  property?: string;
38
- httpEquiv?: string;
38
+ httpEquiv?:
39
+ | 'accept-ch'
40
+ | 'content-security-policy'
41
+ | 'content-type'
42
+ | 'default-style'
43
+ | 'refresh'
44
+ | 'x-ua-compatible';
39
45
  content: string;
40
46
  };
41
47