@open-press/cli 1.0.0 → 1.1.0

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.
Files changed (175) hide show
  1. package/README.md +11 -12
  2. package/dist/cli.js +298 -79
  3. package/package.json +9 -7
  4. package/template/core/AGENTS.md +0 -130
  5. package/template/core/CHANGELOG.md +0 -218
  6. package/template/core/README.md +0 -43
  7. package/template/core/engine/cli.mjs +0 -96
  8. package/template/core/engine/commands/_shared.mjs +0 -199
  9. package/template/core/engine/commands/deploy.mjs +0 -31
  10. package/template/core/engine/commands/dev.mjs +0 -49
  11. package/template/core/engine/commands/doctor.mjs +0 -229
  12. package/template/core/engine/commands/export.mjs +0 -8
  13. package/template/core/engine/commands/image.mjs +0 -29
  14. package/template/core/engine/commands/inspect.mjs +0 -35
  15. package/template/core/engine/commands/pdf.mjs +0 -26
  16. package/template/core/engine/commands/preview.mjs +0 -26
  17. package/template/core/engine/commands/render.mjs +0 -17
  18. package/template/core/engine/commands/replace.mjs +0 -41
  19. package/template/core/engine/commands/search.mjs +0 -33
  20. package/template/core/engine/commands/skills-sync.mjs +0 -71
  21. package/template/core/engine/commands/typecheck.mjs +0 -67
  22. package/template/core/engine/commands/upgrade.mjs +0 -159
  23. package/template/core/engine/commands/validate.mjs +0 -17
  24. package/template/core/engine/document-export.mjs +0 -15
  25. package/template/core/engine/output/chrome-pdf.d.mts +0 -34
  26. package/template/core/engine/output/chrome-pdf.mjs +0 -450
  27. package/template/core/engine/output/deploy-sync.mjs +0 -15
  28. package/template/core/engine/output/fonts.mjs +0 -62
  29. package/template/core/engine/output/katex-assets.mjs +0 -45
  30. package/template/core/engine/output/page-block.mjs +0 -30
  31. package/template/core/engine/output/pdf-media.mjs +0 -45
  32. package/template/core/engine/output/public-assets.mjs +0 -19
  33. package/template/core/engine/output/static-server.mjs +0 -571
  34. package/template/core/engine/react/caption-numbering.mjs +0 -73
  35. package/template/core/engine/react/comment-endpoint.d.mts +0 -11
  36. package/template/core/engine/react/comment-endpoint.mjs +0 -102
  37. package/template/core/engine/react/comment-marker.mjs +0 -374
  38. package/template/core/engine/react/document-entry.mjs +0 -331
  39. package/template/core/engine/react/document-export.mjs +0 -512
  40. package/template/core/engine/react/http-json.mjs +0 -24
  41. package/template/core/engine/react/mdx-compile.mjs +0 -629
  42. package/template/core/engine/react/measurement-css.mjs +0 -157
  43. package/template/core/engine/react/object-entities.mjs +0 -204
  44. package/template/core/engine/react/pagination/allocator.mjs +0 -167
  45. package/template/core/engine/react/pagination/regions.mjs +0 -81
  46. package/template/core/engine/react/pagination-constants.mjs +0 -3
  47. package/template/core/engine/react/pagination.mjs +0 -9
  48. package/template/core/engine/react/pipeline/allocate.mjs +0 -217
  49. package/template/core/engine/react/pipeline/final-render.mjs +0 -94
  50. package/template/core/engine/react/pipeline/frame-measurement.mjs +0 -306
  51. package/template/core/engine/react/pipeline/press-tree.mjs +0 -135
  52. package/template/core/engine/react/press-tree-inspection.mjs +0 -172
  53. package/template/core/engine/react/project-asset-endpoint.d.mts +0 -10
  54. package/template/core/engine/react/project-asset-endpoint.mjs +0 -361
  55. package/template/core/engine/react/section-css.mjs +0 -56
  56. package/template/core/engine/react/source-edit-endpoint.d.mts +0 -10
  57. package/template/core/engine/react/source-edit-endpoint.mjs +0 -75
  58. package/template/core/engine/react/sources/heading-numbering.mjs +0 -132
  59. package/template/core/engine/react/sources/mdx-resolver.mjs +0 -439
  60. package/template/core/engine/react/style-discovery.mjs +0 -160
  61. package/template/core/engine/runtime/config.d.mts +0 -48
  62. package/template/core/engine/runtime/config.mjs +0 -172
  63. package/template/core/engine/runtime/file-utils.mjs +0 -114
  64. package/template/core/engine/runtime/file-walk.mjs +0 -22
  65. package/template/core/engine/runtime/inspection.mjs +0 -328
  66. package/template/core/engine/runtime/issue-report.mjs +0 -44
  67. package/template/core/engine/runtime/page-geometry.mjs +0 -131
  68. package/template/core/engine/runtime/path-utils.mjs +0 -20
  69. package/template/core/engine/runtime/source-text-tools.d.mts +0 -102
  70. package/template/core/engine/runtime/source-text-tools.mjs +0 -832
  71. package/template/core/engine/runtime/source-workspace.mjs +0 -168
  72. package/template/core/engine/runtime/validation.mjs +0 -183
  73. package/template/core/index.html +0 -13
  74. package/template/core/openpress.config.mjs +0 -8
  75. package/template/core/package.json +0 -89
  76. package/template/core/src/main.tsx +0 -16
  77. package/template/core/src/openpress/app/OpenPressApp.tsx +0 -296
  78. package/template/core/src/openpress/app/OpenPressRuntime.tsx +0 -102
  79. package/template/core/src/openpress/app/WorkspaceGalleryPage.tsx +0 -219
  80. package/template/core/src/openpress/app/index.ts +0 -2
  81. package/template/core/src/openpress/core/Frame.tsx +0 -91
  82. package/template/core/src/openpress/core/FrameContext.tsx +0 -26
  83. package/template/core/src/openpress/core/MdxArea.tsx +0 -34
  84. package/template/core/src/openpress/core/Press.tsx +0 -55
  85. package/template/core/src/openpress/core/Workspace.tsx +0 -36
  86. package/template/core/src/openpress/core/cn.ts +0 -4
  87. package/template/core/src/openpress/core/index.tsx +0 -47
  88. package/template/core/src/openpress/core/primitives.tsx +0 -91
  89. package/template/core/src/openpress/core/types.ts +0 -236
  90. package/template/core/src/openpress/core/useSource.ts +0 -28
  91. package/template/core/src/openpress/document-model/anchorMapModel.ts +0 -27
  92. package/template/core/src/openpress/document-model/documentIndexes.ts +0 -329
  93. package/template/core/src/openpress/document-model/documentTypes.ts +0 -147
  94. package/template/core/src/openpress/document-model/index.ts +0 -7
  95. package/template/core/src/openpress/document-model/objectEntityModel.ts +0 -55
  96. package/template/core/src/openpress/document-model/projectIdentityModel.ts +0 -15
  97. package/template/core/src/openpress/document-model/reactDocumentMetadataModel.ts +0 -27
  98. package/template/core/src/openpress/document-model/workspaceManifestModel.ts +0 -57
  99. package/template/core/src/openpress/manuscript/index.tsx +0 -238
  100. package/template/core/src/openpress/mdx/index.ts +0 -96
  101. package/template/core/src/openpress/numbering/index.ts +0 -294
  102. package/template/core/src/openpress/reader/PageThumbnailsPanel.tsx +0 -168
  103. package/template/core/src/openpress/reader/PublicReaderPage.tsx +0 -267
  104. package/template/core/src/openpress/reader/ReaderNavigationPanel.tsx +0 -123
  105. package/template/core/src/openpress/reader/index.ts +0 -11
  106. package/template/core/src/openpress/reader/pageViewportScaleModel.ts +0 -73
  107. package/template/core/src/openpress/reader/readerPageRegistry.ts +0 -41
  108. package/template/core/src/openpress/reader/readerPageRoute.ts +0 -21
  109. package/template/core/src/openpress/reader/readerScroll.ts +0 -92
  110. package/template/core/src/openpress/reader/readerStateModel.ts +0 -15
  111. package/template/core/src/openpress/reader/readerTypes.ts +0 -4
  112. package/template/core/src/openpress/reader/usePageViewportScale.ts +0 -119
  113. package/template/core/src/openpress/reader/usePanelState.ts +0 -56
  114. package/template/core/src/openpress/reader/useReaderHashSync.ts +0 -61
  115. package/template/core/src/openpress/reader/useReaderKeyboardNav.ts +0 -48
  116. package/template/core/src/openpress/reader/useReaderRuntime.ts +0 -146
  117. package/template/core/src/openpress/reader/useReaderScrollAnchor.ts +0 -64
  118. package/template/core/src/openpress/shared/Panel.tsx +0 -77
  119. package/template/core/src/openpress/shared/frameScheduler.ts +0 -32
  120. package/template/core/src/openpress/shared/index.ts +0 -4
  121. package/template/core/src/openpress/shared/numberUtils.ts +0 -3
  122. package/template/core/src/openpress/shared/runtimeMode.ts +0 -11
  123. package/template/core/src/openpress/workbench/Workbench.tsx +0 -506
  124. package/template/core/src/openpress/workbench/actions/DeploymentControl.tsx +0 -157
  125. package/template/core/src/openpress/workbench/actions/ExportImageControl.tsx +0 -96
  126. package/template/core/src/openpress/workbench/actions/PageZoomControl.tsx +0 -182
  127. package/template/core/src/openpress/workbench/actions/SearchControl.tsx +0 -345
  128. package/template/core/src/openpress/workbench/actions/deploymentStatusModel.ts +0 -112
  129. package/template/core/src/openpress/workbench/actions/index.ts +0 -6
  130. package/template/core/src/openpress/workbench/actions/useDeploymentWorkbench.ts +0 -136
  131. package/template/core/src/openpress/workbench/dialog/WorkbenchDialog.tsx +0 -72
  132. package/template/core/src/openpress/workbench/dialog/index.ts +0 -1
  133. package/template/core/src/openpress/workbench/document/components/DocumentPanel.tsx +0 -127
  134. package/template/core/src/openpress/workbench/document/components/InlineSourceEditorLayer.tsx +0 -207
  135. package/template/core/src/openpress/workbench/document/components/ReaderStage.tsx +0 -9
  136. package/template/core/src/openpress/workbench/document/hooks/useDocumentWorkbenchModel.ts +0 -34
  137. package/template/core/src/openpress/workbench/document/hooks/useInlineDocumentEditor.ts +0 -525
  138. package/template/core/src/openpress/workbench/document/index.ts +0 -10
  139. package/template/core/src/openpress/workbench/index.ts +0 -2
  140. package/template/core/src/openpress/workbench/inspector/InlineInspectorLayer.tsx +0 -459
  141. package/template/core/src/openpress/workbench/inspector/index.ts +0 -5
  142. package/template/core/src/openpress/workbench/inspector/inlineCommentModel.ts +0 -125
  143. package/template/core/src/openpress/workbench/inspector/inspectorGeometryModel.ts +0 -160
  144. package/template/core/src/openpress/workbench/inspector/inspectorModel.ts +0 -408
  145. package/template/core/src/openpress/workbench/inspector/useInspectorComments.ts +0 -254
  146. package/template/core/src/openpress/workbench/mentions/MentionSuggestionList.tsx +0 -41
  147. package/template/core/src/openpress/workbench/mentions/index.ts +0 -2
  148. package/template/core/src/openpress/workbench/mentions/useComposerMentions.ts +0 -185
  149. package/template/core/src/openpress/workbench/panels/Panel.tsx +0 -1
  150. package/template/core/src/openpress/workbench/panels/PendingCommentsPanel.tsx +0 -80
  151. package/template/core/src/openpress/workbench/panels/WorkbenchControlPanel.tsx +0 -29
  152. package/template/core/src/openpress/workbench/panels/index.ts +0 -3
  153. package/template/core/src/openpress/workbench/project/ProjectEntryPanel.tsx +0 -525
  154. package/template/core/src/openpress/workbench/project/ProjectPreviewDialog.tsx +0 -35
  155. package/template/core/src/openpress/workbench/project/index.ts +0 -2
  156. package/template/core/src/openpress/workbench/project/projectPreviewTypes.ts +0 -11
  157. package/template/core/src/openpress/workbench/project/projectSourceModel.ts +0 -24
  158. package/template/core/src/openpress/workbench/shell/WorkbenchShell.tsx +0 -167
  159. package/template/core/src/openpress/workbench/shell/index.ts +0 -1
  160. package/template/core/src/openpress/workbench/workbenchFormatters.ts +0 -120
  161. package/template/core/src/openpress/workbench/workbenchTypes.ts +0 -35
  162. package/template/core/src/styles/openpress/app-shell.css +0 -251
  163. package/template/core/src/styles/openpress/media-workspace.css +0 -230
  164. package/template/core/src/styles/openpress/print-route.css +0 -184
  165. package/template/core/src/styles/openpress/project-preview-panel.css +0 -924
  166. package/template/core/src/styles/openpress/public-viewer.css +0 -688
  167. package/template/core/src/styles/openpress/reader-runtime.css +0 -989
  168. package/template/core/src/styles/openpress/responsive.css +0 -245
  169. package/template/core/src/styles/openpress/workbench-panels.css +0 -707
  170. package/template/core/src/styles/openpress/workbench.css +0 -1255
  171. package/template/core/src/styles/openpress/workspace-gallery.css +0 -300
  172. package/template/core/src/styles/openpress.css +0 -15
  173. package/template/core/src/vite-env.d.ts +0 -9
  174. package/template/core/tsconfig.json +0 -40
  175. package/template/core/vite.config.ts +0 -584
@@ -1,331 +0,0 @@
1
- // Layer 1 — Document entry loader.
2
- //
3
- // Loads `press/index.tsx`, validates it exports a Press component as
4
- // default, reads optional `config` and `sources` named exports, and sets
5
- // up the vite SSR server with `@open-press/core` aliases (including the
6
- // subpaths `/mdx` and `/manuscript`).
7
-
8
- import fs from "node:fs/promises";
9
- import { createRequire } from "node:module";
10
- import path from "node:path";
11
- import { fileURLToPath } from "node:url";
12
- import react from "@vitejs/plugin-react";
13
- import ts from "typescript";
14
- import { createServer as createViteServer } from "vite";
15
- import { loadConfig } from "../runtime/config.mjs";
16
- import { inspectPressTree } from "./press-tree-inspection.mjs";
17
-
18
- const ENGINE_REACT_DIR = path.dirname(fileURLToPath(import.meta.url));
19
- const FRAMEWORK_ROOT = path.resolve(ENGINE_REACT_DIR, "..", "..");
20
- export const CORE_ENTRY = path.join(FRAMEWORK_ROOT, "src", "openpress", "core", "index.tsx");
21
- export const MDX_ENTRY = path.join(FRAMEWORK_ROOT, "src", "openpress", "mdx", "index.ts");
22
- export const MANUSCRIPT_ENTRY = path.join(FRAMEWORK_ROOT, "src", "openpress", "manuscript", "index.tsx");
23
- export const NUMBERING_ENTRY = path.join(FRAMEWORK_ROOT, "src", "openpress", "numbering", "index.ts");
24
- const REACT_PACKAGE_ROOT = path.join(FRAMEWORK_ROOT, "node_modules", "react");
25
- const require = createRequire(import.meta.url);
26
- const REACT_EXPORT_NAMES = Object.keys(require("react")).filter((name) => /^[A-Za-z_$][\w$]*$/.test(name));
27
-
28
- // 1.0 contract: the document entry lives at press/index.tsx.
29
- async function resolveEntryPath(workspaceRoot) {
30
- const candidate = path.join(workspaceRoot, "press", "index.tsx");
31
- if (await fileExists(candidate)) return candidate;
32
- return null;
33
- }
34
-
35
- export async function loadReactDocumentEntry(root = ".", { server: externalServer } = {}) {
36
- const workspaceRoot = path.resolve(root);
37
- const entryPath = await resolveEntryPath(workspaceRoot);
38
- if (!entryPath) return null;
39
-
40
- const source = await fs.readFile(entryPath, "utf8");
41
- assertNoObviousTopLevelSideEffects(source, entryPath);
42
-
43
- // If caller provides a server, reuse it so module identity is shared
44
- // across the pipeline (PressContext, React, etc.). Otherwise open a
45
- // temporary server for one-shot config reads.
46
- const ownServer = externalServer ?? (await createReactSsrServer(workspaceRoot));
47
- try {
48
- const mod = await ownServer.ssrLoadModule(entryPath);
49
-
50
- // Press default export is required for export/render but not for
51
- // config-only commands (search, replace, validate). Validate if present;
52
- // export pipeline throws separately if it's missing when actually needed.
53
- const Press = typeof mod.default === "function" ? mod.default : null;
54
-
55
- // Inspect the JSX tree returned by the user's default export to
56
- // pull <Workspace> / <Press> props declared inline. The 1.0 contract
57
- // treats workspaces uniformly as "array of Press children" — the
58
- // single-doc case is just length 1.
59
- let inspection = { workspaceProps: {}, presses: [], wrappedInWorkspace: false };
60
- if (Press) {
61
- const coreModule = await ownServer.ssrLoadModule(
62
- path.join(FRAMEWORK_ROOT, "src", "openpress", "core", "index.tsx"),
63
- );
64
- inspection = inspectPressTree({
65
- UserComponent: Press,
66
- PRESS_MARKER: coreModule.PRESS_MARKER,
67
- WORKSPACE_MARKER: coreModule.WORKSPACE_MARKER,
68
- });
69
- }
70
-
71
- // Workspace-level config (deploy, pdf, captionNumbering defaults)
72
- // comes from package.json "openpress" via loadConfig. Each Press
73
- // overlays its own metadata via JSX props at export time.
74
- const config = await loadConfig(workspaceRoot);
75
-
76
- return {
77
- entryPath,
78
- config,
79
- Press,
80
- presses: inspection.presses,
81
- workspaceProps: inspection.workspaceProps,
82
- pressCount: inspection.presses.length,
83
- wrappedInWorkspace: inspection.wrappedInWorkspace,
84
- };
85
- } finally {
86
- if (!externalServer) await ownServer.close();
87
- }
88
- }
89
-
90
- export async function createReactSsrServer(workspaceRoot = ".") {
91
- const resolvedWorkspaceRoot = path.resolve(workspaceRoot);
92
- return createViteServer({
93
- configFile: false,
94
- root: FRAMEWORK_ROOT,
95
- cacheDir: path.join(resolvedWorkspaceRoot, ".openpress", "vite-ssr"),
96
- appType: "custom",
97
- logLevel: "silent",
98
- plugins: [reactRuntimePlugin(), react()],
99
- resolve: {
100
- alias: [
101
- // ORDER MATTERS: subpath aliases must precede the base alias so that
102
- // `@open-press/core/mdx` doesn't resolve to `@open-press/core` + `/mdx`.
103
- { find: "@open-press/core/mdx", replacement: MDX_ENTRY },
104
- { find: "@open-press/core/manuscript", replacement: MANUSCRIPT_ENTRY },
105
- { find: "@open-press/core/numbering", replacement: NUMBERING_ENTRY },
106
- { find: "@open-press/core", replacement: CORE_ENTRY },
107
- { find: "@/components", replacement: path.join(resolvedWorkspaceRoot, "press", "components") },
108
- ],
109
- },
110
- optimizeDeps: {
111
- include: [
112
- "@mdx-js/react",
113
- "react",
114
- "react-dom",
115
- "react-dom/server",
116
- "react/jsx-dev-runtime",
117
- "react/jsx-runtime",
118
- ],
119
- },
120
- server: {
121
- middlewareMode: true,
122
- fs: {
123
- allow: [FRAMEWORK_ROOT, resolvedWorkspaceRoot],
124
- },
125
- },
126
- });
127
- }
128
-
129
- function assertNoObviousTopLevelSideEffects(source, entryPath) {
130
- const sourceFile = ts.createSourceFile(entryPath, source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
131
- for (const statement of sourceFile.statements) {
132
- if (ts.isImportDeclaration(statement)) {
133
- assertPureImport(statement, entryPath);
134
- continue;
135
- }
136
-
137
- if (ts.isInterfaceDeclaration(statement) || ts.isTypeAliasDeclaration(statement)) continue;
138
- if (ts.isExportDeclaration(statement) && statement.isTypeOnly) continue;
139
- if (ts.isFunctionDeclaration(statement)) continue;
140
- if (ts.isVariableStatement(statement)) {
141
- assertTopLevelVariableStatement(statement, entryPath);
142
- continue;
143
- }
144
- if (ts.isExportAssignment(statement)) {
145
- assertPureDefaultExport(statement.expression, entryPath);
146
- continue;
147
- }
148
-
149
- throw new Error(`OpenPress document entry has unsupported top-level code in ${entryPath}: ${statementKindName(statement)}`);
150
- }
151
- }
152
-
153
- function assertPureImport(statement, entryPath) {
154
- if (!statement.importClause) {
155
- throw new Error(`OpenPress document entry has an unsupported side-effect import in ${entryPath}`);
156
- }
157
- const moduleName = stringLiteralText(statement.moduleSpecifier);
158
- if (!statement.importClause.isTypeOnly && isFileSystemModule(moduleName)) {
159
- throw new Error(`OpenPress document entry imports filesystem APIs at top level in ${entryPath}`);
160
- }
161
- }
162
-
163
- function assertTopLevelVariableStatement(statement, entryPath) {
164
- if ((statement.declarationList.flags & ts.NodeFlags.Const) === 0) {
165
- throw new Error(`OpenPress document entry only allows top-level const declarations in ${entryPath}`);
166
- }
167
-
168
- const exported = hasModifier(statement, ts.SyntaxKind.ExportKeyword);
169
- for (const declaration of statement.declarationList.declarations) {
170
- if (!ts.isIdentifier(declaration.name)) {
171
- throw new Error(`OpenPress document entry only allows identifier const declarations at top level in ${entryPath}`);
172
- }
173
- const name = declaration.name.text;
174
- if (exported && name !== "config" && name !== "sources") {
175
- throw new Error(`OpenPress document entry only allows exported const config and sources in ${entryPath}`);
176
- }
177
- if (!declaration.initializer) {
178
- throw new Error(`OpenPress document entry const "${name}" must have an initializer in ${entryPath}`);
179
- }
180
- if (name === "config") {
181
- assertPureExpression(declaration.initializer, entryPath, { allowMdxSourceCall: false });
182
- } else if (name === "sources") {
183
- assertPureSourcesInitializer(declaration.initializer, entryPath);
184
- } else {
185
- assertPureStaticInitializer(declaration.initializer, entryPath);
186
- }
187
- }
188
- }
189
-
190
- function assertPureSourcesInitializer(node, entryPath) {
191
- const expression = skipExpressionWrappers(node);
192
- if (!ts.isObjectLiteralExpression(expression)) {
193
- throw new Error(`OpenPress document entry exported sources must be an object literal in ${entryPath}`);
194
- }
195
- assertPureExpression(expression, entryPath, { allowMdxSourceCall: true });
196
- }
197
-
198
- function assertPureStaticInitializer(node, entryPath) {
199
- const expression = skipExpressionWrappers(node);
200
- if (ts.isFunctionExpression(expression) || ts.isArrowFunction(expression) || ts.isClassExpression(expression)) return;
201
- assertPureExpression(expression, entryPath, { allowMdxSourceCall: false });
202
- }
203
-
204
- function assertPureDefaultExport(node, entryPath) {
205
- const expression = skipExpressionWrappers(node);
206
- if (ts.isFunctionExpression(expression) || ts.isArrowFunction(expression) || ts.isIdentifier(expression)) return;
207
- throw new Error(`OpenPress document entry default export must be a function component in ${entryPath}`);
208
- }
209
-
210
- function assertPureExpression(node, entryPath, { allowMdxSourceCall }) {
211
- visitExpression(node, (child) => {
212
- if (ts.isAwaitExpression(child)) {
213
- throw new Error(`OpenPress document entry has an unsupported top-level side effect: await in ${entryPath}`);
214
- }
215
- if (ts.isCallExpression(child)) {
216
- const callee = skipExpressionWrappers(child.expression);
217
- if (allowMdxSourceCall && ts.isIdentifier(callee) && callee.text === "mdxSource") return;
218
- if (ts.isIdentifier(callee) && callee.text === "fetch") {
219
- throw new Error(`OpenPress document entry has an unsupported top-level side effect: fetch(...) in ${entryPath}`);
220
- }
221
- if (ts.isPropertyAccessExpression(callee) && isIdentifierText(callee.expression, "console")) {
222
- throw new Error(`OpenPress document entry has an unsupported top-level side effect: console.${callee.name.text}(...) in ${entryPath}`);
223
- }
224
- if (ts.isPropertyAccessExpression(callee) && isIdentifierText(callee.expression, "fs")) {
225
- throw new Error(`OpenPress document entry has an unsupported top-level side effect: fs.${callee.name.text}(...) in ${entryPath}`);
226
- }
227
- throw new Error(`OpenPress document entry cannot execute top-level function calls outside sources.mdxSource(...) in ${entryPath}`);
228
- }
229
- if (ts.isPropertyAccessExpression(child) && isProcessEnvAccess(child)) {
230
- throw new Error(`OpenPress document entry cannot read process.env at top level in ${entryPath}`);
231
- }
232
- });
233
- }
234
-
235
- function visitExpression(node, visitor) {
236
- visitor(node);
237
- if (node !== undefined && node !== null && isFunctionLikeExpression(node)) return;
238
- ts.forEachChild(node, (child) => visitExpression(child, visitor));
239
- }
240
-
241
- function isFunctionLikeExpression(node) {
242
- return ts.isFunctionExpression(node) || ts.isArrowFunction(node) || ts.isClassExpression(node);
243
- }
244
-
245
- function skipExpressionWrappers(node) {
246
- let current = node;
247
- while (ts.isParenthesizedExpression(current) || ts.isAsExpression(current) || ts.isTypeAssertionExpression(current) || ts.isNonNullExpression(current)) {
248
- current = current.expression;
249
- }
250
- return current;
251
- }
252
-
253
- function isProcessEnvAccess(node) {
254
- return node.name.text === "env" && isIdentifierText(skipExpressionWrappers(node.expression), "process");
255
- }
256
-
257
- function isIdentifierText(node, text) {
258
- return ts.isIdentifier(node) && node.text === text;
259
- }
260
-
261
- function hasModifier(node, kind) {
262
- return ts.canHaveModifiers(node) && (ts.getModifiers(node) ?? []).some((modifier) => modifier.kind === kind);
263
- }
264
-
265
- function statementKindName(node) {
266
- return ts.SyntaxKind[node.kind] ?? String(node.kind);
267
- }
268
-
269
- function stringLiteralText(node) {
270
- return ts.isStringLiteral(node) ? node.text : "";
271
- }
272
-
273
- function isFileSystemModule(moduleName) {
274
- return moduleName === "fs" || moduleName === "node:fs" || moduleName === "fs/promises" || moduleName === "node:fs/promises";
275
- }
276
-
277
- async function fileExists(filePath) {
278
- try {
279
- const stat = await fs.stat(filePath);
280
- return stat.isFile();
281
- } catch (error) {
282
- if (error?.code === "ENOENT") return false;
283
- throw error;
284
- }
285
- }
286
-
287
- function reactRuntimePlugin() {
288
- const modules = {
289
- react: "\0openpress-react",
290
- "react/jsx-runtime": "\0openpress-react-jsx-runtime",
291
- "react/jsx-dev-runtime": "\0openpress-react-jsx-dev-runtime",
292
- };
293
- return {
294
- name: "openpress-react-runtime",
295
- enforce: "pre",
296
- resolveId(id) {
297
- return modules[id] ?? null;
298
- },
299
- load(id) {
300
- if (id === modules.react) return reactModuleShim();
301
- if (id === modules["react/jsx-runtime"]) {
302
- return runtimeModuleShim(path.join(REACT_PACKAGE_ROOT, "jsx-runtime.js"), ["Fragment", "jsx", "jsxs"]);
303
- }
304
- if (id === modules["react/jsx-dev-runtime"]) {
305
- return runtimeModuleShim(path.join(REACT_PACKAGE_ROOT, "jsx-dev-runtime.js"), ["Fragment", "jsxDEV"]);
306
- }
307
- return null;
308
- },
309
- };
310
- }
311
-
312
- function runtimeModuleShim(modulePath, names) {
313
- const exports = names.map((name) => `export const ${name} = runtime.${name};`).join("\n");
314
- return `import { createRequire } from "node:module";
315
- const require = createRequire(${JSON.stringify(import.meta.url)});
316
- const runtime = require(${JSON.stringify(modulePath)});
317
- ${exports}
318
- export default runtime;
319
- `;
320
- }
321
-
322
- function reactModuleShim() {
323
- const reactPath = require.resolve("react");
324
- const exports = REACT_EXPORT_NAMES.map((name) => `export const ${name} = React.${name};`).join("\n");
325
- return `import { createRequire } from "node:module";
326
- const require = createRequire(${JSON.stringify(import.meta.url)});
327
- const React = require(${JSON.stringify(reactPath)});
328
- ${exports}
329
- export default React;
330
- `;
331
- }