@aphexcms/cms-core 5.0.5 → 6.0.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.
- package/dist/components/AdminApp.svelte +3 -9
- package/dist/components/AdminApp.svelte.d.ts.map +1 -1
- package/dist/components/admin/AssetBrowserModal.svelte +2 -1
- package/dist/components/admin/DocumentEditor.svelte +7 -3
- package/dist/components/admin/DocumentEditor.svelte.d.ts.map +1 -1
- package/dist/components/admin/MediaBrowser.svelte +3 -2
- package/dist/components/admin/ObjectModal.svelte +1 -1
- package/dist/components/admin/fields/ArrayField.svelte +23 -14
- package/dist/components/admin/fields/ArrayField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/FileField.svelte +17 -6
- package/dist/components/admin/fields/FileField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ImageField.svelte +21 -6
- package/dist/components/admin/fields/ImageField.svelte.d.ts.map +1 -1
- package/dist/components/admin/fields/ReferenceField.svelte +26 -9
- package/dist/components/admin/fields/ReferenceField.svelte.d.ts.map +1 -1
- package/dist/hooks.d.ts +11 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/hooks.js +39 -22
- package/dist/lib/hooks.d.ts +11 -0
- package/dist/lib/hooks.d.ts.map +1 -1
- package/dist/lib/hooks.js +39 -22
- package/dist/lib/hooks.js.map +1 -1
- package/dist/lib/schema-utils/validator.d.ts.map +1 -1
- package/dist/lib/schema-utils/validator.js +10 -7
- package/dist/lib/schema-utils/validator.js.map +1 -1
- package/dist/lib/server/index.d.ts +1 -1
- package/dist/lib/server/index.d.ts.map +1 -1
- package/dist/lib/server/index.js +1 -1
- package/dist/lib/server/index.js.map +1 -1
- package/dist/lib/types/schemas.d.ts +2 -0
- package/dist/lib/types/schemas.d.ts.map +1 -1
- package/dist/lib/utils/preview.d.ts +20 -0
- package/dist/lib/utils/preview.d.ts.map +1 -0
- package/dist/lib/utils/preview.js +68 -0
- package/dist/lib/utils/preview.js.map +1 -0
- package/dist/lib/vite/index.d.ts +86 -0
- package/dist/lib/vite/index.d.ts.map +1 -0
- package/dist/lib/vite/index.js +274 -0
- package/dist/lib/vite/index.js.map +1 -0
- package/dist/schema-utils/validator.d.ts.map +1 -1
- package/dist/schema-utils/validator.js +10 -7
- package/dist/server/index.d.ts +1 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/types/schemas.d.ts +2 -0
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/utils/preview.d.ts +20 -0
- package/dist/utils/preview.d.ts.map +1 -0
- package/dist/utils/preview.js +67 -0
- package/dist/vite/index.d.ts +86 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +273 -0
- package/package.json +6 -2
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
import { createRequire } from 'node:module';
|
|
2
|
+
const require = createRequire(import.meta.url);
|
|
3
|
+
/**
|
|
4
|
+
* Watches the CMS config and schema files in dev. When any of them change,
|
|
5
|
+
* the plugin re-loads `aphex.config.ts` via Vite's SSR loader (so the fresh
|
|
6
|
+
* module re-runs the schema imports) and hands the new config to cms-core's
|
|
7
|
+
* `__notifyAphexConfigChanged()` setter — the engine then re-initializes on
|
|
8
|
+
* the next request without restarting the Vite dev server.
|
|
9
|
+
*
|
|
10
|
+
* Why this works without races:
|
|
11
|
+
* - `server.ssrLoadModule` is Vite's official re-eval path, no cache-bust hacks
|
|
12
|
+
* - The plugin and the running SvelteKit hook share the same cms-core module
|
|
13
|
+
* instance through Vite's module graph, so the setter mutates the same
|
|
14
|
+
* `activeConfig` the hook reads on each request
|
|
15
|
+
* - A single mutation point (`__notifyAphexConfigChanged`) replaces the old
|
|
16
|
+
* global dirty-flag protocol; no two-step set-then-read race window
|
|
17
|
+
*
|
|
18
|
+
* Falls back to `server.restart()` automatically if the swap throws (e.g.
|
|
19
|
+
* the user introduced a syntax error in their schema). `mode: 'restart'`
|
|
20
|
+
* forces the slower-but-most-correct path on every change.
|
|
21
|
+
*/
|
|
22
|
+
export function aphexHMR(options = {}) {
|
|
23
|
+
const schemaDir = options.schemaDir ?? '/schemaTypes/';
|
|
24
|
+
const configFile = options.configFile ?? 'aphex.config.ts';
|
|
25
|
+
const debounceMs = options.debounceMs ?? 150;
|
|
26
|
+
const mode = options.mode ?? 'swap';
|
|
27
|
+
return {
|
|
28
|
+
name: 'aphex:hmr',
|
|
29
|
+
configureServer(server) {
|
|
30
|
+
const { watcher, ws } = server;
|
|
31
|
+
function isReloadTarget(file) {
|
|
32
|
+
const normalized = file.replace(/\\/g, '/');
|
|
33
|
+
return ((normalized.includes(schemaDir) && normalized.endsWith('.ts')) ||
|
|
34
|
+
normalized.endsWith(`/${configFile}`));
|
|
35
|
+
}
|
|
36
|
+
async function swapSchemas(file) {
|
|
37
|
+
const start = Date.now();
|
|
38
|
+
const configPath = `${server.config.root}/${configFile}`;
|
|
39
|
+
// Invalidate the changed file + the config + the schemaTypes barrel
|
|
40
|
+
// so ssrLoadModule re-evaluates with the new disk contents.
|
|
41
|
+
for (const path of [file, configPath]) {
|
|
42
|
+
const mods = server.moduleGraph.getModulesByFile(path);
|
|
43
|
+
mods?.forEach((mod) => server.moduleGraph.invalidateModule(mod));
|
|
44
|
+
}
|
|
45
|
+
const configMod = await server.ssrLoadModule(configPath);
|
|
46
|
+
const freshConfig = configMod.default;
|
|
47
|
+
if (!freshConfig) {
|
|
48
|
+
throw new Error(`${configFile} did not export a default config`);
|
|
49
|
+
}
|
|
50
|
+
const cmsCore = await server.ssrLoadModule('@aphexcms/cms-core/server');
|
|
51
|
+
if (typeof cmsCore.__notifyAphexConfigChanged !== 'function') {
|
|
52
|
+
throw new Error('cms-core does not expose __notifyAphexConfigChanged — upgrade @aphexcms/cms-core');
|
|
53
|
+
}
|
|
54
|
+
cmsCore.__notifyAphexConfigChanged(freshConfig);
|
|
55
|
+
ws.send({ type: 'full-reload' });
|
|
56
|
+
console.log(`🔄 CMS schemas hot-swapped (${Date.now() - start}ms): ${file}`);
|
|
57
|
+
}
|
|
58
|
+
let pending = null;
|
|
59
|
+
let lastFile = '';
|
|
60
|
+
function scheduleReload(file) {
|
|
61
|
+
lastFile = file;
|
|
62
|
+
if (pending)
|
|
63
|
+
clearTimeout(pending);
|
|
64
|
+
pending = setTimeout(async () => {
|
|
65
|
+
pending = null;
|
|
66
|
+
if (mode === 'restart') {
|
|
67
|
+
console.log(`🔄 CMS schema change → restarting dev server: ${lastFile}`);
|
|
68
|
+
server.restart().catch((err) => {
|
|
69
|
+
console.error('[aphex] dev server restart failed:', err);
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
try {
|
|
74
|
+
await swapSchemas(lastFile);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
console.error('[aphex] hot-swap failed, falling back to restart:', err);
|
|
78
|
+
server.restart().catch((err) => {
|
|
79
|
+
console.error('[aphex] dev server restart failed:', err);
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}, debounceMs);
|
|
83
|
+
}
|
|
84
|
+
for (const event of ['change', 'add', 'unlink']) {
|
|
85
|
+
watcher.on(event, (file) => {
|
|
86
|
+
if (isReloadTarget(file))
|
|
87
|
+
scheduleReload(file);
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Redirects `dayjs` and `dayjs/plugin/*` imports to dayjs's ESM build.
|
|
95
|
+
*
|
|
96
|
+
* dayjs 1.x ships a UMD `main` (`dayjs.min.js`) with no `exports` map or
|
|
97
|
+
* `module` field. When imports originate inside a package excluded from
|
|
98
|
+
* Vite's pre-bundling (e.g. `@aphexcms/cms-core`), Vite serves the raw UMD
|
|
99
|
+
* — which has no ESM `default` export — and the browser blows up with
|
|
100
|
+
* "does not provide an export named 'default'". This alias guarantees every
|
|
101
|
+
* dayjs import resolves to the proper ESM build.
|
|
102
|
+
*/
|
|
103
|
+
function aphexDayjsAlias() {
|
|
104
|
+
return {
|
|
105
|
+
name: 'aphex:dayjs-alias',
|
|
106
|
+
config() {
|
|
107
|
+
const dayjsEsm = require.resolve('dayjs/esm/index.js');
|
|
108
|
+
const dayjsEsmPluginDir = dayjsEsm.replace(/\/index\.js$/, '/plugin');
|
|
109
|
+
return {
|
|
110
|
+
resolve: {
|
|
111
|
+
alias: [
|
|
112
|
+
{ find: /^dayjs$/, replacement: dayjsEsm },
|
|
113
|
+
{
|
|
114
|
+
find: /^dayjs\/plugin\/([^/]+?)(\.js)?$/,
|
|
115
|
+
replacement: `${dayjsEsmPluginDir}/$1/index.js`
|
|
116
|
+
}
|
|
117
|
+
]
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* SSR config: cms-core and ui packages re-export `.svelte` components through
|
|
125
|
+
* their entry barrels — Vite must bundle them for SSR. If they are externalised,
|
|
126
|
+
* Node's native ESM loader tries to resolve the raw `.svelte` files directly
|
|
127
|
+
* and throws ERR_UNKNOWN_FILE_EXTENSION (the `svelte` export condition is only
|
|
128
|
+
* honoured by Vite, not by Node).
|
|
129
|
+
*
|
|
130
|
+
* sharp/graphql/graphql-yoga are native or large CJS deps that should stay
|
|
131
|
+
* external — bundling them breaks Node's native bindings or balloons the SSR
|
|
132
|
+
* bundle.
|
|
133
|
+
*/
|
|
134
|
+
function aphexSSR() {
|
|
135
|
+
return {
|
|
136
|
+
name: 'aphex:ssr',
|
|
137
|
+
config() {
|
|
138
|
+
return {
|
|
139
|
+
ssr: {
|
|
140
|
+
noExternal: ['@aphexcms/ui', '@aphexcms/cms-core'],
|
|
141
|
+
external: ['sharp', 'graphql', 'graphql-yoga']
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* optimizeDeps tuning: exclude the Aphex Svelte packages from esbuild
|
|
149
|
+
* pre-bundling (esbuild can't transform `.svelte` files; vite-plugin-svelte
|
|
150
|
+
* handles them at transform time instead), and pre-bundle their transitive
|
|
151
|
+
* deps that Vite would otherwise discover lazily at runtime — which causes
|
|
152
|
+
* full-page reloads when the user first navigates to a route that triggers
|
|
153
|
+
* a new dep.
|
|
154
|
+
*/
|
|
155
|
+
function aphexOptimizeDeps() {
|
|
156
|
+
return {
|
|
157
|
+
name: 'aphex:optimize-deps',
|
|
158
|
+
config() {
|
|
159
|
+
return {
|
|
160
|
+
optimizeDeps: {
|
|
161
|
+
exclude: ['sharp', '@aphexcms/ui', '@aphexcms/cms-core'],
|
|
162
|
+
include: [
|
|
163
|
+
'tailwind-variants',
|
|
164
|
+
'tailwind-merge',
|
|
165
|
+
'@internationalized/date',
|
|
166
|
+
'bits-ui',
|
|
167
|
+
'dayjs',
|
|
168
|
+
'dayjs/plugin/customParseFormat',
|
|
169
|
+
'dayjs/plugin/customParseFormat.js',
|
|
170
|
+
'dayjs/plugin/utc',
|
|
171
|
+
'dayjs/plugin/utc.js',
|
|
172
|
+
'@lucide/svelte',
|
|
173
|
+
'@lucide/svelte/icons/panel-left',
|
|
174
|
+
'@lucide/svelte/icons/minus',
|
|
175
|
+
'@lucide/svelte/icons/circle',
|
|
176
|
+
'@lucide/svelte/icons/chevron-right',
|
|
177
|
+
'@lucide/svelte/icons/search',
|
|
178
|
+
'@lucide/svelte/icons/bot',
|
|
179
|
+
'@lucide/svelte/icons/calendar',
|
|
180
|
+
'@lucide/svelte/icons/check',
|
|
181
|
+
'@lucide/svelte/icons/chevron-down',
|
|
182
|
+
'@lucide/svelte/icons/chevron-left',
|
|
183
|
+
'@lucide/svelte/icons/chevron-up',
|
|
184
|
+
'@lucide/svelte/icons/chevrons-up-down',
|
|
185
|
+
'@lucide/svelte/icons/circle-check',
|
|
186
|
+
'@lucide/svelte/icons/info',
|
|
187
|
+
'@lucide/svelte/icons/loader-2',
|
|
188
|
+
'@lucide/svelte/icons/octagon-x',
|
|
189
|
+
'@lucide/svelte/icons/plus',
|
|
190
|
+
'@lucide/svelte/icons/triangle-alert',
|
|
191
|
+
'@lucide/svelte/icons/x',
|
|
192
|
+
'better-auth/client/plugins',
|
|
193
|
+
'better-auth/svelte',
|
|
194
|
+
'mode-watcher',
|
|
195
|
+
'svelte-sonner',
|
|
196
|
+
'@aphexcms/cms-core > @dnd-kit/helpers',
|
|
197
|
+
'@aphexcms/cms-core > @dnd-kit/svelte',
|
|
198
|
+
'@aphexcms/cms-core > @dnd-kit/svelte/sortable',
|
|
199
|
+
'@aphexcms/cms-core > dayjs',
|
|
200
|
+
'@aphexcms/cms-core > dayjs/plugin/customParseFormat',
|
|
201
|
+
'@aphexcms/cms-core > dayjs/plugin/customParseFormat.js',
|
|
202
|
+
'@aphexcms/cms-core > dayjs/plugin/utc',
|
|
203
|
+
'@aphexcms/cms-core > dayjs/plugin/utc.js'
|
|
204
|
+
]
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Vite's default watcher ignores `node_modules`. In a workspace setup where
|
|
212
|
+
* Aphex packages are linked from `node_modules/@aphexcms/*`, edits to those
|
|
213
|
+
* source files won't trigger HMR unless we explicitly un-ignore them.
|
|
214
|
+
*/
|
|
215
|
+
function aphexWatchUnfilter() {
|
|
216
|
+
return {
|
|
217
|
+
name: 'aphex:watch-unfilter',
|
|
218
|
+
config() {
|
|
219
|
+
return {
|
|
220
|
+
server: {
|
|
221
|
+
watch: {
|
|
222
|
+
ignored: [
|
|
223
|
+
'!**/node_modules/@aphexcms/cms-core/**',
|
|
224
|
+
'!**/node_modules/@aphexcms/ui/**'
|
|
225
|
+
]
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* One-stop Vite plugin for AphexCMS apps. Bundles:
|
|
234
|
+
*
|
|
235
|
+
* - schema HMR (restart-on-change)
|
|
236
|
+
* - dayjs ESM alias redirect
|
|
237
|
+
* - SSR noExternal/external defaults for cms-core/ui packages
|
|
238
|
+
* - optimizeDeps tuning so first-render isn't slowed by lazy dep discovery
|
|
239
|
+
* - watcher un-ignore for in-monorepo Aphex package edits
|
|
240
|
+
*
|
|
241
|
+
* Each piece can be opted out individually. Returns an array of plugins so
|
|
242
|
+
* Vite can attach each one separately and keep diagnostics readable.
|
|
243
|
+
*
|
|
244
|
+
* Usage:
|
|
245
|
+
*
|
|
246
|
+
* ```ts
|
|
247
|
+
* // vite.config.ts
|
|
248
|
+
* import { aphex } from '@aphexcms/cms-core/vite';
|
|
249
|
+
*
|
|
250
|
+
* export default defineConfig({
|
|
251
|
+
* plugins: [tailwindcss(), sveltekit(), aphex()]
|
|
252
|
+
* });
|
|
253
|
+
* ```
|
|
254
|
+
*/
|
|
255
|
+
export function aphex(options = {}) {
|
|
256
|
+
const plugins = [];
|
|
257
|
+
if (options.hmr !== false) {
|
|
258
|
+
plugins.push(aphexHMR(options.hmr ?? {}));
|
|
259
|
+
}
|
|
260
|
+
if (options.dayjs !== false) {
|
|
261
|
+
plugins.push(aphexDayjsAlias());
|
|
262
|
+
}
|
|
263
|
+
if (options.ssr !== false) {
|
|
264
|
+
plugins.push(aphexSSR());
|
|
265
|
+
}
|
|
266
|
+
if (options.optimizeDeps !== false) {
|
|
267
|
+
plugins.push(aphexOptimizeDeps());
|
|
268
|
+
}
|
|
269
|
+
if (options.watch !== false) {
|
|
270
|
+
plugins.push(aphexWatchUnfilter());
|
|
271
|
+
}
|
|
272
|
+
return plugins;
|
|
273
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@aphexcms/cms-core",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.0.0",
|
|
4
4
|
"description": "Aphex CMS Core - A Sanity-style CMS with ports and adapters architecture",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -36,6 +36,10 @@
|
|
|
36
36
|
"types": "./dist/schema/index.d.ts",
|
|
37
37
|
"default": "./dist/schema/index.js"
|
|
38
38
|
},
|
|
39
|
+
"./vite": {
|
|
40
|
+
"types": "./dist/vite/index.d.ts",
|
|
41
|
+
"default": "./dist/vite/index.js"
|
|
42
|
+
},
|
|
39
43
|
"./app-augment": {
|
|
40
44
|
"types": "./dist/app-augment.d.ts",
|
|
41
45
|
"default": "./dist/app-augment.js"
|
|
@@ -77,7 +81,7 @@
|
|
|
77
81
|
"svelte": "^5.44.0",
|
|
78
82
|
"tailwind-merge": "^3.4.0",
|
|
79
83
|
"tailwind-variants": "^3.2.2",
|
|
80
|
-
"@aphexcms/ui": "0.
|
|
84
|
+
"@aphexcms/ui": "0.5.0"
|
|
81
85
|
},
|
|
82
86
|
"peerDependenciesMeta": {
|
|
83
87
|
"graphql": {
|