nextjs-cms 0.5.58 → 0.5.60

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,3 +1,4 @@
1
+ export declare const getConfigImportVersion: () => number;
1
2
  /**
2
3
  * Turbopack-safe loader:
3
4
  * - In Next 16 Turbopack SSR, dynamic require(found) fails ("expression is too dynamic")
@@ -1 +1 @@
1
- {"version":3,"file":"loader-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader-with-esbuild.ts"],"names":[],"mappings":"AAgFA;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,OAAO,CA2BxD,CAAA"}
1
+ {"version":3,"file":"loader-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader-with-esbuild.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,sBAAsB,cAAmC,CAAA;AA0KtE;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,QAAa,OAAO,CAAC,OAAO,CAiBxD,CAAA"}
@@ -4,12 +4,116 @@
4
4
  // - Uses runtime import(file://...) with `turbopackIgnore`
5
5
  // - Still supports TS configs via esbuild-register
6
6
  // - Keeps your Node CJS resolve patch for tests (js specifier -> ts fallback)
7
- import { existsSync } from 'fs';
7
+ import { existsSync, mkdirSync, statSync } from 'fs';
8
8
  import { resolve, join } from 'path';
9
9
  import { createRequire } from 'module';
10
10
  import { pathToFileURL } from 'url';
11
+ import chokidar from 'chokidar';
12
+ import chalk from 'chalk';
13
+ import { writeFileSync } from 'fs';
14
+ import crypto from 'crypto';
11
15
  // Create a require function that works in ES modules
12
16
  const safeRequire = createRequire(import.meta.url);
17
+ const configWatcherState = (() => {
18
+ const key = Symbol.for('nextjs-cms.configWatcher');
19
+ const globalAny = globalThis;
20
+ if (!globalAny[key]) {
21
+ globalAny[key] = {
22
+ watcher: null,
23
+ version: 0,
24
+ lastEventAt: new Map(),
25
+ };
26
+ }
27
+ return globalAny[key];
28
+ })();
29
+ export const getConfigImportVersion = () => configWatcherState.version;
30
+ const hotMarkerFile = resolve(process.cwd(), 'components/form/helpers/_section-hot-reload.js');
31
+ const getEsbuild = () => safeRequire('esbuild');
32
+ const configCacheRoot = resolve(process.cwd(), '.nextjs-cms', 'config');
33
+ if (!existsSync(configCacheRoot))
34
+ mkdirSync(configCacheRoot, { recursive: true });
35
+ const hashKey = (s) => crypto.createHash('sha1').update(s).digest('hex');
36
+ const ensureBundledConfig = async (entryAbsPath) => {
37
+ const esbuild = getEsbuild();
38
+ // Make output stable per file path and rebuild only when the source is newer
39
+ const st = statSync(entryAbsPath);
40
+ const key = hashKey(entryAbsPath);
41
+ const outFile = join(configCacheRoot, `${key}.mjs`);
42
+ if (existsSync(outFile)) {
43
+ const outStat = statSync(outFile);
44
+ if (outStat.mtimeMs >= st.mtimeMs)
45
+ return outFile;
46
+ }
47
+ // Bundle so extensionless imports work (esbuild resolves them)
48
+ await esbuild.build({
49
+ entryPoints: [entryAbsPath],
50
+ outfile: outFile,
51
+ bundle: true,
52
+ platform: 'node',
53
+ format: 'esm',
54
+ target: 'node18',
55
+ sourcemap: 'inline',
56
+ logLevel: 'silent',
57
+ // This is the magic for your UX:
58
+ resolveExtensions: ['.ts', '.tsx', '.mts', '.cts', '.js', '.jsx', '.mjs', '.cjs', '.json'],
59
+ // Don't bundle your library deps; keep them as runtime imports
60
+ packages: 'external',
61
+ });
62
+ return outFile;
63
+ };
64
+ const bumpHotMarker = async () => {
65
+ if (process.env.NODE_ENV === 'production')
66
+ return;
67
+ const content = `/**\n` +
68
+ ` * AUTO-GENERATED. DO NOT EDIT.\n` +
69
+ ` * This file is used to track the last time the sections/config schema was updated.\n` +
70
+ ` * It is used to trigger a hot reload of the section/config in development mode.\n` +
71
+ ` */\n` +
72
+ `\n` +
73
+ `export const revalidate = 0\n` +
74
+ `\n` +
75
+ `// @refresh reset\n` +
76
+ `\n` +
77
+ `export const configLastUpdated = ${Date.now()}\n`;
78
+ try {
79
+ writeFileSync(hotMarkerFile, content, 'utf8');
80
+ }
81
+ catch (err) {
82
+ console.error('Failed to bump _section-hot-reload.js:', err);
83
+ }
84
+ };
85
+ const startConfigWatcher = () => {
86
+ if (process.env.NODE_ENV === 'production' || configWatcherState.watcher)
87
+ return;
88
+ const cwd = process.cwd();
89
+ const invalidateForRelPath = async (relPath) => {
90
+ const normalized = relPath.replace(/\\/g, '/');
91
+ const now = Date.now();
92
+ const last = configWatcherState.lastEventAt.get(normalized);
93
+ if (last && now - last < 150)
94
+ return;
95
+ configWatcherState.lastEventAt.set(normalized, now);
96
+ console.log(chalk.green('Detected config file change, reloading config...'));
97
+ const absPath = resolve(cwd, relPath);
98
+ delete safeRequire.cache?.[absPath];
99
+ configWatcherState.version++;
100
+ await bumpHotMarker();
101
+ };
102
+ configWatcherState.watcher = chokidar
103
+ .watch('cms.config.*', {
104
+ cwd,
105
+ ignoreInitial: true,
106
+ atomic: true,
107
+ awaitWriteFinish: {
108
+ stabilityThreshold: 100,
109
+ pollInterval: 20,
110
+ },
111
+ })
112
+ .setMaxListeners(3)
113
+ .on('add', async (path) => await invalidateForRelPath(path))
114
+ .on('change', async (path) => await invalidateForRelPath(path))
115
+ .on('unlink', async (path) => await invalidateForRelPath(path));
116
+ };
13
117
  /**
14
118
  * See SectionFactory.ts: during dev/tests we may runtime-load TS that contains NodeNext-style `./x.js` specifiers
15
119
  * pointing at `./x.ts` in the source tree. Patch CJS resolution to fall back to `.ts` for relative imports.
@@ -74,25 +178,18 @@ const findConfigFile = () => {
74
178
  * - Use runtime import(file://...) and tell turbopack to ignore analyzing it.
75
179
  */
76
180
  export const loadConfigModule = async () => {
181
+ startConfigWatcher();
77
182
  const { found, isTs } = findConfigFile();
78
- let unregister;
79
- try {
80
- if (isTs) {
81
- unregister = registerEsbuildForTs();
82
- }
83
- // For tests (NODE_ENV=test), keep your CJS resolver patch behavior
84
- const importConfig = async () => {
85
- const url = pathToFileURL(found).href;
86
- // IMPORTANT: prevent Turbopack from trying to statically analyze the specifier
87
- const mod = await import(/* turbopackIgnore: true */ url);
88
- return mod;
89
- };
90
- const mod = process.env.NODE_ENV === 'test' && isTs
91
- ? await withPatchedCjsResolveJsToTs(() => importConfig())
92
- : await importConfig();
183
+ if (!isTs) {
184
+ // For non-TS configs, load directly
185
+ const url = pathToFileURL(found).href;
186
+ // IMPORTANT: prevent Turbopack from trying to statically analyze the specifier
187
+ const mod = await import(/* turbopackIgnore: true */ url);
93
188
  return mod?.default ?? mod;
94
189
  }
95
- finally {
96
- unregister?.();
97
- }
190
+ // For TS configs, bundle them first (like sections do)
191
+ const bundled = await ensureBundledConfig(found);
192
+ const url = `${pathToFileURL(bundled).href}?v=${configWatcherState.version}`;
193
+ const mod = await import(/* turbopackIgnore: true */ url);
194
+ return mod?.default ?? mod;
98
195
  };
@@ -1,2 +1,2 @@
1
- export * from './loader-with-jiti.js';
1
+ export * from './loader-with-esbuild.js';
2
2
  //# sourceMappingURL=loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAA"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/core/config/loader.ts"],"names":[],"mappings":"AAAA,cAAc,0BAA0B,CAAA"}
@@ -1 +1 @@
1
- export * from './loader-with-jiti.js';
1
+ export * from './loader-with-esbuild.js';
@@ -1,2 +1,2 @@
1
- export * from './section-factory-with-jiti.js';
1
+ export * from './section-factory-with-esbuild.js';
2
2
  //# sourceMappingURL=SectionFactory.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"SectionFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/SectionFactory.ts"],"names":[],"mappings":"AAAA,cAAc,gCAAgC,CAAA"}
1
+ {"version":3,"file":"SectionFactory.d.ts","sourceRoot":"","sources":["../../../src/core/factories/SectionFactory.ts"],"names":[],"mappings":"AAAA,cAAc,mCAAmC,CAAA"}
@@ -1 +1 @@
1
- export * from './section-factory-with-jiti.js';
1
+ export * from './section-factory-with-esbuild.js';
@@ -21,6 +21,9 @@ export declare class SectionFactory {
21
21
  private static allSectionsPromise;
22
22
  private static allSectionsLoaded;
23
23
  private static watcherStarted;
24
+ private static configVersion;
25
+ private static sectionWatcher;
26
+ private static ensureConfigFresh;
24
27
  static bumpHotMarker(): void;
25
28
  /**
26
29
  * Get all sections
@@ -1 +1 @@
1
- {"version":3,"file":"section-factory-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-esbuild.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtF,OAAO,KAAK,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAA;AAC7G,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAiIrD,KAAK,gBAAgB,GAAG,qBAAqB,GAAG,mBAAmB,GAAG,qBAAqB,CAAA;AAY3F,qBAAa,cAAc;IACvB;;OAEG;IACH,MAAM,CAAC,QAAQ,CAAC,aAAa,WAAiD;IAE9E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAwC;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAc;IAE5C,OAAO,CAAC,MAAM,CAAC,uBAAuB,CAA+B;IACrE,OAAO,CAAC,MAAM,CAAC,qBAAqB,CAA+B;IACnE,OAAO,CAAC,MAAM,CAAC,UAAU,CAAI;IAE7B;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAA2C;IAC5E,OAAO,CAAC,MAAM,CAAC,iBAAiB,CAAQ;IACxC,OAAO,CAAC,MAAM,CAAC,cAAc,CAAQ;IAErC,MAAM,CAAC,aAAa,IAAI,IAAI;IAwB5B;;;;OAIG;WACU,WAAW,CAAC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC;IAI3F;;;;;OAKG;WACU,mBAAmB,CAAC,EAC7B,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC;QACR,MAAM,EAAE,mBAAmB,EAAE,CAAA;QAC7B,SAAS,EAAE,qBAAqB,EAAE,CAAA;QAClC,QAAQ,EAAE,qBAAqB,EAAE,CAAA;QACjC,KAAK,EAAE,MAAM,EAAE,CAAA;KAClB,CAAC;IA+BF;;;;;OAKG;WACU,UAAU,CAAC,EACpB,IAAI,EACJ,IAAI,GACP,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;KACvC,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;OAMG;WACU,kBAAkB,CAAC,EAC5B,IAAI,EACJ,IAAI,EACJ,KAAK,GACR,EAAE;QACC,IAAI,EAAE,MAAM,CAAA;QACZ,IAAI,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAA;QACpC,KAAK,EAAE;YACH,EAAE,EAAE,MAAM,CAAA;YACV,YAAY,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;SACjC,CAAA;KACJ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IAKpC;;;;;;;;;;OAUG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE;QAClB,KAAK,EAAE,MAAM,eAAe,GAAG,aAAa,GAAG,eAAe,CAAA;QAC9D,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAA;KACrB,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe;IAYrD;;;;;;;;;OASG;mBACkB,GAAG;IA6FxB;;;;OAIG;mBACkB,eAAe;IAkKpC,OAAO,CAAC,MAAM,CAAC,YAAY;IA+C3B,OAAO,CAAC,MAAM,CAAC,IAAI;CAatB"}
1
+ {"version":3,"file":"section-factory-with-esbuild.d.ts","sourceRoot":"","sources":["../../../src/core/factories/section-factory-with-esbuild.ts"],"names":[],"mappings":"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"}
@@ -9,9 +9,17 @@ import { createRequire } from 'module';
9
9
  import { pathToFileURL } from 'url';
10
10
  import { db } from '../../db/client.js';
11
11
  import { AdminPrivilegesTable } from '../../db/schema.js';
12
- import { getCMSConfig } from '../config/index.js';
12
+ import { getCMSConfig, getConfigImportVersion } from '../config/index.js';
13
13
  import crypto from 'crypto';
14
- const cmsConfig = await getCMSConfig();
14
+ let cachedCmsConfig = null;
15
+ let cachedCmsConfigVersion = -1;
16
+ const getCmsConfigCached = async (currentVersion = getConfigImportVersion()) => {
17
+ if (!cachedCmsConfig || cachedCmsConfigVersion !== currentVersion) {
18
+ cachedCmsConfig = await getCMSConfig();
19
+ cachedCmsConfigVersion = currentVersion;
20
+ }
21
+ return cachedCmsConfig;
22
+ };
15
23
  const hotMarkerFile = resolve(process.cwd(), 'components/form/helpers/_section-hot-reload.js');
16
24
  // Create a require function that works in ES modules
17
25
  const safeRequire = createRequire(import.meta.url);
@@ -70,12 +78,15 @@ if (!existsSync(cacheRoot))
70
78
  const hashKey = (s) => crypto.createHash('sha1').update(s).digest('hex');
71
79
  const ensureBundledSection = async (entryAbsPath) => {
72
80
  const esbuild = getEsbuild();
73
- // Make output stable per file + mtime (so edits re-bundle)
81
+ // Make output stable per file path and rebuild only when the source is newer
74
82
  const st = statSync(entryAbsPath);
75
- const key = hashKey(`${entryAbsPath}|${st.mtimeMs}`);
83
+ const key = hashKey(entryAbsPath);
76
84
  const outFile = join(cacheRoot, `${key}.mjs`);
77
- if (existsSync(outFile))
78
- return outFile;
85
+ if (existsSync(outFile)) {
86
+ const outStat = statSync(outFile);
87
+ if (outStat.mtimeMs >= st.mtimeMs)
88
+ return outFile;
89
+ }
79
90
  // Bundle so extensionless imports work (esbuild resolves them)
80
91
  await esbuild.build({
81
92
  entryPoints: [entryAbsPath],
@@ -117,7 +128,7 @@ const loadSectionModuleRuntime = async (absPath) => {
117
128
  * @returns void
118
129
  */
119
130
  const log = (...args) => {
120
- if (!cmsConfig.debug)
131
+ if (!cachedCmsConfig?.debug)
121
132
  return;
122
133
  console.log(chalk.black.bgGreen(`[${new Date().toISOString()}][next-cms-debug]`, ...args));
123
134
  };
@@ -140,6 +151,29 @@ export class SectionFactory {
140
151
  static allSectionsPromise = null;
141
152
  static allSectionsLoaded = false;
142
153
  static watcherStarted = false;
154
+ static configVersion = -1;
155
+ static sectionWatcher = null;
156
+ static async ensureConfigFresh() {
157
+ const currentVersion = getConfigImportVersion();
158
+ const cmsConfig = await getCmsConfigCached(currentVersion);
159
+ if (this.configVersion !== currentVersion) {
160
+ this.configVersion = currentVersion;
161
+ this.sectionProcessingErrors = {};
162
+ this.sectionFetchingErrors = {};
163
+ this.errorCount = 0;
164
+ this.allSectionsPromise = null;
165
+ this.allSectionsLoaded = false;
166
+ // Reset section import version to force re-bundling
167
+ sectionImportVersion = 0;
168
+ // Close and reset the watcher if it exists
169
+ if (this.sectionWatcher) {
170
+ await this.sectionWatcher.close();
171
+ this.sectionWatcher = null;
172
+ this.watcherStarted = false;
173
+ }
174
+ }
175
+ return cmsConfig;
176
+ }
143
177
  static bumpHotMarker() {
144
178
  if (!SectionFactory.isDev)
145
179
  return;
@@ -328,12 +362,13 @@ export class SectionFactory {
328
362
  * (until invalidated in dev by file changes).
329
363
  */
330
364
  static async loadAllSections() {
365
+ const cmsConfig = await this.ensureConfigFresh();
331
366
  if (this.allSectionsPromise)
332
367
  return this.allSectionsPromise;
333
368
  if (this.isDev) {
334
369
  // In dev, watch for changes and reload on demand
335
370
  // This will lazy load on first get() as well
336
- this.startWatcher();
371
+ this.startWatcher(cmsConfig);
337
372
  }
338
373
  this.allSectionsPromise = (async () => {
339
374
  if (!this.allSectionsLoaded) {
@@ -454,7 +489,7 @@ If you added an extension manually, remove it.`);
454
489
  return this.allSectionsPromise;
455
490
  }
456
491
  // ---------- DEV WATCHER & CACHE INVALIDATION ----------
457
- static startWatcher() {
492
+ static startWatcher(cmsConfig) {
458
493
  if (!this.isDev || this.watcherStarted)
459
494
  return;
460
495
  this.watcherStarted = true;
@@ -462,6 +497,7 @@ If you added an extension manually, remove it.`);
462
497
  cwd: cmsConfig.sections.path,
463
498
  ignoreInitial: true,
464
499
  });
500
+ this.sectionWatcher = watcher;
465
501
  log('Starting section watcher in dev mode...');
466
502
  /**
467
503
  * Invalidate section cache + bust runtime import cache.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextjs-cms",
3
- "version": "0.5.58",
3
+ "version": "0.5.60",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "type": "module",