-
-
Notifications
You must be signed in to change notification settings - Fork 11.9k
Expand file tree
/
Copy path.dependency-cruiser.cjs
More file actions
130 lines (126 loc) · 6.76 KB
/
Copy path.dependency-cruiser.cjs
File metadata and controls
130 lines (126 loc) · 6.76 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
'use strict';
/*
* Architectural boundary rules for the monorepo, enforced on the resolved
* module graph (require AND import). Two sections:
*
* ghost/core — layer separation inside the Ghost server: shared/ must stay
* dependency-free, frontend/ crosses to server/ only via the
* proxy seam, and server/ must not reach into the frontend
* rendering layer. Paths are anchored on `^ghost/core/core/`.
*
* apps/ — design system layer hierarchy and public/admin separation.
* shade/ is a leaf package that nothing above it may pull
* back into. admin-x-framework/ sits above it but below
* feature apps. Public UMD bundles (portal, comments-ui,
* etc.) must not depend on admin libs.
*
* Workspace packages appear as unresolved `@tryghost/*` module
* specifiers in the graph (pnpm workspace symlinks are stopped
* by doNotFollow:node_modules), so `to.path` matches on
* package name rather than a file path.
*
* @type {import('dependency-cruiser').IConfiguration}
*/
module.exports = {
forbidden: [
// ============================================================
// shared/ must not require server/* or frontend/*
// ============================================================
{
name: 'shared-not-server-or-frontend',
comment: 'Invalid require of core/server or core/frontend from core/shared.',
severity: 'error',
from: {path: '^ghost/core/core/shared/'},
to: {path: '^ghost/core/core/(server|frontend)/'}
},
// ============================================================
// Frontend must not require server/models directly
// ============================================================
{
name: 'frontend-not-server-models',
comment: 'Invalid require of core/server/models from core/frontend. Fetch content through the public Content API (api.postsPublic / api.pagesPublic), injected via core/frontend/services/proxy — not the model layer directly. See #28420.',
severity: 'error',
from: {path: '^ghost/core/core/frontend/'},
to: {path: '^ghost/core/core/server/models/'}
},
// ============================================================
// Frontend must cross to server only via proxy (with allowlist)
// ============================================================
{
name: 'frontend-to-server-via-proxy-only',
comment: 'Invalid require of core/server from core/frontend. Cross only via the proxy seam (core/frontend/services/proxy.js).',
severity: 'error',
from: {
path: '^ghost/core/core/frontend/',
// Adding files to this list is an anti-pattern
// Goal: Work down until only proxy.js remains
pathNot: [
// The sanctioned seam.
'^ghost/core/core/frontend/services/proxy\\.js$',
// Composition root wiring (less wrong).
'^ghost/core/core/frontend/web/site\\.js$',
'^ghost/core/core/frontend/web/middleware/frontend-caching\\.js$',
'^ghost/core/core/frontend/web/middleware/handle-image-sizes\\.js$',
'^ghost/core/core/frontend/web/routers/link-redirects\\.js$',
'^ghost/core/core/frontend/apps/private-blogging/lib/router\\.js$'
]
},
to: {path: '^ghost/core/core/server/'}
},
// ============================================================
// Server must not require frontend (with allowlist)
// ============================================================
{
name: 'server-not-frontend',
comment: 'Invalid require of core/frontend from core/server. The server must not depend on the frontend rendering layer.',
severity: 'error',
from: {
path: '^ghost/core/core/server/',
// Adding files to this list is an anti-pattern
// Goal: Work down until the list is empty
pathNot: [
// Composition root: mounts the frontend Express app onto the server (less wrong).
'^ghost/core/core/server/web/parent/frontend\\.js$',
// Leak: route-settings reaches into the frontend routing config for QUERY/TAXONOMIES (fix first — config should be injected, see the in-file TODO).
'^ghost/core/core/server/services/route-settings/validate\\.js$',
'^ghost/core/core/server/services/route-settings/activation-bridge\\.ts$'
]
},
to: {path: '^ghost/core/core/frontend/'}
},
// ============================================================
// apps/ — shade/ is the foundation; must not depend on higher layers
// ============================================================
{
name: 'shade-is-leaf',
comment: 'shade/ must not depend on admin-x-framework. It is the foundation layer.',
severity: 'error',
from: {path: '^apps/shade/'},
to: {path: '^@tryghost/admin-x-framework'}
},
// ============================================================
// apps/ — admin-x-framework/ must not depend on feature apps
// ============================================================
{
name: 'framework-not-feature-apps',
comment: 'admin-x-framework/ must not depend on feature apps (activitypub, admin-x-settings). The framework layer sits below the feature layer.',
severity: 'error',
from: {path: '^apps/admin-x-framework/'},
to: {path: '^@tryghost/(activitypub|admin-x-settings)'}
},
// ============================================================
// apps/ — public UMD apps must not depend on admin-only libraries
// ============================================================
{
name: 'public-apps-not-admin-libs',
comment: 'Public UMD apps (portal, comments-ui, etc.) must not depend on admin-only libraries (shade, admin-x-framework).',
severity: 'error',
from: {path: '^apps/(portal|comments-ui|signup-form|sodo-search|announcement-bar|admin-toolbar)/'},
to: {path: '^@tryghost/(shade|admin-x-framework)'}
}
],
options: {
doNotFollow: {path: 'node_modules'},
exclude: {path: '(^|/)(node_modules|coverage|coverage-next|test|built|dist)/'}
}
};