poveste 0.1.3 → 0.2.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/node/bin.js +3 -1
- package/dist/node/build.d.ts.map +1 -1
- package/dist/node/build.js +23 -5
- package/dist/node/builtin-plugins/pinceau-tokens.js +35 -35
- package/dist/node/builtin-plugins/tailwind-tokens.js +38 -38
- package/dist/node/builtin-plugins/vanilla-support/RenderStory.d.ts.map +1 -1
- package/dist/node/builtin-plugins/vanilla-support/RenderStory.js +7 -4
- package/dist/node/builtin-plugins/vanilla-support/types.d.ts +6 -5
- package/dist/node/builtin-plugins/vanilla-support/types.d.ts.map +1 -1
- package/dist/node/commands/preview.d.ts +2 -0
- package/dist/node/commands/preview.d.ts.map +1 -1
- package/dist/node/commands/preview.js +6 -3
- package/dist/node/config.d.ts.map +1 -1
- package/dist/node/config.js +1 -0
- package/dist/node/context.js +2 -2
- package/dist/node/dom/env.d.ts.map +1 -1
- package/dist/node/dom/env.js +26 -1
- package/dist/node/markdown.js +1 -1
- package/dist/node/preview.d.ts +7 -1
- package/dist/node/preview.d.ts.map +1 -1
- package/dist/node/preview.js +22 -39
- package/dist/node/style-isolation/entry-css-merger.d.ts +9 -0
- package/dist/node/style-isolation/entry-css-merger.d.ts.map +1 -0
- package/dist/node/style-isolation/entry-css-merger.js +128 -0
- package/dist/node/style-isolation/global-styles.d.ts +8 -0
- package/dist/node/style-isolation/global-styles.d.ts.map +1 -0
- package/dist/node/style-isolation/global-styles.js +31 -0
- package/dist/node/style-isolation/index.d.ts +6 -0
- package/dist/node/style-isolation/index.d.ts.map +1 -0
- package/dist/node/style-isolation/index.js +5 -0
- package/dist/node/style-isolation/scope-chrome.d.ts +6 -0
- package/dist/node/style-isolation/scope-chrome.d.ts.map +1 -0
- package/dist/node/style-isolation/scope-chrome.js +37 -0
- package/dist/node/style-isolation/selectors.d.ts +7 -0
- package/dist/node/style-isolation/selectors.d.ts.map +1 -0
- package/dist/node/style-isolation/selectors.js +15 -0
- package/dist/node/style-isolation/transforms.d.ts +11 -0
- package/dist/node/style-isolation/transforms.d.ts.map +1 -0
- package/dist/node/style-isolation/transforms.js +75 -0
- package/dist/node/style-isolation/vite-plugin.d.ts +15 -0
- package/dist/node/style-isolation/vite-plugin.d.ts.map +1 -0
- package/dist/node/style-isolation/vite-plugin.js +62 -0
- package/dist/node/util/head.d.ts +3 -0
- package/dist/node/util/head.d.ts.map +1 -0
- package/dist/node/util/head.js +10 -0
- package/dist/node/virtual/markdown.js +1 -1
- package/dist/node/virtual/noop.d.ts +2 -1
- package/dist/node/virtual/noop.d.ts.map +1 -1
- package/dist/node/virtual/noop.js +7 -1
- package/dist/node/virtual/resolved-generated-global-setup.js +3 -3
- package/dist/node/virtual/resolved-markdown-files.js +2 -2
- package/dist/node/virtual/util.d.ts +15 -0
- package/dist/node/virtual/util.d.ts.map +1 -1
- package/dist/node/virtual/util.js +18 -0
- package/dist/node/virtual/vite-plugin.js +1 -1
- package/dist/node/vite.d.ts +1 -1
- package/dist/node/vite.d.ts.map +1 -1
- package/dist/node/vite.js +51 -9
- package/package.json +7 -5
- package/src/node/__tests__/dom-env.spec.ts +38 -0
- package/src/node/__tests__/head.spec.ts +32 -0
- package/src/node/__tests__/virtual-setup.spec.ts +51 -0
- package/src/node/bin.ts +3 -1
- package/src/node/build.ts +31 -5
- package/src/node/builtin-plugins/pinceau-tokens.ts +35 -35
- package/src/node/builtin-plugins/tailwind-tokens.ts +38 -38
- package/src/node/builtin-plugins/vanilla-support/RenderStory.ts +8 -5
- package/src/node/builtin-plugins/vanilla-support/types.ts +3 -1
- package/src/node/commands/preview.ts +8 -3
- package/src/node/config.ts +1 -0
- package/src/node/context.ts +2 -2
- package/src/node/dom/env.ts +26 -1
- package/src/node/markdown.ts +1 -1
- package/src/node/preview.ts +30 -47
- package/src/node/style-isolation/__tests__/entry-css-merger.spec.ts +126 -0
- package/src/node/style-isolation/__tests__/transforms.spec.ts +92 -0
- package/src/node/style-isolation/__tests__/vite-plugin.spec.ts +39 -0
- package/src/node/style-isolation/entry-css-merger.ts +133 -0
- package/src/node/style-isolation/global-styles.ts +37 -0
- package/src/node/style-isolation/index.ts +5 -0
- package/src/node/style-isolation/scope-chrome.ts +42 -0
- package/src/node/style-isolation/selectors.ts +16 -0
- package/src/node/style-isolation/transforms.ts +90 -0
- package/src/node/style-isolation/vite-plugin.ts +75 -0
- package/src/node/util/head.ts +12 -0
- package/src/node/virtual/markdown.ts +1 -1
- package/src/node/virtual/noop.ts +9 -1
- package/src/node/virtual/resolved-generated-global-setup.ts +3 -3
- package/src/node/virtual/resolved-markdown-files.ts +2 -2
- package/src/node/virtual/util.ts +22 -0
- package/src/node/virtual/vite-plugin.ts +1 -1
- package/src/node/vite.ts +57 -9
|
@@ -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,CA4HhD;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;;;;;;;;qIAK3B,CAAA;AAEF,eAAO,MAAM,WAAW;;;;;;;;qIA8DtB,CAAA;AAEF,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAsB,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAa7H;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
package/dist/node/context.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { resolveConfig as resolveViteConfig } from 'vite';
|
|
2
2
|
import { processConfig, resolveConfig } from './config.js';
|
|
3
|
-
import {
|
|
3
|
+
import { mergePovesteViteConfig } from './vite.js';
|
|
4
4
|
export async function createContext(options) {
|
|
5
5
|
const config = await resolveConfig(process.cwd(), options.mode, options.configFile);
|
|
6
6
|
const command = options.mode === 'dev' ? 'serve' : 'build';
|
|
@@ -16,7 +16,7 @@ export async function createContext(options) {
|
|
|
16
16
|
markdownFiles: [],
|
|
17
17
|
registeredCommands: [],
|
|
18
18
|
};
|
|
19
|
-
ctx.resolvedViteConfig = await
|
|
19
|
+
ctx.resolvedViteConfig = await mergePovesteViteConfig(viteConfig, ctx);
|
|
20
20
|
await processConfig(ctx);
|
|
21
21
|
// List commands
|
|
22
22
|
for (const plugin of ctx.config.plugins) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/node/dom/env.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../../src/node/dom/env.ts"],"names":[],"mappings":"AA+BA,wBAAgB,YAAY;;;EAqD3B"}
|
package/dist/node/dom/env.js
CHANGED
|
@@ -1,11 +1,36 @@
|
|
|
1
1
|
import { JSDOM, VirtualConsole, } from 'jsdom';
|
|
2
2
|
import { populateGlobal } from './util.js';
|
|
3
|
+
// jsdom error types — not exported by jsdom.
|
|
4
|
+
const JSDOM_ERROR_CSS_PARSING = 'css-parsing';
|
|
5
|
+
const JSDOM_ERROR_UNHANDLED_EXCEPTION = 'unhandled-exception';
|
|
6
|
+
// Directives JSDOM's CSS parser doesn't know — Tailwind v4's `@theme` is the
|
|
7
|
+
// common one — make it emit a jsdomError per stylesheet, so collecting stories
|
|
8
|
+
// from a Tailwind app prints "Could not parse CSS stylesheet" over and over.
|
|
9
|
+
// The parser recovers on its own and keeps the valid rules, so the message is
|
|
10
|
+
// pure noise: drop css-parsing errors, mirror jsdom's default forwardTo for
|
|
11
|
+
// the rest.
|
|
12
|
+
function createVirtualConsole() {
|
|
13
|
+
if (!console || !globalThis.console)
|
|
14
|
+
return undefined;
|
|
15
|
+
const virtualConsole = new VirtualConsole().forwardTo(globalThis.console, { jsdomErrors: 'none' });
|
|
16
|
+
virtualConsole.on('jsdomError', (err) => {
|
|
17
|
+
if (err.type === JSDOM_ERROR_CSS_PARSING)
|
|
18
|
+
return;
|
|
19
|
+
if (err.type === JSDOM_ERROR_UNHANDLED_EXCEPTION) {
|
|
20
|
+
globalThis.console.error(err.cause?.stack ?? err.message);
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
globalThis.console.error(err.message);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
return virtualConsole;
|
|
27
|
+
}
|
|
3
28
|
export function createDomEnv() {
|
|
4
29
|
const dom = new JSDOM('<!DOCTYPE html>', {
|
|
5
30
|
pretendToBeVisual: true,
|
|
6
31
|
runScripts: 'dangerously',
|
|
7
32
|
url: 'http://localhost:3000',
|
|
8
|
-
virtualConsole:
|
|
33
|
+
virtualConsole: createVirtualConsole(),
|
|
9
34
|
includeNodeLocations: false,
|
|
10
35
|
contentType: 'text/html',
|
|
11
36
|
});
|
package/dist/node/markdown.js
CHANGED
|
@@ -27,7 +27,7 @@ export async function createMarkdownRenderer(ctx) {
|
|
|
27
27
|
langs: Object.keys(bundledLanguages), // not ideal but markdown-it does not provide async highlight
|
|
28
28
|
});
|
|
29
29
|
const md = new MarkdownIt({
|
|
30
|
-
highlight: (code, lang) => `<div class="
|
|
30
|
+
highlight: (code, lang) => `<div class="ptw-relative ptw-not-prose __poveste-code __histoire-code"><div class="ptw-absolute ptw-top-0 ptw-right-0 ptw-text-xs ptw-text-white/40">${lang}</div>${highlighter.codeToHtml(code, { theme: 'github-dark', lang })}</div>`,
|
|
31
31
|
linkify: true,
|
|
32
32
|
html: true,
|
|
33
33
|
breaks: false,
|
package/dist/node/preview.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import type { Context } from './context.js';
|
|
2
|
+
export interface StartPreviewOptions {
|
|
3
|
+
port?: number;
|
|
4
|
+
host?: string | boolean;
|
|
5
|
+
open?: boolean;
|
|
6
|
+
}
|
|
2
7
|
interface ReturnPayload {
|
|
3
8
|
baseUrl: string;
|
|
9
|
+
printUrls: () => void;
|
|
4
10
|
close: () => Promise<void>;
|
|
5
11
|
}
|
|
6
|
-
export declare function startPreview(
|
|
12
|
+
export declare function startPreview(options: StartPreviewOptions, ctx: Context): Promise<ReturnPayload>;
|
|
7
13
|
export {};
|
|
8
14
|
//# sourceMappingURL=preview.d.ts.map
|
|
@@ -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;
|
|
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,CAwBrG"}
|
package/dist/node/preview.js
CHANGED
|
@@ -1,41 +1,24 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
else {
|
|
19
|
-
reject(e);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
httpServer.on('error', onError);
|
|
23
|
-
httpServer.listen(finalPort, () => {
|
|
24
|
-
httpServer.off('error', onError);
|
|
25
|
-
const baseUrl = `http://localhost:${finalPort}${ctx.resolvedViteConfig.base}`;
|
|
26
|
-
resolve({
|
|
27
|
-
baseUrl,
|
|
28
|
-
close: () => new Promise((resolve, reject) => {
|
|
29
|
-
httpServer.close((err) => {
|
|
30
|
-
if (err) {
|
|
31
|
-
reject(err);
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
resolve();
|
|
35
|
-
}
|
|
36
|
-
});
|
|
37
|
-
}),
|
|
38
|
-
});
|
|
39
|
-
});
|
|
1
|
+
import { preview } from 'vite';
|
|
2
|
+
export async function startPreview(options, ctx) {
|
|
3
|
+
const port = options.port ?? 6006;
|
|
4
|
+
const server = await preview({
|
|
5
|
+
root: ctx.root,
|
|
6
|
+
base: ctx.resolvedViteConfig.base,
|
|
7
|
+
configFile: false,
|
|
8
|
+
build: {
|
|
9
|
+
outDir: ctx.config.outDir,
|
|
10
|
+
},
|
|
11
|
+
preview: {
|
|
12
|
+
port,
|
|
13
|
+
host: options.host,
|
|
14
|
+
open: options.open,
|
|
15
|
+
strictPort: false,
|
|
16
|
+
},
|
|
40
17
|
});
|
|
18
|
+
const baseUrl = server.resolvedUrls?.local[0] ?? `http://localhost:${port}${ctx.resolvedViteConfig.base}`;
|
|
19
|
+
return {
|
|
20
|
+
baseUrl,
|
|
21
|
+
printUrls: () => server.printUrls(),
|
|
22
|
+
close: () => server.close(),
|
|
23
|
+
};
|
|
41
24
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Plugin as VitePlugin } from 'vite';
|
|
2
|
+
export interface EntryCssMergerOptions {
|
|
3
|
+
isolateStyles: boolean;
|
|
4
|
+
scopeRoot?: string;
|
|
5
|
+
mainEntryName?: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function entryCssMergerPlugin(opts?: EntryCssMergerOptions): VitePlugin;
|
|
8
|
+
export declare function wrapMarkedUserCss(css: string, scopeRoot: string): string;
|
|
9
|
+
//# sourceMappingURL=entry-css-merger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry-css-merger.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/entry-css-merger.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAA;AAKhD,MAAM,WAAW,qBAAqB;IACpC,aAAa,EAAE,OAAO,CAAA;IACtB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,GAAE,qBAAgD,GAAG,UAAU,CA4FvG;AAMD,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAsBxE"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { STORY_SCOPE_ROOT } from './selectors.js';
|
|
2
|
+
import { wrapUserCss } from './transforms.js';
|
|
3
|
+
import { USER_CSS_MARK_END, USER_CSS_MARK_START } from './vite-plugin.js';
|
|
4
|
+
export function entryCssMergerPlugin(opts = { isolateStyles: false }) {
|
|
5
|
+
const scopeRoot = opts.scopeRoot ?? STORY_SCOPE_ROOT;
|
|
6
|
+
const mainEntryName = opts.mainEntryName ?? 'bundle-main';
|
|
7
|
+
return {
|
|
8
|
+
name: 'poveste:style-isolation:entry-css-merger',
|
|
9
|
+
apply: 'build',
|
|
10
|
+
enforce: 'post',
|
|
11
|
+
generateBundle(_options, bundle) {
|
|
12
|
+
function collectChunkCss(entryFileName, entryName, acc) {
|
|
13
|
+
const seen = new Set();
|
|
14
|
+
const queue = [entryFileName];
|
|
15
|
+
let head = 0;
|
|
16
|
+
while (head < queue.length) {
|
|
17
|
+
const cur = queue[head++];
|
|
18
|
+
if (seen.has(cur))
|
|
19
|
+
continue;
|
|
20
|
+
seen.add(cur);
|
|
21
|
+
const c = bundle[cur];
|
|
22
|
+
if (!c || c.type !== 'chunk')
|
|
23
|
+
continue;
|
|
24
|
+
const meta = c.viteMetadata;
|
|
25
|
+
if (meta?.importedCss) {
|
|
26
|
+
for (const cssName of meta.importedCss) {
|
|
27
|
+
const list = acc.get(cssName) ?? [];
|
|
28
|
+
if (!list.includes(entryName))
|
|
29
|
+
list.push(entryName);
|
|
30
|
+
acc.set(cssName, list);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
for (const imp of c.imports ?? [])
|
|
34
|
+
queue.push(imp);
|
|
35
|
+
for (const imp of c.dynamicImports ?? [])
|
|
36
|
+
queue.push(imp);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const cssAssetUsedBy = new Map();
|
|
40
|
+
for (const [fileName, chunk] of Object.entries(bundle)) {
|
|
41
|
+
if (chunk.type !== 'chunk' || !chunk.isEntry)
|
|
42
|
+
continue;
|
|
43
|
+
collectChunkCss(fileName, chunk.name, cssAssetUsedBy);
|
|
44
|
+
}
|
|
45
|
+
const mergedByEntry = new Map();
|
|
46
|
+
for (const [cssName, entries] of cssAssetUsedBy) {
|
|
47
|
+
const asset = bundle[cssName];
|
|
48
|
+
if (!asset || asset.type !== 'asset')
|
|
49
|
+
continue;
|
|
50
|
+
const source = typeof asset.source === 'string'
|
|
51
|
+
? asset.source
|
|
52
|
+
: new TextDecoder().decode(asset.source);
|
|
53
|
+
for (const entryName of entries) {
|
|
54
|
+
const list = mergedByEntry.get(entryName) ?? [];
|
|
55
|
+
list.push(source);
|
|
56
|
+
mergedByEntry.set(entryName, list);
|
|
57
|
+
}
|
|
58
|
+
delete bundle[cssName];
|
|
59
|
+
}
|
|
60
|
+
for (const [entryName, sources] of mergedByEntry) {
|
|
61
|
+
const fileName = `${entryName}.css`;
|
|
62
|
+
const merged = sources.join('\n');
|
|
63
|
+
const finalSource = entryName === mainEntryName && opts.isolateStyles
|
|
64
|
+
? wrapMarkedUserCss(merged, scopeRoot)
|
|
65
|
+
: stripMarkers(merged);
|
|
66
|
+
bundle[fileName] = {
|
|
67
|
+
type: 'asset',
|
|
68
|
+
fileName,
|
|
69
|
+
name: fileName,
|
|
70
|
+
source: finalSource,
|
|
71
|
+
needsCodeReference: false,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
// Re-point CSS metadata: entries claim their own merged file; non-entry
|
|
75
|
+
// chunks (vendor, route splits) drop their importedCss because the
|
|
76
|
+
// assets they referenced were merged into the entry's CSS and deleted.
|
|
77
|
+
// Without this, Vite's runtime preload helper 404s on the missing
|
|
78
|
+
// per-chunk CSS files.
|
|
79
|
+
const entryCssByEntryName = new Map();
|
|
80
|
+
for (const [, chunk] of Object.entries(bundle)) {
|
|
81
|
+
if (chunk.type !== 'chunk' || !chunk.isEntry)
|
|
82
|
+
continue;
|
|
83
|
+
if (mergedByEntry.has(chunk.name)) {
|
|
84
|
+
entryCssByEntryName.set(chunk.name, `${chunk.name}.css`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
for (const [, chunk] of Object.entries(bundle)) {
|
|
88
|
+
if (chunk.type !== 'chunk')
|
|
89
|
+
continue;
|
|
90
|
+
const meta = chunk.viteMetadata;
|
|
91
|
+
if (!meta?.importedCss)
|
|
92
|
+
continue;
|
|
93
|
+
if (chunk.isEntry && entryCssByEntryName.has(chunk.name)) {
|
|
94
|
+
meta.importedCss = new Set([entryCssByEntryName.get(chunk.name)]);
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
meta.importedCss = new Set();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function stripMarkers(css) {
|
|
104
|
+
return css.split(USER_CSS_MARK_START).join('').split(USER_CSS_MARK_END).join('');
|
|
105
|
+
}
|
|
106
|
+
export function wrapMarkedUserCss(css, scopeRoot) {
|
|
107
|
+
let out = '';
|
|
108
|
+
let cursor = 0;
|
|
109
|
+
while (cursor < css.length) {
|
|
110
|
+
const start = css.indexOf(USER_CSS_MARK_START, cursor);
|
|
111
|
+
if (start === -1) {
|
|
112
|
+
out += css.slice(cursor);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
out += css.slice(cursor, start);
|
|
116
|
+
const end = css.indexOf(USER_CSS_MARK_END, start + USER_CSS_MARK_START.length);
|
|
117
|
+
if (end === -1) {
|
|
118
|
+
out += css.slice(start + USER_CSS_MARK_START.length);
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
const inner = css.slice(start + USER_CSS_MARK_START.length, end).trim();
|
|
122
|
+
if (inner.length > 0) {
|
|
123
|
+
out += `${wrapUserCss(inner, { scopeRoot })}\n`;
|
|
124
|
+
}
|
|
125
|
+
cursor = end + USER_CSS_MARK_END.length;
|
|
126
|
+
}
|
|
127
|
+
return out;
|
|
128
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Plugin as VitePlugin } from 'vite';
|
|
2
|
+
export interface GlobalStylesPluginOptions {
|
|
3
|
+
files: string[];
|
|
4
|
+
rootDir: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function globalStylesPlugin(opts: GlobalStylesPluginOptions): VitePlugin;
|
|
7
|
+
export declare function getGlobalStylesVirtualId(): string;
|
|
8
|
+
//# sourceMappingURL=global-styles.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-styles.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/global-styles.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAA;AAOhD,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,UAAU,CAoB9E;AAED,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { resolve } from 'pathe';
|
|
2
|
+
import { GLOBAL_LAYER_QUERY, USER_GLOBALS_LAYER } from './selectors.js';
|
|
3
|
+
const VIRTUAL_ID = 'virtual:$poveste-global-styles';
|
|
4
|
+
const RESOLVED_ID = `\0${VIRTUAL_ID}`;
|
|
5
|
+
export function globalStylesPlugin(opts) {
|
|
6
|
+
return {
|
|
7
|
+
name: 'poveste:style-isolation:global-styles',
|
|
8
|
+
resolveId(id) {
|
|
9
|
+
if (id === VIRTUAL_ID)
|
|
10
|
+
return RESOLVED_ID;
|
|
11
|
+
},
|
|
12
|
+
load(id) {
|
|
13
|
+
if (id !== RESOLVED_ID)
|
|
14
|
+
return null;
|
|
15
|
+
return opts.files
|
|
16
|
+
.map(f => `import ${JSON.stringify(`${resolve(opts.rootDir, f)}?${GLOBAL_LAYER_QUERY}`)}`)
|
|
17
|
+
.join('\n');
|
|
18
|
+
},
|
|
19
|
+
transform(code, id) {
|
|
20
|
+
if (!id.includes(`?${GLOBAL_LAYER_QUERY}`))
|
|
21
|
+
return null;
|
|
22
|
+
return {
|
|
23
|
+
code: `@layer ${USER_GLOBALS_LAYER} {\n${code}\n}\n`,
|
|
24
|
+
map: null,
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export function getGlobalStylesVirtualId() {
|
|
30
|
+
return VIRTUAL_ID;
|
|
31
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAA;AACrC,cAAc,oBAAoB,CAAA;AAClC,cAAc,mBAAmB,CAAA;AACjC,cAAc,iBAAiB,CAAA;AAC/B,cAAc,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-chrome.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/scope-chrome.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAA;AAKhD,MAAM,WAAW,2BAA2B;IAC1C,OAAO,EAAE,OAAO,CAAA;CACjB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,2BAA2B,GAAG,UAAU,CAgBlF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { APP_SCOPE_ROOT, DEFAULTS_LAYER, STORY_SCOPE_BOUNDARY } from './selectors.js';
|
|
2
|
+
import { wrapChromeCss } from './transforms.js';
|
|
3
|
+
import { isChromeCss } from './vite-plugin.js';
|
|
4
|
+
export function chromeCssScopePlugin(opts) {
|
|
5
|
+
return {
|
|
6
|
+
name: 'poveste:style-isolation:chrome-css',
|
|
7
|
+
transform(code, id) {
|
|
8
|
+
if (!opts.enabled)
|
|
9
|
+
return null;
|
|
10
|
+
if (isMainChromeCss(id)) {
|
|
11
|
+
return { code: wrapChromeCss(code, { scopeRoot: APP_SCOPE_ROOT, scopeLower: STORY_SCOPE_BOUNDARY }), map: null };
|
|
12
|
+
}
|
|
13
|
+
if (isSandboxChromeCss(id)) {
|
|
14
|
+
// Sandbox chrome defaults coexist with user CSS inside the iframe.
|
|
15
|
+
// @layer makes user's unlayered rules win the cascade.
|
|
16
|
+
return { code: `@layer ${DEFAULTS_LAYER} {\n${code}\n}\n`, map: null };
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
// Stylesheets loaded only by the chrome page (bundle-main).
|
|
23
|
+
function isMainChromeCss(id) {
|
|
24
|
+
if (!isChromeCss(id))
|
|
25
|
+
return false;
|
|
26
|
+
const cleaned = id.split('?')[0];
|
|
27
|
+
return /(?:poveste-app|@poveste\/app)\/(?:dist\/style\.css|dist\/bundled\/[^/]+\.css|src\/app\/style\/main\.(?:css|pcss))$/.test(cleaned);
|
|
28
|
+
}
|
|
29
|
+
// Stylesheets loaded into the sandbox iframe — must coexist with user CSS,
|
|
30
|
+
// so they get a cascade-layer wrap rather than an @scope wrap.
|
|
31
|
+
function isSandboxChromeCss(id) {
|
|
32
|
+
if (!isChromeCss(id))
|
|
33
|
+
return false;
|
|
34
|
+
const cleaned = id.split('?')[0];
|
|
35
|
+
return /\/(?:poveste-app|@poveste\/app)\/(?:dist|src)\/.*\bsandbox\.css$/.test(cleaned)
|
|
36
|
+
|| /\/(?:poveste-controls|@poveste\/controls)\/dist\/index\.es\.css$/.test(cleaned);
|
|
37
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const APP_SCOPE_ROOT = ".poveste-app-root";
|
|
2
|
+
export declare const STORY_SCOPE_ROOT = ".__poveste-render-story";
|
|
3
|
+
export declare const STORY_SCOPE_BOUNDARY = ".__poveste-render-story:not(.__poveste-render-custom-controls)";
|
|
4
|
+
export declare const DEFAULTS_LAYER = "poveste-defaults";
|
|
5
|
+
export declare const USER_GLOBALS_LAYER = "poveste-user-globals";
|
|
6
|
+
export declare const GLOBAL_LAYER_QUERY = "poveste-global-layer";
|
|
7
|
+
//# sourceMappingURL=selectors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selectors.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/selectors.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,cAAc,sBAAsB,CAAA;AACjD,eAAO,MAAM,gBAAgB,4BAA4B,CAAA;AAIzD,eAAO,MAAM,oBAAoB,mEAAmE,CAAA;AACpG,eAAO,MAAM,cAAc,qBAAqB,CAAA;AAChD,eAAO,MAAM,kBAAkB,yBAAyB,CAAA;AAGxD,eAAO,MAAM,kBAAkB,yBAAyB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// Centralised CSS scope-root class names used by the style-isolation
|
|
2
|
+
// pipeline. Keep in sync with the runtime markers applied in
|
|
3
|
+
// poveste-app (App.vue's `poveste-app-root` wrapper, GenericRenderStory's
|
|
4
|
+
// `__poveste-render-story` class, sandbox.ts's body class).
|
|
5
|
+
export const APP_SCOPE_ROOT = '.poveste-app-root';
|
|
6
|
+
export const STORY_SCOPE_ROOT = '.__poveste-render-story';
|
|
7
|
+
// Custom-controls panels carry both classes (.__poveste-render-story and
|
|
8
|
+
// .__poveste-render-custom-controls) but render inside the chrome panel,
|
|
9
|
+
// so the @scope boundary must keep them in chrome scope.
|
|
10
|
+
export const STORY_SCOPE_BOUNDARY = '.__poveste-render-story:not(.__poveste-render-custom-controls)';
|
|
11
|
+
export const DEFAULTS_LAYER = 'poveste-defaults';
|
|
12
|
+
export const USER_GLOBALS_LAYER = 'poveste-user-globals';
|
|
13
|
+
// Import query `globalStyles` files carry so the user-CSS plugin leaves them
|
|
14
|
+
// alone — they belong in the chrome page, not inside the story scope.
|
|
15
|
+
export const GLOBAL_LAYER_QUERY = 'poveste-global-layer';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface WrapOptions {
|
|
2
|
+
scopeRoot: string;
|
|
3
|
+
}
|
|
4
|
+
export interface WrapWithLowerOptions {
|
|
5
|
+
scopeRoot: string;
|
|
6
|
+
scopeLower: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function wrapUserCss(css: string, opts: WrapOptions): string;
|
|
9
|
+
export declare function wrapChromeCss(css: string, opts: WrapWithLowerOptions): string;
|
|
10
|
+
export declare function isGlobalImport(id: string): boolean;
|
|
11
|
+
//# sourceMappingURL=transforms.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/transforms.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,MAAM,CAWlE;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,oBAAoB,GAAG,MAAM,CAc7E;AAED,wBAAgB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAKlD"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Buffer } from 'node:buffer';
|
|
2
|
+
import { transform as lightningcssTransform } from 'lightningcss';
|
|
3
|
+
export function wrapUserCss(css, opts) {
|
|
4
|
+
const trimmed = css.trimStart();
|
|
5
|
+
if (trimmed.startsWith('@scope')) {
|
|
6
|
+
return css;
|
|
7
|
+
}
|
|
8
|
+
const { hoisted, remainder } = extractHoistableAtRules(css);
|
|
9
|
+
const body = remainder.includes(':root')
|
|
10
|
+
? rewriteRootToScope(remainder)
|
|
11
|
+
: remainder;
|
|
12
|
+
const hoistedBlock = hoisted.length > 0 ? `${hoisted.join('\n')}\n` : '';
|
|
13
|
+
return `${hoistedBlock}@scope (${opts.scopeRoot}) {\n${body}\n}\n`;
|
|
14
|
+
}
|
|
15
|
+
export function wrapChromeCss(css, opts) {
|
|
16
|
+
const trimmed = css.trimStart();
|
|
17
|
+
if (trimmed.startsWith('@scope (')) {
|
|
18
|
+
return css;
|
|
19
|
+
}
|
|
20
|
+
const { hoisted, remainder } = extractHoistableAtRules(css);
|
|
21
|
+
// Rewrite `:root` to `:scope` so source-level `@scope (:root) to (...)`
|
|
22
|
+
// rules nest correctly under the outer scope; without this, the inner
|
|
23
|
+
// `:root` resolves to the document root which is outside the outer scope.
|
|
24
|
+
const body = remainder.includes(':root')
|
|
25
|
+
? rewriteRootToScope(remainder)
|
|
26
|
+
: remainder;
|
|
27
|
+
const hoistedBlock = hoisted.length > 0 ? `${hoisted.join('\n')}\n` : '';
|
|
28
|
+
return `${hoistedBlock}@scope (${opts.scopeRoot}) to (${opts.scopeLower}) {\n${body}\n}\n`;
|
|
29
|
+
}
|
|
30
|
+
export function isGlobalImport(id) {
|
|
31
|
+
const q = id.indexOf('?');
|
|
32
|
+
if (q === -1)
|
|
33
|
+
return false;
|
|
34
|
+
const parts = id.slice(q + 1).split('&');
|
|
35
|
+
return parts.includes('global') || parts.some(p => p.startsWith('global='));
|
|
36
|
+
}
|
|
37
|
+
function rewriteRootToScope(css) {
|
|
38
|
+
const processed = lightningcssTransform({
|
|
39
|
+
filename: 'user.css',
|
|
40
|
+
code: Buffer.from(css, 'utf8'),
|
|
41
|
+
minify: false,
|
|
42
|
+
visitor: {
|
|
43
|
+
Selector(selector) {
|
|
44
|
+
for (const part of selector) {
|
|
45
|
+
if (part.type === 'pseudo-class' && part.kind === 'root') {
|
|
46
|
+
;
|
|
47
|
+
part.kind = 'scope';
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
return selector;
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
return Buffer.from(processed.code).toString('utf8');
|
|
55
|
+
}
|
|
56
|
+
// Top-level at-rule extraction. Anchored to line start with optional leading
|
|
57
|
+
// whitespace; covers the formatted output produced by Vite/PostCSS. Inputs
|
|
58
|
+
// with rules on the same line as other rules, or strings/comments containing
|
|
59
|
+
// `;`/`}`, are not handled — these are extremely rare in practice and would
|
|
60
|
+
// only mis-classify within a generated poveste-app or vendor stylesheet.
|
|
61
|
+
const HOIST_SEMI_RE = /^[ \t]*@(?:import|charset|namespace)\s[^;]+;[ \t]*\n?/gm;
|
|
62
|
+
const HOIST_FONT_FACE_RE = /^[ \t]*@font-face\s*\{[^}]*\}[ \t]*\n?/gm;
|
|
63
|
+
function extractHoistableAtRules(css) {
|
|
64
|
+
const hoisted = [];
|
|
65
|
+
let remainder = css;
|
|
66
|
+
remainder = remainder.replace(HOIST_SEMI_RE, (match) => {
|
|
67
|
+
hoisted.push(match.trim());
|
|
68
|
+
return '';
|
|
69
|
+
});
|
|
70
|
+
remainder = remainder.replace(HOIST_FONT_FACE_RE, (match) => {
|
|
71
|
+
hoisted.push(match.trim());
|
|
72
|
+
return '';
|
|
73
|
+
});
|
|
74
|
+
return { hoisted, remainder };
|
|
75
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Plugin as VitePlugin } from 'vite';
|
|
2
|
+
export declare const USER_CSS_MARK_START = "/*__PVT_USER_CSS_START__*/";
|
|
3
|
+
export declare const USER_CSS_MARK_END = "/*__PVT_USER_CSS_END__*/";
|
|
4
|
+
export interface UserCssScopePluginOptions {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
/**
|
|
7
|
+
* 'mark' — insert sentinel comments; entry-css-merger wraps per-entry at
|
|
8
|
+
* build time. 'wrap' — wrap directly in @scope at transform time (dev,
|
|
9
|
+
* no merger).
|
|
10
|
+
*/
|
|
11
|
+
mode?: 'mark' | 'wrap';
|
|
12
|
+
}
|
|
13
|
+
export declare function userCssScopePlugin(opts: UserCssScopePluginOptions): VitePlugin;
|
|
14
|
+
export declare function isChromeCss(id: string): boolean;
|
|
15
|
+
//# sourceMappingURL=vite-plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../../../src/node/style-isolation/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,MAAM,CAAA;AAIhD,eAAO,MAAM,mBAAmB,+BAA+B,CAAA;AAC/D,eAAO,MAAM,iBAAiB,6BAA6B,CAAA;AAE3D,MAAM,WAAW,yBAAyB;IACxC,OAAO,EAAE,OAAO,CAAA;IAChB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACvB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,yBAAyB,GAAG,UAAU,CAsB9E;AAsBD,wBAAgB,WAAW,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAG/C"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { GLOBAL_LAYER_QUERY, STORY_SCOPE_ROOT } from './selectors.js';
|
|
2
|
+
import { wrapUserCss } from './transforms.js';
|
|
3
|
+
export const USER_CSS_MARK_START = '/*__PVT_USER_CSS_START__*/';
|
|
4
|
+
export const USER_CSS_MARK_END = '/*__PVT_USER_CSS_END__*/';
|
|
5
|
+
export function userCssScopePlugin(opts) {
|
|
6
|
+
const mode = opts.mode ?? 'mark';
|
|
7
|
+
return {
|
|
8
|
+
name: 'poveste:style-isolation:user-css',
|
|
9
|
+
transform(code, id) {
|
|
10
|
+
if (!opts.enabled)
|
|
11
|
+
return null;
|
|
12
|
+
const q = id.indexOf('?');
|
|
13
|
+
const path = q === -1 ? id : id.slice(0, q);
|
|
14
|
+
const query = q === -1 ? '' : id.slice(q + 1);
|
|
15
|
+
// Cheap substring rejection of all poveste-internal CSS first.
|
|
16
|
+
if (isChromePath(path))
|
|
17
|
+
return null;
|
|
18
|
+
if (!isCssPath(path, query))
|
|
19
|
+
return null;
|
|
20
|
+
if (hasGlobalQuery(query))
|
|
21
|
+
return null;
|
|
22
|
+
if (mode === 'wrap') {
|
|
23
|
+
return { code: wrapUserCss(code, { scopeRoot: STORY_SCOPE_ROOT }), map: null };
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
code: `${USER_CSS_MARK_START}\n${code}\n${USER_CSS_MARK_END}\n`,
|
|
27
|
+
map: null,
|
|
28
|
+
};
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
const CSS_EXT_RE = /\.(?:css|pcss|postcss|scss|sass|less|styl|stylus)$/;
|
|
33
|
+
// Vue / Svelte / Vite virtual style modules carry the source extension as a
|
|
34
|
+
// `lang.<ext>` query, e.g. `Foo.vue?vue&type=style&index=0&lang.css`.
|
|
35
|
+
const CSS_LANG_QUERY_RE = /(?:^|&)lang\.(?:css|pcss|postcss|scss|sass|less|styl|stylus)(?:&|$)/;
|
|
36
|
+
function isCssPath(path, query) {
|
|
37
|
+
return CSS_EXT_RE.test(path) || CSS_LANG_QUERY_RE.test(query);
|
|
38
|
+
}
|
|
39
|
+
function hasGlobalQuery(query) {
|
|
40
|
+
if (!query)
|
|
41
|
+
return false;
|
|
42
|
+
const parts = query.split('&');
|
|
43
|
+
// `?global` is the per-import escape hatch; the `globalStyles` config marks
|
|
44
|
+
// its files with `?poveste-global-layer` and they get a cascade layer of
|
|
45
|
+
// their own in global-styles.ts.
|
|
46
|
+
return parts.includes('global')
|
|
47
|
+
|| parts.some(p => p.startsWith('global='))
|
|
48
|
+
|| parts.includes(GLOBAL_LAYER_QUERY);
|
|
49
|
+
}
|
|
50
|
+
export function isChromeCss(id) {
|
|
51
|
+
const q = id.indexOf('?');
|
|
52
|
+
return isChromePath(q === -1 ? id : id.slice(0, q));
|
|
53
|
+
}
|
|
54
|
+
function isChromePath(path) {
|
|
55
|
+
return path.includes('@poveste/app/')
|
|
56
|
+
|| path.includes('poveste-app/')
|
|
57
|
+
|| path.includes('@poveste/controls/')
|
|
58
|
+
|| path.includes('poveste-controls/')
|
|
59
|
+
|| path.includes('@poveste/vendors/')
|
|
60
|
+
|| path.includes('poveste-vendors/')
|
|
61
|
+
|| path.includes('virtual:$poveste-');
|
|
62
|
+
}
|