appflare 0.2.54 โ 0.2.55
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/cli/generate.ts +93 -65
- package/cli/utils/resolve-package.ts +21 -0
- package/dist/cli/index.js +202 -201
- package/dist/cli/index.mjs +202 -201
- package/package.json +2 -1
package/cli/generate.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { ensureRelativeImportPath } from "./utils/path-utils";
|
|
|
17
17
|
import {
|
|
18
18
|
packageSearchDirs,
|
|
19
19
|
resolvePackageBin,
|
|
20
|
+
resolvePackageModule,
|
|
20
21
|
} from "./utils/resolve-package";
|
|
21
22
|
|
|
22
23
|
function extractRolesFromConfig(config: LoadedAppflareConfig["config"]): string[] {
|
|
@@ -108,11 +109,9 @@ export async function generateArtifacts(
|
|
|
108
109
|
|
|
109
110
|
const moduleDir = dirname(fileURLToPath(import.meta.url));
|
|
110
111
|
const searchDirs = packageSearchDirs(moduleDir, [configDir]);
|
|
111
|
-
const tscBin = resolvePackageBin(
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
searchDirs,
|
|
115
|
-
);
|
|
112
|
+
const tscBin = resolvePackageBin("typescript", "bin/tsc", searchDirs);
|
|
113
|
+
const esbuildModulePath = resolvePackageModule("esbuild", searchDirs);
|
|
114
|
+
const typescriptModulePath = resolvePackageModule("typescript", searchDirs);
|
|
116
115
|
const betterAuthBin = resolvePackageBin(
|
|
117
116
|
"@better-auth/cli",
|
|
118
117
|
"dist/index.mjs",
|
|
@@ -253,52 +252,85 @@ export async function generateArtifacts(
|
|
|
253
252
|
process.stdout.write(`๐ง Patched role type (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
254
253
|
}
|
|
255
254
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
jsx: "react-jsx",
|
|
270
|
-
paths: {
|
|
271
|
-
"_generated/*": ["./*"],
|
|
272
|
-
},
|
|
273
|
-
...overrides,
|
|
274
|
-
},
|
|
275
|
-
include: ["./*.ts", "./client/*.ts"],
|
|
276
|
-
};
|
|
255
|
+
// Collect all .ts entries written so far (includes schema-compiler + better-auth outputs)
|
|
256
|
+
const tsEntries: string[] = [];
|
|
257
|
+
async function collectTsEntries(dir: string): Promise<void> {
|
|
258
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
259
|
+
for (const entry of entries) {
|
|
260
|
+
const fullPath = join(dir, entry.name);
|
|
261
|
+
if (entry.isDirectory()) {
|
|
262
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".")) continue;
|
|
263
|
+
await collectTsEntries(fullPath);
|
|
264
|
+
} else if (entry.name.endsWith(".ts") && !entry.name.endsWith(".d.ts")) {
|
|
265
|
+
tsEntries.push(fullPath);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
277
268
|
}
|
|
269
|
+
await collectTsEntries(outDirAbs);
|
|
278
270
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
)
|
|
286
|
-
|
|
287
|
-
|
|
271
|
+
// Transpile .ts โ .js in-process with esbuild. Per-file syntax transform with
|
|
272
|
+
// no bundling keeps output strictly inside _generated and preserves extensionless
|
|
273
|
+
// relative imports exactly as Wrangler's bundler expects at runtime.
|
|
274
|
+
process.stdout.write(`โ๏ธ Transpiling (esbuild)... (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
275
|
+
const esbuild = (await import(esbuildModulePath)) as typeof import("esbuild");
|
|
276
|
+
await Promise.all(
|
|
277
|
+
tsEntries.map(async (tsPath) => {
|
|
278
|
+
const source = await Bun.file(tsPath).text();
|
|
279
|
+
const result = await esbuild.transform(source, {
|
|
280
|
+
loader: tsPath.endsWith(".tsx") ? "tsx" : "ts",
|
|
281
|
+
format: "esm",
|
|
282
|
+
target: "es2024",
|
|
283
|
+
jsx: "automatic",
|
|
284
|
+
sourcefile: tsPath,
|
|
285
|
+
});
|
|
286
|
+
await Bun.write(tsPath.replace(/\.tsx?$/, ".js"), result.code);
|
|
287
|
+
}),
|
|
288
|
+
);
|
|
289
|
+
process.stdout.write(`โ
JS files (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
288
290
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
291
|
+
// Emit .d.ts in-process with the TypeScript compiler API.
|
|
292
|
+
// .tsbuildinfo persists parsed lib + node_modules type info between rebuilds so
|
|
293
|
+
// the declaration pass only re-resolves what changed (~60% faster on warm builds).
|
|
294
|
+
process.stdout.write(`โ๏ธ Declarations (tsc)... (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
295
|
+
const ts = (await import(typescriptModulePath)) as { default?: typeof import("typescript") } & typeof import("typescript");
|
|
296
|
+
const tsApi = ts.default ?? ts;
|
|
297
|
+
const tsBuildInfoPath = resolve(outDirAbs, ".tsbuildinfo");
|
|
298
|
+
const declOptions: import("typescript").CompilerOptions = {
|
|
299
|
+
lib: ["lib.es2024.d.ts"],
|
|
300
|
+
types: ["@types/node", "@cloudflare/workers-types/2023-07-01"],
|
|
301
|
+
module: tsApi.ModuleKind.ES2022,
|
|
302
|
+
target: tsApi.ScriptTarget.ES2024,
|
|
303
|
+
moduleResolution: tsApi.ModuleResolutionKind.Bundler,
|
|
304
|
+
strictNullChecks: true,
|
|
305
|
+
skipLibCheck: true,
|
|
306
|
+
declaration: true,
|
|
307
|
+
emitDeclarationOnly: true,
|
|
308
|
+
noCheck: true,
|
|
309
|
+
incremental: true,
|
|
310
|
+
tsBuildInfoFile: tsBuildInfoPath,
|
|
311
|
+
jsx: tsApi.JsxEmit.ReactJSX,
|
|
312
|
+
rootDir: outDirAbs,
|
|
313
|
+
outDir: outDirAbs,
|
|
314
|
+
paths: { "_generated/*": ["./*"] },
|
|
315
|
+
baseUrl: outDirAbs,
|
|
316
|
+
};
|
|
317
|
+
const program = tsApi.createIncrementalProgram({ rootNames: tsEntries, options: declOptions });
|
|
318
|
+
const emitResult = program.emit();
|
|
319
|
+
if (emitResult.emitSkipped) {
|
|
320
|
+
const diagnostics = tsApi
|
|
321
|
+
.getPreEmitDiagnostics(program.getProgram())
|
|
322
|
+
.concat(emitResult.diagnostics);
|
|
323
|
+
throw new Error(
|
|
324
|
+
`tsc declaration emit failed:\n${tsApi.formatDiagnostics(diagnostics, {
|
|
325
|
+
getCanonicalFileName: (f) => f,
|
|
326
|
+
getCurrentDirectory: () => outDirAbs,
|
|
327
|
+
getNewLine: () => "\n",
|
|
328
|
+
})}`,
|
|
329
|
+
);
|
|
298
330
|
}
|
|
331
|
+
process.stdout.write(`โ
Declarations (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
299
332
|
|
|
300
|
-
|
|
301
|
-
process.stdout.write(`โ
JS + declarations (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
333
|
+
// Remove .ts source files from _generated (keep .js + .d.ts + .tsbuildinfo)
|
|
302
334
|
async function removeTsFiles(dir: string): Promise<void> {
|
|
303
335
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
304
336
|
for (const entry of entries) {
|
|
@@ -312,34 +344,30 @@ export async function generateArtifacts(
|
|
|
312
344
|
}
|
|
313
345
|
}
|
|
314
346
|
await removeTsFiles(outDirAbs);
|
|
315
|
-
|
|
316
|
-
|
|
347
|
+
// Remove stale config files written by earlier versions of the generator.
|
|
348
|
+
await Promise.all([
|
|
349
|
+
rm(resolve(outDirAbs, "vite.generated.config.mjs"), { force: true }),
|
|
350
|
+
rm(resolve(outDirAbs, "tsconfig.dts.json"), { force: true }),
|
|
351
|
+
rm(resolve(outDirAbs, "tsconfig.js.json"), { force: true }),
|
|
352
|
+
]);
|
|
353
|
+
|
|
354
|
+
// esbuild's per-file transform never emits outside _generated. tsc declaration
|
|
355
|
+
// emit follows ../imports into user source, so only .d.ts need cleaning outside.
|
|
317
356
|
const generatedDirPrefix = outDirAbs + "/";
|
|
318
|
-
async function
|
|
357
|
+
async function cleanStrayDts(dir: string): Promise<void> {
|
|
319
358
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
320
359
|
for (const entry of entries) {
|
|
321
360
|
const fullPath = join(dir, entry.name);
|
|
322
361
|
if (entry.isDirectory()) {
|
|
323
|
-
if (
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
fullPath === outDirAbs
|
|
327
|
-
) {
|
|
328
|
-
continue;
|
|
329
|
-
}
|
|
330
|
-
await cleanDtsOutside(fullPath);
|
|
331
|
-
} else if (
|
|
332
|
-
!fullPath.startsWith(generatedDirPrefix) && (
|
|
333
|
-
entry.name.endsWith(".d.ts") || (
|
|
334
|
-
entry.name.endsWith(".js"))
|
|
335
|
-
)
|
|
336
|
-
) {
|
|
362
|
+
if (entry.name === "node_modules" || entry.name.startsWith(".") || fullPath === outDirAbs) continue;
|
|
363
|
+
await cleanStrayDts(fullPath);
|
|
364
|
+
} else if (!fullPath.startsWith(generatedDirPrefix) && entry.name.endsWith(".d.ts")) {
|
|
337
365
|
await rm(fullPath);
|
|
338
366
|
}
|
|
339
367
|
}
|
|
340
368
|
}
|
|
341
|
-
await
|
|
342
|
-
process.stdout.write(`๐งน
|
|
369
|
+
await cleanStrayDts(configDir);
|
|
370
|
+
process.stdout.write(`๐งน Cleaned up (${(performance.now() - t0).toFixed(0)}ms)\n`);
|
|
343
371
|
|
|
344
372
|
|
|
345
373
|
const tsconfigPath = resolve(configDir, "tsconfig.json");
|
|
@@ -57,3 +57,24 @@ export function packageSearchDirs(
|
|
|
57
57
|
];
|
|
58
58
|
return [...new Set(dirs)];
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Resolves the importable module entry for a package so it can be loaded
|
|
63
|
+
* in-process via dynamic `import()`, searching the user's install dirs first.
|
|
64
|
+
*/
|
|
65
|
+
export function resolvePackageModule(
|
|
66
|
+
packageName: string,
|
|
67
|
+
searchDirs: string[],
|
|
68
|
+
): string {
|
|
69
|
+
for (const dir of searchDirs) {
|
|
70
|
+
try {
|
|
71
|
+
return Bun.resolveSync(packageName, dir);
|
|
72
|
+
} catch {
|
|
73
|
+
continue;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Could not resolve "${packageName}". Install it in your project (see appflare peerDependencies).`,
|
|
79
|
+
);
|
|
80
|
+
}
|