@open-press/core 1.1.0 → 1.1.1

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.
@@ -1,7 +1,9 @@
1
1
  import fs from "node:fs";
2
+ import { mkdir, writeFile } from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { createRequire } from "node:module";
4
- import { runCommand } from "./_shared.mjs";
5
+ import { FRAMEWORK_ROOT, runCommand } from "./_shared.mjs";
6
+ import { loadConfig } from "../runtime/config.mjs";
5
7
 
6
8
  // Run typecheck via the locally installed typescript. The previous
7
9
  // implementation used `npx tsc`; npm 11 + Node 24 (our CI / release
@@ -17,14 +19,15 @@ import { runCommand } from "./_shared.mjs";
17
19
  // even when bare require.resolve doesn't, which is what CI hits.
18
20
  export async function run({ root }) {
19
21
  const absoluteRoot = path.resolve(root);
22
+ const projectPath = await resolveTypecheckProject(absoluteRoot);
20
23
 
21
24
  const tscBin = resolveTscBin(absoluteRoot);
22
25
  if (tscBin) {
23
- return runCommand("node", [tscBin, "--noEmit", "-p", "tsconfig.json"], absoluteRoot);
26
+ return runCommand("node", [tscBin, "--noEmit", "-p", projectPath], absoluteRoot);
24
27
  }
25
28
 
26
29
  if (hasCommand("pnpm")) {
27
- return runCommand("pnpm", ["exec", "tsc", "--noEmit", "-p", "tsconfig.json"], absoluteRoot);
30
+ return runCommand("pnpm", ["exec", "tsc", "--noEmit", "-p", projectPath], absoluteRoot);
28
31
  }
29
32
 
30
33
  console.error("[openpress] typescript is not installed in this workspace.");
@@ -32,6 +35,88 @@ export async function run({ root }) {
32
35
  return 1;
33
36
  }
34
37
 
38
+ async function resolveTypecheckProject(absoluteRoot) {
39
+ const workspaceProject = path.join(absoluteRoot, "tsconfig.json");
40
+ if (fs.existsSync(workspaceProject)) return workspaceProject;
41
+ return await writeGeneratedTypecheckProject(absoluteRoot);
42
+ }
43
+
44
+ async function writeGeneratedTypecheckProject(absoluteRoot) {
45
+ const config = await loadConfig(absoluteRoot);
46
+ const outDir = path.join(absoluteRoot, ".openpress");
47
+ await mkdir(outDir, { recursive: true });
48
+
49
+ const projectPath = path.join(outDir, "typecheck.tsconfig.json");
50
+ const fromProjectDir = (target) => normalizePath(path.relative(outDir, target)) || ".";
51
+ const fromWorkspace = (target) => normalizePath(path.relative(absoluteRoot, target)) || ".";
52
+ const includeRoot = (target) => {
53
+ const relative = fromProjectDir(target);
54
+ return relative === "." ? "." : relative;
55
+ };
56
+
57
+ const typeRoots = [
58
+ path.join(absoluteRoot, "node_modules", "@types"),
59
+ path.join(FRAMEWORK_ROOT, "node_modules", "@types"),
60
+ ]
61
+ .filter((dir) => fs.existsSync(dir))
62
+ .map((dir) => fromProjectDir(dir));
63
+
64
+ const typecheckConfig = {
65
+ compilerOptions: {
66
+ target: "ES2022",
67
+ useDefineForClassFields: true,
68
+ lib: ["DOM", "DOM.Iterable", "ES2022"],
69
+ allowJs: false,
70
+ skipLibCheck: true,
71
+ esModuleInterop: true,
72
+ allowSyntheticDefaultImports: true,
73
+ strict: true,
74
+ forceConsistentCasingInFileNames: true,
75
+ module: "ESNext",
76
+ moduleResolution: "Bundler",
77
+ types: ["node"],
78
+ ...(typeRoots.length > 0 ? { typeRoots } : {}),
79
+ resolveJsonModule: true,
80
+ isolatedModules: true,
81
+ noEmit: true,
82
+ jsx: "react-jsx",
83
+ ignoreDeprecations: "6.0",
84
+ baseUrl: "..",
85
+ paths: {
86
+ "@open-press/core": [fromWorkspace(path.join(FRAMEWORK_ROOT, "src", "openpress", "core", "index.tsx"))],
87
+ "@open-press/core/mdx": [fromWorkspace(path.join(FRAMEWORK_ROOT, "src", "openpress", "mdx", "index.ts"))],
88
+ "@open-press/core/manuscript": [fromWorkspace(path.join(FRAMEWORK_ROOT, "src", "openpress", "manuscript", "index.tsx"))],
89
+ "@open-press/core/numbering": [fromWorkspace(path.join(FRAMEWORK_ROOT, "src", "openpress", "numbering", "index.ts"))],
90
+ "@/components": [
91
+ `${fromWorkspace(config.paths.componentsDir)}/index.ts`,
92
+ `${fromWorkspace(config.paths.componentsDir)}/index.tsx`,
93
+ ],
94
+ "@/components/*": [`${fromWorkspace(config.paths.componentsDir)}/*`],
95
+ "@workspace/content": [fromWorkspace(config.paths.sourceDir)],
96
+ "@workspace/content/*": [`${fromWorkspace(config.paths.sourceDir)}/*`],
97
+ "@workspace/media": [fromWorkspace(config.paths.mediaDir)],
98
+ "@workspace/media/*": [`${fromWorkspace(config.paths.mediaDir)}/*`],
99
+ "@workspace/components": [fromWorkspace(config.paths.componentsDir)],
100
+ "@workspace/components/*": [`${fromWorkspace(config.paths.componentsDir)}/*`],
101
+ "@/*": [`${fromWorkspace(path.join(FRAMEWORK_ROOT, "src"))}/*`],
102
+ },
103
+ },
104
+ include: [
105
+ `${includeRoot(config.paths.documentRoot)}/**/*.ts`,
106
+ `${includeRoot(config.paths.documentRoot)}/**/*.tsx`,
107
+ "../tests/**/*.test.ts",
108
+ "../tests/**/*.test.tsx",
109
+ ],
110
+ };
111
+
112
+ await writeFile(projectPath, `${JSON.stringify(typecheckConfig, null, 2)}\n`, "utf8");
113
+ return projectPath;
114
+ }
115
+
116
+ function normalizePath(value) {
117
+ return value.replaceAll("\\", "/");
118
+ }
119
+
35
120
  function resolveTscBin(absoluteRoot) {
36
121
  try {
37
122
  const require = createRequire(path.join(absoluteRoot, "package.json"));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-press/core",
3
- "version": "1.1.0",
3
+ "version": "1.1.1",
4
4
  "type": "module",
5
5
  "description": "open-press core — runtime primitives, CLI, and render pipeline for AI-first fixed-layout documents.",
6
6
  "license": "MIT",