@michaelthielemann/kestrel 4.0.0 → 4.0.1
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,7 +1,7 @@
|
|
|
1
1
|
import { existsSync } from 'node:fs'
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { addComponentsDir, addTemplate, addTypeTemplate, createResolver, defineNuxtModule } from '@nuxt/kit'
|
|
4
|
-
import { collectBlockSfcs, collectDefinitions, collectManifestFiles, renderPackageConcatRegistry, renderPackageMergedRegistry, renderRegistry } from './scan'
|
|
4
|
+
import { collectBlockSfcs, collectDefinitions, collectManifestFiles, renderPackageConcatRegistry, renderPackageMergedRegistry, renderRegistry, resolvePackageEntry } from './scan'
|
|
5
5
|
import { renderBlockRegistry } from './extract-block'
|
|
6
6
|
import { offerableLayouts, renderLayoutRegistry } from '../../app/utils/layouts'
|
|
7
7
|
import { PACKAGE_COLLECTIONS, PACKAGE_MANIFESTS, PACKAGE_SCHEMA_TABLES } from './package-registry'
|
|
@@ -38,9 +38,10 @@ export default defineNuxtModule({
|
|
|
38
38
|
nitro.virtual ||= {}
|
|
39
39
|
// `@michaelthielemann/kestrel-fields`'s built-in descriptors (text/richtext/number/…) seed `core`'s field-type registry
|
|
40
40
|
// as a side effect of importing the package itself — core cannot import fields, so this is the one
|
|
41
|
-
// place that import happens.
|
|
42
|
-
//
|
|
43
|
-
//
|
|
41
|
+
// place that import happens. Resolved to a real file path (`resolvePackageEntry`), not left as the
|
|
42
|
+
// bare specifier: a Nitro virtual module has no real file of its own for a bundler to resolve a bare
|
|
43
|
+
// import FROM, so it falls back to the project root — where, under a real consumer's pnpm install,
|
|
44
|
+
// this package isn't visible (only the engine directly depends on it). Prepended so it always runs, even with zero consumer
|
|
44
45
|
// field types (an empty `collectDefinitions` result would otherwise generate `export default []`,
|
|
45
46
|
// importing nothing). Consumer field types register as a side effect on import too, and the schema
|
|
46
47
|
// engine builds a table the moment a collection/block module loads — so the collections/blocks/
|
|
@@ -48,7 +49,7 @@ export default defineNuxtModule({
|
|
|
48
49
|
// now reach a package's `buildCollection()` call transitively via `kestrelDiscovery`, per ADR-0029 —
|
|
49
50
|
// an ESM barrel is an eager, whole-module-graph load — so all four need the same guard, not only the
|
|
50
51
|
// two that directly build collections themselves).
|
|
51
|
-
const importFieldTypesSeed = `import { fieldTypes as __kestrelSeed } from '@michaelthielemann/kestrel-fields'\n`
|
|
52
|
+
const importFieldTypesSeed = `import { fieldTypes as __kestrelSeed } from ${JSON.stringify(resolvePackageEntry('@michaelthielemann/kestrel-fields'))}\n`
|
|
52
53
|
+ `if (!__kestrelSeed || typeof __kestrelSeed !== 'object') throw new Error('[kestrel] built-in field types failed to seed')\n`
|
|
53
54
|
// A real runtime check on the imported binding, not a bare `import "path"` or a discarded `void x`
|
|
54
55
|
// — Nitro's dev build tree-shakes an import whose binding has no provable effect, silently dropping
|
|
@@ -68,7 +69,7 @@ export default defineNuxtModule({
|
|
|
68
69
|
|
|
69
70
|
nitro.virtual['#kestrel/collections'] = () =>
|
|
70
71
|
renderPackageMergedRegistry({
|
|
71
|
-
packages: PACKAGE_COLLECTIONS,
|
|
72
|
+
packages: PACKAGE_COLLECTIONS.map(resolvePackageEntry),
|
|
72
73
|
property: 'collections',
|
|
73
74
|
consumerFiles: collectDefinitions(roots, 'server/collections'),
|
|
74
75
|
nameOfExpr: '(x) => x.name',
|
|
@@ -87,7 +88,7 @@ export default defineNuxtModule({
|
|
|
87
88
|
// hardcoding upper-layer tables.
|
|
88
89
|
nitro.virtual['#kestrel/schema-tables'] = () =>
|
|
89
90
|
renderPackageMergedRegistry({
|
|
90
|
-
packages: PACKAGE_SCHEMA_TABLES,
|
|
91
|
+
packages: PACKAGE_SCHEMA_TABLES.map(resolvePackageEntry),
|
|
91
92
|
property: 'schemaTables',
|
|
92
93
|
consumerFiles: collectDefinitions(roots, 'server/schema-tables'),
|
|
93
94
|
nameOfExpr: '(x) => __kestrelTableName(x)',
|
|
@@ -101,7 +102,7 @@ export default defineNuxtModule({
|
|
|
101
102
|
// distinct module (see `collectManifestFiles`'s own TSDoc).
|
|
102
103
|
nitro.virtual['#kestrel/module-manifests'] = () =>
|
|
103
104
|
renderPackageConcatRegistry({
|
|
104
|
-
packages: PACKAGE_MANIFESTS,
|
|
105
|
+
packages: PACKAGE_MANIFESTS.map(resolvePackageEntry),
|
|
105
106
|
property: 'manifest',
|
|
106
107
|
consumerFiles: collectManifestFiles(roots),
|
|
107
108
|
preamble: importFieldTypesVirtual,
|
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
import { readdirSync } from 'node:fs'
|
|
2
2
|
import { basename, join } from 'node:path'
|
|
3
|
+
import { fileURLToPath } from 'node:url'
|
|
3
4
|
import { blockNameFromFile } from './extract-block'
|
|
4
5
|
|
|
5
6
|
type Lister = (dir: string) => string[]
|
|
6
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Resolves a bare `@michaelthielemann/kestrel-*` package specifier to its real entry FILE PATH, via Node's
|
|
10
|
+
* own ESM resolution from THIS module's own location — not the bare specifier itself, which a Nitro
|
|
11
|
+
* virtual module (no real file path of its own) cannot resolve reliably: Rollup falls back to resolving a
|
|
12
|
+
* virtual's imports from the project root, and under pnpm's isolated `node_modules` a package the
|
|
13
|
+
* CONSUMER never declared a direct dependency on (only the engine did, transitively) is invisible there —
|
|
14
|
+
* observed as `Cannot find package` at runtime, npm's flat hoisting having accidentally masked it in
|
|
15
|
+
* testing. This module's own file, once installed, sits inside the engine's package tree, so resolving
|
|
16
|
+
* from here walks the engine's OWN nested `node_modules`, where pnpm DID link the real dependency.
|
|
17
|
+
*/
|
|
18
|
+
export function resolvePackageEntry(spec: string): string {
|
|
19
|
+
return fileURLToPath(import.meta.resolve(spec))
|
|
20
|
+
}
|
|
21
|
+
|
|
7
22
|
const isDefinition = (name: string) =>
|
|
8
23
|
name.endsWith('.ts') && !name.endsWith('.test.ts') && !name.endsWith('.d.ts')
|
|
9
24
|
|
|
@@ -118,7 +133,7 @@ export function renderPackageMergedRegistry(opts: {
|
|
|
118
133
|
return [
|
|
119
134
|
opts.preamble ?? '',
|
|
120
135
|
opts.extraImports ?? '',
|
|
121
|
-
`import { mergeKestrelDiscovered } from '@michaelthielemann/kestrel-core'`,
|
|
136
|
+
`import { mergeKestrelDiscovered } from ${JSON.stringify(resolvePackageEntry('@michaelthielemann/kestrel-core'))}`,
|
|
122
137
|
...pkgImports,
|
|
123
138
|
...consumerImports,
|
|
124
139
|
`export default mergeKestrelDiscovered([${pkgSpread}], [${consumerArr}], ${opts.nameOfExpr})`,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michaelthielemann/kestrel",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.1",
|
|
4
4
|
"description": "A slim, collection-driven Nuxt 4 CMS meta-layer with a runtime schema engine. Add `extends: ['@michaelthielemann/kestrel']`, define collections, and the database migrates itself.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Michael Thielemann <283621694+MichaelThielemann@users.noreply.github.com>",
|
|
@@ -78,14 +78,14 @@
|
|
|
78
78
|
"zod": "^4.4.3",
|
|
79
79
|
"@michaelthielemann/kestrel-access": "0.1.0",
|
|
80
80
|
"@michaelthielemann/kestrel-auth": "0.1.0",
|
|
81
|
-
"@michaelthielemann/kestrel-core": "0.1.0",
|
|
82
81
|
"@michaelthielemann/kestrel-contracts": "0.1.0",
|
|
83
82
|
"@michaelthielemann/kestrel-collections": "0.1.0",
|
|
83
|
+
"@michaelthielemann/kestrel-core": "0.1.0",
|
|
84
84
|
"@michaelthielemann/kestrel-delivery-live": "0.1.0",
|
|
85
85
|
"@michaelthielemann/kestrel-delivery-static": "0.1.0",
|
|
86
|
-
"@michaelthielemann/kestrel-fields": "0.1.0",
|
|
87
86
|
"@michaelthielemann/kestrel-media": "0.1.0",
|
|
88
|
-
"@michaelthielemann/kestrel-publishing": "0.1.0"
|
|
87
|
+
"@michaelthielemann/kestrel-publishing": "0.1.0",
|
|
88
|
+
"@michaelthielemann/kestrel-fields": "0.1.0"
|
|
89
89
|
},
|
|
90
90
|
"//peers": "Framework singletons the layer sources import by bare specifier. Peers, not dependencies: a second copy breaks identity (two Vue instances; an h3 v1 `createError` handed to an h3 v2 error handler, which surfaces our 400/404/409 as bare 500s). All optional, because kestrel's own `nuxt` dependency already supplies them transitively — the entry pins identity where a copy exists rather than demanding one, and a required peer would ERESOLVE-fail npm installs on any Nuxt whose bundled range we did not anticipate. Each is also a devDependency so this repo resolves it without auto-install-peers writing a phantom root dependency into the lockfile.",
|
|
91
91
|
"peerDependencies": {
|
|
@@ -27,8 +27,11 @@ log(`work dir: ${work}`)
|
|
|
27
27
|
|
|
28
28
|
let server
|
|
29
29
|
try {
|
|
30
|
+
// `pnpm --filter "@michaelthielemann/kestrel-*" -r build` does NOT reliably respect the dependency
|
|
31
|
+
// graph (observed: kestrel-access started before kestrel-core/kestrel-auth finished) — `build:packages`
|
|
32
|
+
// builds in explicit topological order instead.
|
|
30
33
|
log('building @michaelthielemann/kestrel-* packages (dist/ must exist before pnpm pack)')
|
|
31
|
-
run('pnpm', ['
|
|
34
|
+
run('pnpm', ['build:packages'], { cwd: root })
|
|
32
35
|
|
|
33
36
|
log('packing the engine + every @michaelthielemann/kestrel-* package as npm publish would')
|
|
34
37
|
const tarball = {}
|