poveste 0.5.2 → 0.5.3
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/node/bin.js +1 -0
- package/dist/node/builtin-plugins/pinceau-tokens.d.ts.map +1 -1
- package/dist/node/builtin-plugins/pinceau-tokens.js +2 -1
- package/dist/node/builtin-plugins/tailwind-tokens.d.ts.map +1 -1
- package/dist/node/builtin-plugins/tailwind-tokens.js +2 -1
- package/dist/node/commands/dev.d.ts +1 -1
- package/dist/node/commands/dev.d.ts.map +1 -1
- package/dist/node/commands/dev.js +3 -1
- package/dist/node/commands/port.d.ts +10 -0
- package/dist/node/commands/port.d.ts.map +1 -0
- package/dist/node/commands/port.js +24 -0
- package/dist/node/commands/preview.d.ts +1 -1
- package/dist/node/commands/preview.d.ts.map +1 -1
- package/dist/node/commands/preview.js +3 -1
- package/dist/node/config.d.ts.map +1 -1
- package/dist/node/config.js +0 -1
- package/dist/node/preview.d.ts.map +1 -1
- package/dist/node/preview.js +6 -1
- package/dist/node/server.d.ts.map +1 -1
- package/dist/node/server.js +6 -0
- package/package.json +5 -5
- package/src/node/__tests__/port.spec.ts +33 -0
- package/src/node/bin.ts +1 -0
- package/src/node/builtin-plugins/pinceau-tokens.ts +3 -1
- package/src/node/builtin-plugins/tailwind-tokens.ts +3 -1
- package/src/node/commands/dev.ts +5 -2
- package/src/node/commands/port.ts +29 -0
- package/src/node/commands/preview.ts +5 -2
- package/src/node/config.ts +0 -1
- package/src/node/preview.ts +6 -1
- package/src/node/server.ts +7 -0
package/dist/node/bin.js
CHANGED
|
@@ -6,6 +6,7 @@ const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
|
6
6
|
const { version } = JSON.parse(fs.readFileSync(resolve(__dirname, '../../package.json'), 'utf8'));
|
|
7
7
|
process.env.NODE_ENV = 'development';
|
|
8
8
|
process.env.HISTOIRE = 'true';
|
|
9
|
+
process.env.POVESTE = 'true';
|
|
9
10
|
const program = sade('poveste');
|
|
10
11
|
program.version(version);
|
|
11
12
|
program.command('dev')
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pinceau-tokens.d.ts","sourceRoot":"","sources":["../../../src/node/builtin-plugins/pinceau-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AAI5D,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,aAAa,CAAC,QAAQ,GAAE,oBAAyB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"pinceau-tokens.d.ts","sourceRoot":"","sources":["../../../src/node/builtin-plugins/pinceau-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AAI5D,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;IACjC,cAAc,CAAC,EAAE,MAAM,CAAA;CACxB;AAED,wBAAgB,aAAa,CAAC,QAAQ,GAAE,oBAAyB,GAAG,MAAM,CA6DzE"}
|
|
@@ -41,7 +41,8 @@ export function pinceauTokens(_options = {}) {
|
|
|
41
41
|
});
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
-
onDev(api, onCleanup) {
|
|
44
|
+
async onDev(api, onCleanup) {
|
|
45
|
+
await generate(api);
|
|
45
46
|
const watcher = api.watcher.watch(themePath)
|
|
46
47
|
.on('change', () => generate(api))
|
|
47
48
|
.on('add', () => generate(api));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind-tokens.d.ts","sourceRoot":"","sources":["../../../src/node/builtin-plugins/tailwind-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AAI5D,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAqBD,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"tailwind-tokens.d.ts","sourceRoot":"","sources":["../../../src/node/builtin-plugins/tailwind-tokens.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,iBAAiB,CAAA;AAI5D,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAqBD,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B,GAAG,MAAM,CAkE1E"}
|
|
@@ -61,8 +61,9 @@ export function tailwindTokens(options = {}) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
},
|
|
64
|
-
onDev(api, onCleanup) {
|
|
64
|
+
async onDev(api, onCleanup) {
|
|
65
65
|
if (tailwindCssFile) {
|
|
66
|
+
await generate(api);
|
|
66
67
|
const watcher = api.watcher.watch(tailwindCssFile)
|
|
67
68
|
.on('change', () => generate(api))
|
|
68
69
|
.on('add', () => generate(api));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/node/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/node/commands/dev.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,UAAU,CAAC,OAAO,EAAE,UAAU,iBAsDnD"}
|
|
@@ -3,7 +3,9 @@ import pc from 'picocolors';
|
|
|
3
3
|
import { resolveConfigFile } from '../config.js';
|
|
4
4
|
import { createContext } from '../context.js';
|
|
5
5
|
import { createServer } from '../server.js';
|
|
6
|
+
import { resolvePort } from './port.js';
|
|
6
7
|
export async function devCommand(options) {
|
|
8
|
+
const port = resolvePort(options.port, 'dev');
|
|
7
9
|
let stop;
|
|
8
10
|
async function start() {
|
|
9
11
|
const ctx = await createContext({
|
|
@@ -11,7 +13,7 @@ export async function devCommand(options) {
|
|
|
11
13
|
mode: 'dev',
|
|
12
14
|
});
|
|
13
15
|
const { server, viteConfigFile, close } = await createServer(ctx, {
|
|
14
|
-
port
|
|
16
|
+
port,
|
|
15
17
|
open: options.open,
|
|
16
18
|
host: options.host,
|
|
17
19
|
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a `--port` value off the parsed CLI options.
|
|
3
|
+
*
|
|
4
|
+
* sade declares the flag as taking a value but does not enforce one, so
|
|
5
|
+
* `poveste preview --port` arrives as the boolean `true` and reaches node's
|
|
6
|
+
* listen validation, which rejects it with `ERR_INVALID_ARG_VALUE` and names
|
|
7
|
+
* neither the flag nor the mistake. A non-numeric value fails the same way.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolvePort(value: unknown, command: string): number | undefined;
|
|
10
|
+
//# sourceMappingURL=port.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"port.d.ts","sourceRoot":"","sources":["../../../src/node/commands/port.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAoB/E"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a `--port` value off the parsed CLI options.
|
|
3
|
+
*
|
|
4
|
+
* sade declares the flag as taking a value but does not enforce one, so
|
|
5
|
+
* `poveste preview --port` arrives as the boolean `true` and reaches node's
|
|
6
|
+
* listen validation, which rejects it with `ERR_INVALID_ARG_VALUE` and names
|
|
7
|
+
* neither the flag nor the mistake. A non-numeric value fails the same way.
|
|
8
|
+
*/
|
|
9
|
+
export function resolvePort(value, command) {
|
|
10
|
+
if (value === undefined || value === null) {
|
|
11
|
+
return undefined;
|
|
12
|
+
}
|
|
13
|
+
// Checked by type, not by coercion: a valueless flag arrives as `true`, and
|
|
14
|
+
// `Number(true)` is 1, a valid port that would bind to a privileged one.
|
|
15
|
+
const port = typeof value === 'number'
|
|
16
|
+
? value
|
|
17
|
+
: typeof value === 'string' && value.trim() !== ''
|
|
18
|
+
? Number(value)
|
|
19
|
+
: Number.NaN;
|
|
20
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
21
|
+
throw new TypeError(`--port needs a number between 0 and 65535, got ${JSON.stringify(value)}. Try \`poveste ${command} --port 6006\`.`);
|
|
22
|
+
}
|
|
23
|
+
return port;
|
|
24
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/node/commands/preview.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../../src/node/commands/preview.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;IACtB,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,cAAc,iBAmB3D"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createContext } from '../context.js';
|
|
2
2
|
import { startPreview } from '../preview.js';
|
|
3
|
+
import { resolvePort } from './port.js';
|
|
3
4
|
export async function previewCommand(options) {
|
|
5
|
+
const port = resolvePort(options.port, 'preview');
|
|
4
6
|
const ctx = await createContext({
|
|
5
7
|
mode: 'build',
|
|
6
8
|
});
|
|
@@ -10,7 +12,7 @@ export async function previewCommand(options) {
|
|
|
10
12
|
}
|
|
11
13
|
}
|
|
12
14
|
const { printUrls } = await startPreview({
|
|
13
|
-
port
|
|
15
|
+
port,
|
|
14
16
|
host: options.host,
|
|
15
17
|
open: options.open,
|
|
16
18
|
}, ctx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/node/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EAEd,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAkB3C,wBAAgB,gBAAgB,IAAI,aAAa,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/node/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EAEV,aAAa,EAEd,MAAM,iBAAiB,CAAA;AACxB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAkB3C,wBAAgB,gBAAgB,IAAI,aAAa,CA2HhD;AAED,eAAO,MAAM,eAAe,UAU3B,CAAA;AAED,wBAAgB,iBAAiB,CAAC,GAAG,GAAE,MAAsB,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CAQ1F;AAED,wBAAsB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAexF;AAED,eAAO,MAAM,gBAAgB,uBAK3B,CAAA;AAEF,eAAO,MAAM,WAAW,uBA8DtB,CAAA;AAEF,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAgB7H;AA2BD,wBAAsB,aAAa,CAAC,GAAG,EAAE,OAAO,iBAoE/C;AAED,wBAAgB,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,0BAE1D;AAED,OAAO,QAAQ,MAAM,CAAC;IACpB,UAAU,UAAU;QAClB;;WAEG;QACH,OAAO,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;QAChC;;WAEG;QACH,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAA;KAClC;CACF"}
|
package/dist/node/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/node/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"preview.d.ts","sourceRoot":"","sources":["../../src/node/preview.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAG3C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;IACvB,IAAI,CAAC,EAAE,OAAO,CAAA;CACf;AAED,UAAU,aAAa;IACrB,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,IAAI,CAAA;IACrB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,mBAAmB,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,aAAa,CAAC,CA6BrG"}
|
package/dist/node/preview.js
CHANGED
|
@@ -12,7 +12,12 @@ export async function startPreview(options, ctx) {
|
|
|
12
12
|
port,
|
|
13
13
|
host: options.host,
|
|
14
14
|
open: options.open,
|
|
15
|
-
|
|
15
|
+
// A port asked for by name has to be that port or nothing. Moving to the
|
|
16
|
+
// next free one serves the book where nobody is looking, and lands it on
|
|
17
|
+
// whatever example owns that number, whose suite then adopts it (#175).
|
|
18
|
+
// Without an explicit port there is no such expectation, and `build`'s
|
|
19
|
+
// internal preview reads the port back off the server.
|
|
20
|
+
strictPort: options.port != null,
|
|
16
21
|
},
|
|
17
22
|
});
|
|
18
23
|
const baseUrl = server.resolvedUrls?.local[0] ?? `http://localhost:${port}${ctx.resolvedViteConfig.base}`;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/node/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAa3C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACxB;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,mBAAwB;;;;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/node/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAA;AAa3C,MAAM,WAAW,mBAAmB;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAA;CACxB;AAED,wBAAsB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,GAAE,mBAAwB;;;;GA6NjF"}
|
package/dist/node/server.js
CHANGED
|
@@ -19,6 +19,12 @@ export async function createServer(ctx, options = {}) {
|
|
|
19
19
|
if (options.host) {
|
|
20
20
|
viteConfig.server.host = options.host;
|
|
21
21
|
}
|
|
22
|
+
// Same rule as `preview`: a port asked for by name is that port or
|
|
23
|
+
// nothing. Floating to the next free one hands back a server nobody asked
|
|
24
|
+
// for, and whoever opens the port they typed reads a different book.
|
|
25
|
+
if (options.port != null) {
|
|
26
|
+
viteConfig.server.strictPort = true;
|
|
27
|
+
}
|
|
22
28
|
}
|
|
23
29
|
const server = await createViteServer(mergeViteConfig(viteConfig, {
|
|
24
30
|
optimizeDeps: { include: viteConfig.optimizeDeps?.include ?? [], noDiscovery: collecting },
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "poveste",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.5.
|
|
4
|
+
"version": "0.5.3",
|
|
5
5
|
"description": "A fast story book powered by Vite",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Sorin Gitlan"
|
|
@@ -68,10 +68,10 @@
|
|
|
68
68
|
"sirv": "^3.0.0",
|
|
69
69
|
"unhead": "^3.1.0",
|
|
70
70
|
"vite-node": "^6.0.0",
|
|
71
|
-
"@poveste/app": "^0.5.
|
|
72
|
-
"@poveste/
|
|
73
|
-
"@poveste/
|
|
74
|
-
"@poveste/vendors": "^0.5.
|
|
71
|
+
"@poveste/app": "^0.5.3",
|
|
72
|
+
"@poveste/shared": "^0.5.3",
|
|
73
|
+
"@poveste/controls": "^0.5.3",
|
|
74
|
+
"@poveste/vendors": "^0.5.3"
|
|
75
75
|
},
|
|
76
76
|
"devDependencies": {
|
|
77
77
|
"@types/fs-extra": "^11.0.4",
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { resolvePort } from '../commands/port.js'
|
|
3
|
+
|
|
4
|
+
describe('resolvePort', () => {
|
|
5
|
+
it('returns undefined when the flag was not passed', () => {
|
|
6
|
+
expect(resolvePort(undefined, 'preview')).toBeUndefined()
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('parses the number sade hands over as a string', () => {
|
|
10
|
+
expect(resolvePort('4569', 'preview')).toBe(4569)
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
it('passes a number through', () => {
|
|
14
|
+
expect(resolvePort(6006, 'dev')).toBe(6006)
|
|
15
|
+
})
|
|
16
|
+
|
|
17
|
+
// sade declares `--port <port>` but does not enforce the value, so a bare
|
|
18
|
+
// `--port` arrives as `true`. `Number(true)` is 1 — a valid port that binds
|
|
19
|
+
// to a privileged one — so this has to be rejected by type.
|
|
20
|
+
it.each([
|
|
21
|
+
['a valueless flag', true],
|
|
22
|
+
['a non-numeric value', 'abc'],
|
|
23
|
+
['an empty value', ''],
|
|
24
|
+
['a port above the range', '99999'],
|
|
25
|
+
['a fractional port', '80.5'],
|
|
26
|
+
])('rejects %s', (_name, value) => {
|
|
27
|
+
expect(() => resolvePort(value, 'preview')).toThrow(/--port needs a number/)
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
it('names the command in the message, so the hint is runnable', () => {
|
|
31
|
+
expect(() => resolvePort(true, 'dev')).toThrow(/poveste dev --port 6006/)
|
|
32
|
+
})
|
|
33
|
+
})
|
package/src/node/bin.ts
CHANGED
|
@@ -52,7 +52,9 @@ export function pinceauTokens(_options: PinceauTokensOptions = {}): Plugin {
|
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
54
|
|
|
55
|
-
onDev(api, onCleanup) {
|
|
55
|
+
async onDev(api, onCleanup) {
|
|
56
|
+
await generate(api)
|
|
57
|
+
|
|
56
58
|
const watcher = api.watcher.watch(themePath)
|
|
57
59
|
.on('change', () => generate(api))
|
|
58
60
|
.on('add', () => generate(api))
|
|
@@ -77,8 +77,10 @@ export function tailwindTokens(options: TailwindTokensOptions = {}): Plugin {
|
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
79
|
|
|
80
|
-
onDev(api, onCleanup) {
|
|
80
|
+
async onDev(api, onCleanup) {
|
|
81
81
|
if (tailwindCssFile) {
|
|
82
|
+
await generate(api)
|
|
83
|
+
|
|
82
84
|
const watcher = api.watcher.watch(tailwindCssFile)
|
|
83
85
|
.on('change', () => generate(api))
|
|
84
86
|
.on('add', () => generate(api))
|
package/src/node/commands/dev.ts
CHANGED
|
@@ -4,15 +4,18 @@ import pc from 'picocolors'
|
|
|
4
4
|
import { resolveConfigFile } from '../config.js'
|
|
5
5
|
import { createContext } from '../context.js'
|
|
6
6
|
import { createServer } from '../server.js'
|
|
7
|
+
import { resolvePort } from './port.js'
|
|
7
8
|
|
|
8
9
|
export interface DevOptions {
|
|
9
|
-
port
|
|
10
|
+
port?: number | string
|
|
10
11
|
open?: boolean
|
|
11
12
|
host?: string | boolean
|
|
12
13
|
config?: string
|
|
13
14
|
}
|
|
14
15
|
|
|
15
16
|
export async function devCommand(options: DevOptions) {
|
|
17
|
+
const port = resolvePort(options.port, 'dev')
|
|
18
|
+
|
|
16
19
|
let stop: () => Promise<void>
|
|
17
20
|
|
|
18
21
|
async function start() {
|
|
@@ -21,7 +24,7 @@ export async function devCommand(options: DevOptions) {
|
|
|
21
24
|
mode: 'dev',
|
|
22
25
|
})
|
|
23
26
|
const { server, viteConfigFile, close } = await createServer(ctx, {
|
|
24
|
-
port
|
|
27
|
+
port,
|
|
25
28
|
open: options.open,
|
|
26
29
|
host: options.host,
|
|
27
30
|
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reads a `--port` value off the parsed CLI options.
|
|
3
|
+
*
|
|
4
|
+
* sade declares the flag as taking a value but does not enforce one, so
|
|
5
|
+
* `poveste preview --port` arrives as the boolean `true` and reaches node's
|
|
6
|
+
* listen validation, which rejects it with `ERR_INVALID_ARG_VALUE` and names
|
|
7
|
+
* neither the flag nor the mistake. A non-numeric value fails the same way.
|
|
8
|
+
*/
|
|
9
|
+
export function resolvePort(value: unknown, command: string): number | undefined {
|
|
10
|
+
if (value === undefined || value === null) {
|
|
11
|
+
return undefined
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Checked by type, not by coercion: a valueless flag arrives as `true`, and
|
|
15
|
+
// `Number(true)` is 1, a valid port that would bind to a privileged one.
|
|
16
|
+
const port = typeof value === 'number'
|
|
17
|
+
? value
|
|
18
|
+
: typeof value === 'string' && value.trim() !== ''
|
|
19
|
+
? Number(value)
|
|
20
|
+
: Number.NaN
|
|
21
|
+
|
|
22
|
+
if (!Number.isInteger(port) || port < 0 || port > 65535) {
|
|
23
|
+
throw new TypeError(
|
|
24
|
+
`--port needs a number between 0 and 65535, got ${JSON.stringify(value)}. Try \`poveste ${command} --port 6006\`.`,
|
|
25
|
+
)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return port
|
|
29
|
+
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { createContext } from '../context.js'
|
|
2
2
|
import { startPreview } from '../preview.js'
|
|
3
|
+
import { resolvePort } from './port.js'
|
|
3
4
|
|
|
4
5
|
export interface PreviewOptions {
|
|
5
|
-
port?: number
|
|
6
|
+
port?: number | string
|
|
6
7
|
host?: string | boolean
|
|
7
8
|
open?: boolean
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export async function previewCommand(options: PreviewOptions) {
|
|
12
|
+
const port = resolvePort(options.port, 'preview')
|
|
13
|
+
|
|
11
14
|
const ctx = await createContext({
|
|
12
15
|
mode: 'build',
|
|
13
16
|
})
|
|
@@ -19,7 +22,7 @@ export async function previewCommand(options: PreviewOptions) {
|
|
|
19
22
|
}
|
|
20
23
|
|
|
21
24
|
const { printUrls } = await startPreview({
|
|
22
|
-
port
|
|
25
|
+
port,
|
|
23
26
|
host: options.host,
|
|
24
27
|
open: options.open,
|
|
25
28
|
}, ctx)
|
package/src/node/config.ts
CHANGED
package/src/node/preview.ts
CHANGED
|
@@ -26,7 +26,12 @@ export async function startPreview(options: StartPreviewOptions, ctx: Context):
|
|
|
26
26
|
port,
|
|
27
27
|
host: options.host,
|
|
28
28
|
open: options.open,
|
|
29
|
-
|
|
29
|
+
// A port asked for by name has to be that port or nothing. Moving to the
|
|
30
|
+
// next free one serves the book where nobody is looking, and lands it on
|
|
31
|
+
// whatever example owns that number, whose suite then adopts it (#175).
|
|
32
|
+
// Without an explicit port there is no such expectation, and `build`'s
|
|
33
|
+
// internal preview reads the port back off the server.
|
|
34
|
+
strictPort: options.port != null,
|
|
30
35
|
},
|
|
31
36
|
})
|
|
32
37
|
|
package/src/node/server.ts
CHANGED
|
@@ -30,6 +30,13 @@ export async function createServer(ctx: Context, options: CreateServerOptions =
|
|
|
30
30
|
if (options.host) {
|
|
31
31
|
viteConfig.server.host = options.host
|
|
32
32
|
}
|
|
33
|
+
|
|
34
|
+
// Same rule as `preview`: a port asked for by name is that port or
|
|
35
|
+
// nothing. Floating to the next free one hands back a server nobody asked
|
|
36
|
+
// for, and whoever opens the port they typed reads a different book.
|
|
37
|
+
if (options.port != null) {
|
|
38
|
+
viteConfig.server.strictPort = true
|
|
39
|
+
}
|
|
33
40
|
}
|
|
34
41
|
|
|
35
42
|
const server = await createViteServer(
|