poveste 0.17.0 → 0.17.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.
package/bin.mjs CHANGED
@@ -2,6 +2,7 @@
2
2
  'use strict'
3
3
 
4
4
  import process from 'node:process'
5
+ import { supportedFrameworks } from './framework-floor.mjs'
5
6
  import { supportedNode } from './node-floor.mjs'
6
7
 
7
8
  // Before the CLI is imported, not inside it: on a Node below the floor the import
@@ -12,7 +13,11 @@ import { supportedNode } from './node-floor.mjs'
12
13
  // Imported dynamically for the same reason. A static import is parsed with this
13
14
  // module, before a line of it runs, so syntax `dist/` may carry would win the race
14
15
  // against the message explaining it.
15
- if (supportedNode()) {
16
+ // The framework floor goes here for the same reason: on a framework below a
17
+ // plugin's peer, importing the CLI fails first and names neither (#1062). Not for
18
+ // `--help` or `--version`, which load no command and so cannot reach that failure.
19
+ const informational = process.argv.slice(2).some(arg => ['--help', '-h', '--version', '-v'].includes(arg))
20
+ if (supportedNode() && (informational || supportedFrameworks())) {
16
21
  import('./dist/node/bin.js').catch((error) => {
17
22
  // `exitCode`, not `exit`: the error is the last thing written, and forcing the
18
23
  // process out on the same tick truncates it on a pipe.
@@ -1,3 +1,3 @@
1
1
  export { default as MountStory } from './MountStory';
2
2
  export { default as RenderStory } from './RenderStory';
3
- export declare function generateSourceCode(): void;
3
+ export declare function generateSourceCode(): undefined;
@@ -0,0 +1,6 @@
1
+ import type { ClientSupportPlugin } from '@poveste/shared';
2
+ import type { Component } from '@poveste/vendors/vue';
3
+ import type * as client from './client';
4
+ type Satisfies<T extends ClientSupportPlugin<Component>> = T;
5
+ export type ClientContract = Satisfies<typeof client>;
6
+ export {};
package/dist/node/vite.js CHANGED
@@ -146,6 +146,7 @@ export async function getViteConfigWithPlugins(isServer, ctx) {
146
146
  plugins.push({
147
147
  name: 'poveste-vite-plugin',
148
148
  config(_, { command }) {
149
+ const collapsedVue = isServer || process.env['POVESTE_DEV'] ? {} : collapseVendoredVue({ root: ctx.root });
149
150
  return {
150
151
  resolve: {
151
152
  dedupe: [
@@ -160,7 +161,7 @@ export async function getViteConfigWithPlugins(isServer, ctx) {
160
161
  // `@poveste/vendors/vue`, so sending `poveste-vue` back to `vue` would
161
162
  // point the vendored entry at itself — the empty re-export its own
162
163
  // comment warns about.
163
- ...(isServer || process.env['POVESTE_DEV'] ? {} : collapseVendoredVue({ root: ctx.root })),
164
+ ...collapsedVue,
164
165
  },
165
166
  ...(isServer
166
167
  ? {
@@ -177,9 +178,17 @@ export async function getViteConfigWithPlugins(isServer, ctx) {
177
178
  // their deps cost a full reload when they turn up later (#282).
178
179
  ...optimizeEntries(ctx.config, ctx.root, isServer),
179
180
  ],
180
- include: optimizeDeps([
181
- 'shiki',
182
- ]),
181
+ include: [
182
+ ...optimizeDeps([
183
+ 'shiki',
184
+ ]),
185
+ // With the alias above, `poveste-vue` is pre-bundled from the project's
186
+ // Vue, but bare `vue` is pre-bundled only if a project file imports it.
187
+ // A Svelte, Solid or React book has none, so `poveste-vue-router`'s
188
+ // bare `vue` was served raw beside the pre-bundled copy of the same
189
+ // file: two module instances, and `RouterView` rendered nothing (#1134).
190
+ ...(Object.keys(collapsedVue).length > 0 ? ['vue'] : []),
191
+ ],
183
192
  exclude: [
184
193
  'poveste',
185
194
  '@poveste/vendors',
@@ -0,0 +1,88 @@
1
+ // The framework check the CLI makes before it loads anything, beside the Node one.
2
+ //
3
+ // A framework plugin declares its framework as a peer, and the package manager
4
+ // enforces that well — until a reader takes `--legacy-peer-deps`, which npm's own
5
+ // ERESOLVE output suggests. On Nuxt 3 what they meet next is `Cannot find package
6
+ // 'vite'`: Nuxt 4 hoists the `vite@^8` Poveste imports and Nuxt 3 does not. That
7
+ // failure comes from importing the CLI's commands, before the config — and so the
8
+ // plugin — is loaded at all, which is why the plugin cannot check its own peer in
9
+ // time and this file does (#1062).
10
+ //
11
+ // Nuxt only, until a second instance is reported. One measured case does not
12
+ // justify holding six plugins' peers here; another is one line in `PEERS`.
13
+ //
14
+ // Plain ES2015 beside `node-floor.mjs`, for the reason that file gives.
15
+
16
+ import { readFileSync, writeSync } from 'node:fs'
17
+ import { dirname, join } from 'node:path'
18
+ import process from 'node:process'
19
+ import { floorOf, isBelow } from './node-floor.mjs'
20
+
21
+ /** Each plugin whose framework is checked, and the peer that names it. */
22
+ export const PEERS = {
23
+ '@poveste/plugin-nuxt': 'nuxt',
24
+ }
25
+
26
+ /**
27
+ * The floor of a `^x.y.z` or `>=x.y.z` range, or `null` for any other shape.
28
+ *
29
+ * Only the floor: a version above a caret's major is the package manager's to
30
+ * refuse, and saying nothing about a shape this cannot read keeps our own
31
+ * manifest drift from becoming a reader's failed command.
32
+ */
33
+ export function rangeFloor(range) {
34
+ return floorOf(String(range ?? '').trim().replace(/^\^/, '>='))
35
+ }
36
+
37
+ /**
38
+ * The manifest of `name` as Node would find it from `dir`, or `null`.
39
+ *
40
+ * Only a missing file sends the walk upward, as it does Node's. A manifest that
41
+ * is there and unreadable ends it: going on would read an ancestor's copy, which
42
+ * in a monorepo can be another package's framework at another version.
43
+ */
44
+ export function installedManifest(name, dir) {
45
+ for (let current = dir; ; current = dirname(current)) {
46
+ try {
47
+ return JSON.parse(readFileSync(join(current, 'node_modules', name, 'package.json'), 'utf8'))
48
+ }
49
+ catch (error) {
50
+ if (error?.code !== 'ENOENT' || dirname(current) === current) {
51
+ return null
52
+ }
53
+ }
54
+ }
55
+ }
56
+
57
+ /** The Node message's shape, so the two read as one family. */
58
+ export function unsupportedFrameworkMessage(framework, version, plugin, range) {
59
+ return `You are using ${framework} ${version}. ${plugin} requires ${framework} ${range}. Please upgrade ${framework}.`
60
+ }
61
+
62
+ /** A sentence per checked plugin whose installed framework is below its peer floor. */
63
+ export function frameworkProblems(dir) {
64
+ const problems = []
65
+
66
+ for (const [plugin, framework] of Object.entries(PEERS)) {
67
+ const range = installedManifest(plugin, dir)?.peerDependencies?.[framework]
68
+ const floor = rangeFloor(range)
69
+ const version = installedManifest(framework, dir)?.version
70
+ if (floor && version && isBelow(version, floor)) {
71
+ problems.push(unsupportedFrameworkMessage(framework, version, plugin, range))
72
+ }
73
+ }
74
+
75
+ return problems
76
+ }
77
+
78
+ /** Whether the project's frameworks may run the CLI, saying so on stderr when not. */
79
+ export function supportedFrameworks(dir = process.cwd()) {
80
+ const problems = frameworkProblems(dir)
81
+ if (problems.length === 0) {
82
+ return true
83
+ }
84
+
85
+ writeSync(2, `${problems.join('\n')}\n`)
86
+ process.exitCode = 1
87
+ return false
88
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "poveste",
3
3
  "type": "module",
4
- "version": "0.17.0",
4
+ "version": "0.17.2",
5
5
  "description": "Interactive component playgrounds for Vue, Nuxt, Svelte, SvelteKit and Quasar — a drop-in fork of histoire, with Quasar support histoire does not ship.",
6
6
  "author": {
7
7
  "name": "Sorin Gitlan",
@@ -61,6 +61,7 @@
61
61
  "client.d.ts",
62
62
  "client.js",
63
63
  "dist",
64
+ "framework-floor.mjs",
64
65
  "index.d.ts",
65
66
  "node-floor.mjs",
66
67
  "plugin.d.ts",
@@ -74,10 +75,10 @@
74
75
  },
75
76
  "dependencies": {
76
77
  "@11ty/gray-matter": "^3.0.0",
77
- "@poveste/app": "^0.17.0",
78
- "@poveste/controls": "^0.17.0",
79
- "@poveste/shared": "^0.17.0",
80
- "@poveste/vendors": "^0.17.0",
78
+ "@poveste/app": "^0.17.2",
79
+ "@poveste/controls": "^0.17.2",
80
+ "@poveste/shared": "^0.17.2",
81
+ "@poveste/vendors": "^0.17.2",
81
82
  "change-case": "^5.4.4",
82
83
  "chokidar": "^5.0.0",
83
84
  "defu": "^6.1.4",