adtec-core-package 3.0.1 → 3.0.2

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.
@@ -0,0 +1,175 @@
1
+ import { createRequire } from 'node:module'
2
+ import fs from 'node:fs'
3
+ import path from 'node:path'
4
+ import type { Alias } from 'vite'
5
+ import { getProjectRoot } from './projectRoot'
6
+
7
+ export function preferEsmEntry(resolved: string): string {
8
+ if (resolved.endsWith('.cjs')) {
9
+ const js = resolved.replace(/\.cjs$/, '.js')
10
+ const mjs = resolved.replace(/\.cjs$/, '.mjs')
11
+ if (fs.existsSync(mjs)) return mjs
12
+ if (fs.existsSync(js)) return js
13
+ }
14
+ return resolved
15
+ }
16
+
17
+ export function readPkgVersion(pkgJsonPath: string): string | null {
18
+ try {
19
+ const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8')) as { version?: string }
20
+ return pkg.version ?? null
21
+ } catch {
22
+ return null
23
+ }
24
+ }
25
+
26
+ function isTiptapV3(version: string | null): boolean {
27
+ return version != null && version.startsWith('3.')
28
+ }
29
+
30
+ /** 宿主 node_modules/adtec-core-package(npm / pnpm / file: 均适用) */
31
+ export function findCorePackageRoot(): string | null {
32
+ const root = getProjectRoot()
33
+ const linked = path.join(root, 'node_modules/adtec-core-package')
34
+ if (fs.existsSync(path.join(linked, 'package.json'))) {
35
+ try {
36
+ return fs.realpathSync(linked)
37
+ } catch {
38
+ return linked
39
+ }
40
+ }
41
+
42
+ const sibling = path.join(root, '../前端核心包')
43
+ if (fs.existsSync(path.join(sibling, 'package.json'))) {
44
+ return sibling
45
+ }
46
+
47
+ const selfPkg = path.join(root, 'package.json')
48
+ if (fs.existsSync(selfPkg)) {
49
+ try {
50
+ const pkg = JSON.parse(fs.readFileSync(selfPkg, 'utf-8')) as { name?: string }
51
+ if (pkg.name === 'adtec-core-package') return root
52
+ } catch {
53
+ // ignore
54
+ }
55
+ }
56
+
57
+ return null
58
+ }
59
+
60
+ function hostNodeModules(): string {
61
+ return path.join(getProjectRoot(), 'node_modules')
62
+ }
63
+
64
+ function pnpmStoreDir(): string {
65
+ return path.join(hostNodeModules(), '.pnpm')
66
+ }
67
+
68
+ function findTiptapV3RootFromPnpm(): string | null {
69
+ const dir = pnpmStoreDir()
70
+ if (!fs.existsSync(dir)) return null
71
+
72
+ const entries = fs.readdirSync(dir)
73
+ const coreDir =
74
+ entries.find(
75
+ (name) => name.startsWith('@tiptap+core@3.20') && name.includes('@tiptap+pm@3.20'),
76
+ ) ?? entries.find((name) => name.startsWith('@tiptap+core@3.') && name.includes('@tiptap+pm@3.'))
77
+ if (!coreDir) return null
78
+
79
+ const tiptapRoot = path.join(dir, coreDir, 'node_modules')
80
+ if (!fs.existsSync(path.join(tiptapRoot, '@tiptap/core/package.json'))) return null
81
+ return tiptapRoot
82
+ }
83
+
84
+ function findTiptapV3RootFromHoisted(baseNodeModules: string): string | null {
85
+ const corePkg = path.join(baseNodeModules, '@tiptap/core/package.json')
86
+ if (!fs.existsSync(corePkg) || !isTiptapV3(readPkgVersion(corePkg))) return null
87
+ return baseNodeModules
88
+ }
89
+
90
+ /** TipTap 3.x 依赖树根(兼容 pnpm store 与 npm 扁平 node_modules) */
91
+ export function findTiptapV3Root(): string | null {
92
+ const fromPnpm = findTiptapV3RootFromPnpm()
93
+ if (fromPnpm) return fromPnpm
94
+
95
+ const fromHost = findTiptapV3RootFromHoisted(hostNodeModules())
96
+ if (fromHost) return fromHost
97
+
98
+ const coreRoot = findCorePackageRoot()
99
+ if (coreRoot) {
100
+ const fromCore = findTiptapV3RootFromHoisted(path.join(coreRoot, 'node_modules'))
101
+ if (fromCore) return fromCore
102
+ }
103
+
104
+ return null
105
+ }
106
+
107
+ export function findTiptapCorePkgJson(): string | null {
108
+ const tiptapRoot = findTiptapV3Root()
109
+ if (!tiptapRoot) return null
110
+
111
+ const corePkg = path.join(tiptapRoot, '@tiptap/core/package.json')
112
+ return fs.existsSync(corePkg) ? corePkg : null
113
+ }
114
+
115
+ export function findTiptapPmPackageJson(): string | null {
116
+ const dir = pnpmStoreDir()
117
+ const exact = path.join(dir, '@tiptap+pm@3.20.0', 'node_modules', '@tiptap/pm', 'package.json')
118
+ if (fs.existsSync(exact)) return exact
119
+
120
+ if (fs.existsSync(dir)) {
121
+ const pmDir = fs
122
+ .readdirSync(dir)
123
+ .find((name) => name.startsWith('@tiptap+pm@3.20') || name.startsWith('@tiptap+pm@3.'))
124
+ if (pmDir) {
125
+ const candidate = path.join(dir, pmDir, 'node_modules', '@tiptap/pm', 'package.json')
126
+ if (fs.existsSync(candidate)) return candidate
127
+ }
128
+ }
129
+
130
+ const tiptapRoot = findTiptapV3Root()
131
+ if (tiptapRoot) {
132
+ const inTree = path.join(tiptapRoot, '@tiptap/pm/package.json')
133
+ if (fs.existsSync(inTree) && isTiptapV3(readPkgVersion(inTree))) return inTree
134
+ }
135
+
136
+ return null
137
+ }
138
+
139
+ export function resolveFromContext(source: string, contextPkgJson: string): string | null {
140
+ try {
141
+ return preferEsmEntry(createRequire(contextPkgJson).resolve(source))
142
+ } catch {
143
+ return null
144
+ }
145
+ }
146
+
147
+ /** 从宿主或核心包解析模块(npm / pnpm 通用) */
148
+ export function resolveFromHostOrCore(source: string): string | null {
149
+ const root = getProjectRoot()
150
+ const hostPkg = path.join(root, 'package.json')
151
+ if (fs.existsSync(hostPkg)) {
152
+ const resolved = resolveFromContext(source, hostPkg)
153
+ if (resolved) return resolved
154
+ }
155
+
156
+ const coreRoot = findCorePackageRoot()
157
+ if (coreRoot) {
158
+ const corePkg = path.join(coreRoot, 'package.json')
159
+ const resolved = resolveFromContext(source, corePkg)
160
+ if (resolved) return resolved
161
+ }
162
+
163
+ return null
164
+ }
165
+
166
+ export function buildPeerAliases(packages: string[]): Alias[] {
167
+ const aliases: Alias[] = []
168
+ for (const pkg of packages) {
169
+ const resolved = resolveFromHostOrCore(pkg)
170
+ if (resolved) {
171
+ aliases.push({ find: pkg, replacement: resolved })
172
+ }
173
+ }
174
+ return aliases
175
+ }
@@ -2,73 +2,20 @@ import { createRequire } from 'node:module'
2
2
  import fs from 'node:fs'
3
3
  import path from 'node:path'
4
4
  import type { Alias, Plugin } from 'vite'
5
- import { getProjectRoot } from './projectRoot'
5
+ import {
6
+ findTiptapCorePkgJson,
7
+ findTiptapPmPackageJson,
8
+ findTiptapV3Root,
9
+ preferEsmEntry,
10
+ resolveFromContext,
11
+ } from './nodeModulesResolve'
12
+
13
+ export { findTiptapV3Root } from './nodeModulesResolve'
6
14
 
7
15
  const AIEDITOR_MARKERS = ['aieditor', '@tiptap+core@2', '@tiptap+pm@2', '@tiptap+vue-3@2']
8
16
 
9
17
  const OPTIMIZE_DEPS_EXCLUDE = ['@tiptap/core', '@tiptap/pm', '@tiptap/vue-3']
10
18
 
11
- function pnpmDir(): string {
12
- return path.join(getProjectRoot(), 'node_modules/.pnpm')
13
- }
14
-
15
- /** 优先使用宿主 node_modules 中的 TipTap 3.20 依赖树 */
16
- export function findTiptapV3Root(): string | null {
17
- const dir = pnpmDir()
18
- if (!fs.existsSync(dir)) return null
19
-
20
- const entries = fs.readdirSync(dir)
21
- const coreDir =
22
- entries.find(
23
- (name) => name.startsWith('@tiptap+core@3.20') && name.includes('@tiptap+pm@3.20'),
24
- ) ?? entries.find((name) => name.startsWith('@tiptap+core@3.') && name.includes('@tiptap+pm@3.'))
25
- if (!coreDir) return null
26
-
27
- const tiptapRoot = path.join(dir, coreDir, 'node_modules')
28
- if (!fs.existsSync(path.join(tiptapRoot, '@tiptap/core/package.json'))) return null
29
- return tiptapRoot
30
- }
31
-
32
- function findTiptapPmPackageJson(): string | null {
33
- const dir = pnpmDir()
34
- const exact = path.join(dir, '@tiptap+pm@3.20.0', 'node_modules', '@tiptap/pm', 'package.json')
35
- if (fs.existsSync(exact)) return exact
36
-
37
- if (fs.existsSync(dir)) {
38
- const pmDir = fs
39
- .readdirSync(dir)
40
- .find((name) => name.startsWith('@tiptap+pm@3.20') || name.startsWith('@tiptap+pm@3.'))
41
- if (pmDir) {
42
- const candidate = path.join(dir, pmDir, 'node_modules', '@tiptap/pm', 'package.json')
43
- if (fs.existsSync(candidate)) return candidate
44
- }
45
- }
46
-
47
- const tiptapRoot = findTiptapV3Root()
48
- if (tiptapRoot) {
49
- const inTree = path.join(tiptapRoot, '@tiptap/pm/package.json')
50
- if (fs.existsSync(inTree)) return inTree
51
- }
52
-
53
- return null
54
- }
55
-
56
- function preferEsmEntry(resolved: string): string {
57
- if (resolved.endsWith('.cjs')) {
58
- const js = resolved.replace(/\.cjs$/, '.js')
59
- if (fs.existsSync(js)) return js
60
- }
61
- return resolved
62
- }
63
-
64
- function resolveFromContext(source: string, contextPkgJson: string): string | null {
65
- try {
66
- return preferEsmEntry(createRequire(contextPkgJson).resolve(source))
67
- } catch {
68
- return null
69
- }
70
- }
71
-
72
19
  function buildVue3Aliases(requireFromV3: NodeRequire): Alias[] {
73
20
  const aliases: Alias[] = []
74
21
  try {
@@ -99,11 +46,10 @@ function buildProsemirrorAliases(): Alias[] {
99
46
  }
100
47
 
101
48
  export function buildTiptapV3Aliases(): Alias[] {
102
- const tiptapV3Root = findTiptapV3Root()
103
- if (!tiptapV3Root) return buildProsemirrorAliases()
49
+ const corePkgJson = findTiptapCorePkgJson()
50
+ if (!corePkgJson) return buildProsemirrorAliases()
104
51
 
105
- const requireFromV3 = createRequire(path.join(tiptapV3Root, '@tiptap/core/package.json'))
106
- void requireFromV3
52
+ const requireFromV3 = createRequire(corePkgJson)
107
53
  return [...buildProsemirrorAliases(), ...buildVue3Aliases(requireFromV3)]
108
54
  }
109
55
 
@@ -122,8 +68,7 @@ export function tiptapUmoResolve(): Plugin {
122
68
  if (importer && AIEDITOR_MARKERS.some((marker) => importer.includes(marker))) return null
123
69
  if (source === '@tiptap/vue-3') return null
124
70
 
125
- const tiptapV3Root = findTiptapV3Root()
126
- const corePkgJson = tiptapV3Root ? path.join(tiptapV3Root, '@tiptap/core/package.json') : null
71
+ const corePkgJson = findTiptapCorePkgJson()
127
72
  const pmPkgJson = findTiptapPmPackageJson()
128
73
 
129
74
  if (corePkgJson && source.startsWith('@tiptap/')) {
@@ -2,7 +2,7 @@ import fs from 'node:fs'
2
2
  import path from 'node:path'
3
3
  import { createRequire } from 'node:module'
4
4
  import type { Plugin } from 'vite'
5
- import { findTiptapV3Root } from './tiptapUmoResolve'
5
+ import { findTiptapCorePkgJson } from './nodeModulesResolve'
6
6
  import { getProjectRoot } from './projectRoot'
7
7
 
8
8
  const VIRTUAL_TIPTAP_VUE3 = '\0virtual:patched-tiptap-vue-3'
@@ -92,10 +92,10 @@ function findCanonicalTiptapVue3Entry(): string | null {
92
92
  }
93
93
  }
94
94
 
95
- const tiptapRoot = findTiptapV3Root()
96
- if (!tiptapRoot) return null
95
+ const corePkgJson = findTiptapCorePkgJson()
96
+ if (!corePkgJson) return null
97
97
 
98
- const pkgJson = path.join(tiptapRoot, '@tiptap/vue-3/package.json')
98
+ const pkgJson = path.join(path.dirname(path.dirname(corePkgJson)), '@tiptap/vue-3/package.json')
99
99
  if (!fs.existsSync(pkgJson)) return null
100
100
 
101
101
  try {
@@ -114,7 +114,7 @@ function loadPatchedTiptapVue3Code(): string {
114
114
 
115
115
  const entry = findCanonicalTiptapVue3Entry()
116
116
  if (!entry) {
117
- throw new Error('[tiptap-vue-renderer-fix] 未找到 @tiptap/vue-3@3.20,请先 pnpm install')
117
+ throw new Error('[tiptap-vue-renderer-fix] 未找到 @tiptap/vue-3@3.x,请先 npm/pnpm install')
118
118
  }
119
119
 
120
120
  const patched = patchTiptapVueRendererCode(fs.readFileSync(entry, 'utf-8'))