@qds.dev/tools 0.7.5 → 0.8.5
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/lib/docs/component-props.qwik.mjs +500 -0
- package/lib/docs/index.qwik.mjs +3 -0
- package/lib/playground/generate-jsx.qwik.mjs +153 -0
- package/lib/playground/index.qwik.mjs +10 -0
- package/lib/playground/prop-extraction.qwik.mjs +500 -0
- package/lib/playground/scenario-injection.qwik.mjs +68 -0
- package/lib/repl/bundler/bundled.qwik.mjs +38 -0
- package/lib/repl/bundler/index.qwik.mjs +89 -0
- package/lib/repl/index.qwik.mjs +21 -0
- package/lib/repl/repl-constants.qwik.mjs +5 -0
- package/lib/rolldown/index.qwik.mjs +2 -1
- package/lib/rolldown/inline-asset.qwik.mjs +171 -0
- package/lib/rolldown/playground.qwik.mjs +67 -0
- package/lib/vite/index.qwik.mjs +2 -1
- package/lib/vite/minify-content.qwik.mjs +6 -4
- package/lib-types/tools/docs/component-props.d.ts +32 -0
- package/lib-types/tools/docs/component-props.unit.d.ts +1 -0
- package/lib-types/tools/docs/generate-metadata.d.ts +1 -0
- package/lib-types/tools/docs/generate-metadata.unit.d.ts +1 -0
- package/lib-types/tools/docs/index.d.ts +2 -0
- package/lib-types/tools/playground/generate-jsx.d.ts +9 -0
- package/lib-types/tools/playground/generate-metadata.d.ts +1 -0
- package/lib-types/tools/playground/generate-metadata.unit.d.ts +1 -0
- package/lib-types/tools/playground/index.d.ts +5 -0
- package/lib-types/tools/playground/prop-extraction.d.ts +32 -0
- package/lib-types/tools/playground/prop-extraction.unit.d.ts +1 -0
- package/lib-types/tools/playground/scenario-injection.d.ts +2 -0
- package/lib-types/tools/playground/scenario-injection.unit.d.ts +1 -0
- package/lib-types/tools/rolldown/index.d.ts +2 -0
- package/lib-types/tools/rolldown/inline-asset.d.ts +18 -0
- package/lib-types/tools/rolldown/inline-asset.unit.d.ts +1 -0
- package/lib-types/tools/rolldown/playground.d.ts +8 -0
- package/lib-types/tools/rolldown/playground.unit.d.ts +1 -0
- package/lib-types/tools/src/vite.d.ts +1 -0
- package/lib-types/tools/utils/fs-mock.d.ts +17 -0
- package/lib-types/tools/vite/index.d.ts +3 -2
- package/package.json +6 -2
- package/lib-types/tsconfig.tsbuildinfo +0 -1
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { getDeps } from "./bundled.qwik.mjs";
|
|
2
|
+
|
|
3
|
+
//#region repl/bundler/index.ts
|
|
4
|
+
var Bundler = class {
|
|
5
|
+
worker = null;
|
|
6
|
+
initP = null;
|
|
7
|
+
ready = null;
|
|
8
|
+
timer = null;
|
|
9
|
+
buildPromises = /* @__PURE__ */ new Map();
|
|
10
|
+
nextBuildId = 1;
|
|
11
|
+
constructor() {
|
|
12
|
+
this.initWorker();
|
|
13
|
+
this.keepAlive();
|
|
14
|
+
}
|
|
15
|
+
initWorker() {
|
|
16
|
+
this.initP = new Promise((res) => this.ready = res);
|
|
17
|
+
this.worker = new Worker(new URL("./repl-bundler-worker.ts", import.meta.url), { type: "module" });
|
|
18
|
+
this.worker.addEventListener("message", this.messageHandler);
|
|
19
|
+
this.worker.addEventListener("error", (e) => {
|
|
20
|
+
console.error(`Bundler worker failed`, e.message);
|
|
21
|
+
this.terminateWorker();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
messageHandler = (e) => {
|
|
25
|
+
const { type } = e.data;
|
|
26
|
+
if (type === "ready") {
|
|
27
|
+
const message = {
|
|
28
|
+
type: "init",
|
|
29
|
+
deps: getDeps()
|
|
30
|
+
};
|
|
31
|
+
this.worker.postMessage.bind(this.worker)(message);
|
|
32
|
+
this.ready();
|
|
33
|
+
} else if (type === "result" || type === "error") {
|
|
34
|
+
const { buildId } = e.data;
|
|
35
|
+
const promise = this.buildPromises.get(buildId);
|
|
36
|
+
if (promise) {
|
|
37
|
+
this.buildPromises.delete(buildId);
|
|
38
|
+
if (type === "result") promise.resolve(e.data.result);
|
|
39
|
+
else {
|
|
40
|
+
const { error, stack } = e.data;
|
|
41
|
+
const err = new Error(error);
|
|
42
|
+
if (stack) err.stack = stack;
|
|
43
|
+
promise.reject(err);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
keepAlive() {
|
|
49
|
+
clearTimeout(this.timer);
|
|
50
|
+
this.timer = setTimeout(() => this.terminateWorker(), 1e3 * 60 * 5);
|
|
51
|
+
}
|
|
52
|
+
bundle(options) {
|
|
53
|
+
if (!this.worker) this.initWorker();
|
|
54
|
+
this.keepAlive();
|
|
55
|
+
return this.initP.then(() => {
|
|
56
|
+
return new Promise((resolve, reject) => {
|
|
57
|
+
const buildId = this.nextBuildId++;
|
|
58
|
+
this.buildPromises.set(buildId, {
|
|
59
|
+
resolve,
|
|
60
|
+
reject
|
|
61
|
+
});
|
|
62
|
+
const message = {
|
|
63
|
+
type: "bundle",
|
|
64
|
+
buildId,
|
|
65
|
+
data: options
|
|
66
|
+
};
|
|
67
|
+
const postMessage = this.worker?.postMessage.bind(this.worker);
|
|
68
|
+
postMessage?.(message);
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
terminateWorker() {
|
|
73
|
+
if (this.worker) {
|
|
74
|
+
this.worker.removeEventListener("message", this.messageHandler);
|
|
75
|
+
this.worker.terminate();
|
|
76
|
+
this.worker = null;
|
|
77
|
+
this.buildPromises.forEach((p) => p.reject(/* @__PURE__ */ new Error("Worker terminated")));
|
|
78
|
+
this.buildPromises.clear();
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
let bundler;
|
|
83
|
+
const getBundler = () => {
|
|
84
|
+
if (!bundler) bundler = new Bundler();
|
|
85
|
+
return bundler;
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
//#endregion
|
|
89
|
+
export { getBundler };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { getBundler } from "./bundler/index.qwik.mjs";
|
|
2
|
+
|
|
3
|
+
//#region repl/index.ts
|
|
4
|
+
var ReplCompiler = class {
|
|
5
|
+
options;
|
|
6
|
+
bundler;
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.options = options;
|
|
9
|
+
this.bundler = getBundler();
|
|
10
|
+
}
|
|
11
|
+
async compile(input) {
|
|
12
|
+
const finalOptions = {
|
|
13
|
+
...this.options,
|
|
14
|
+
...input
|
|
15
|
+
};
|
|
16
|
+
return this.bundler.bundle(finalOptions);
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
//#endregion
|
|
21
|
+
export { ReplCompiler };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { asChild } from "./as-child.qwik.mjs";
|
|
2
2
|
import { icons } from "./icons.qwik.mjs";
|
|
3
|
+
import { inlineAsset } from "./inline-asset.qwik.mjs";
|
|
3
4
|
import { inlineCssPlugin } from "./inline-css.qwik.mjs";
|
|
4
5
|
import { qwikRolldown } from "./qwik-rolldown.qwik.mjs";
|
|
5
6
|
|
|
6
|
-
export { asChild, icons, inlineCssPlugin, qwikRolldown };
|
|
7
|
+
export { asChild, icons, inlineAsset, inlineCssPlugin, qwikRolldown };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { anyOf, char, createRegExp, exactly, maybe, oneOrMore } from "magic-regexp";
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
4
|
+
import { basename, dirname, join } from "node:path";
|
|
5
|
+
import { createHash } from "node:crypto";
|
|
6
|
+
|
|
7
|
+
//#region rolldown/inline-asset.ts
|
|
8
|
+
const nodeRequire = createRequire(import.meta.url);
|
|
9
|
+
/**
|
|
10
|
+
* Embeds file content as build-time assets, returning URLs to the inlined content.
|
|
11
|
+
* Supports both relative paths and package imports (e.g., @qwik.dev/core/dist/...).
|
|
12
|
+
*
|
|
13
|
+
* Supports two query parameters:
|
|
14
|
+
* - `?inline-asset` - Inlines the file content as an asset
|
|
15
|
+
* - `?no-transform` - Returns raw file content without any transformations
|
|
16
|
+
*
|
|
17
|
+
* @param options - Plugin configuration options
|
|
18
|
+
* @returns Rolldown/Vite-compatible plugin object
|
|
19
|
+
*/ const inlineAsset = (options = {}) => {
|
|
20
|
+
const { debug: isDebugMode = false, outDir = "public/.qds-inline-assets" } = options;
|
|
21
|
+
const debugInlineAsset = (...args) => {
|
|
22
|
+
if (!isDebugMode) return;
|
|
23
|
+
console.log("[inline-asset]", ...args);
|
|
24
|
+
};
|
|
25
|
+
let isDevMode = false;
|
|
26
|
+
const assetDir = join(process.cwd(), outDir);
|
|
27
|
+
if (!existsSync(assetDir)) {
|
|
28
|
+
mkdirSync(assetDir, { recursive: true });
|
|
29
|
+
debugInlineAsset("Created asset directory:", assetDir);
|
|
30
|
+
}
|
|
31
|
+
const inlineAssetQuery = createRegExp(anyOf("?", "&"), exactly("inline-asset"));
|
|
32
|
+
const noTransformQuery = createRegExp(anyOf("?", "&"), exactly("no-transform"));
|
|
33
|
+
const combinedQuery = createRegExp(anyOf("?", "&"), anyOf(exactly("inline-asset"), exactly("no-transform")));
|
|
34
|
+
const inlineAssetPattern = createRegExp(anyOf(exactly("?"), exactly("&")), exactly("inline-asset"), maybe(exactly("&"), oneOrMore(char)), ["g"]);
|
|
35
|
+
const noTransformPattern = createRegExp(anyOf(exactly("?"), exactly("&")), exactly("no-transform"), maybe(exactly("&"), oneOrMore(char)), ["g"]);
|
|
36
|
+
return {
|
|
37
|
+
name: "inline-asset",
|
|
38
|
+
configResolved(config) {
|
|
39
|
+
isDevMode = config.command === "serve";
|
|
40
|
+
debugInlineAsset("Dev mode:", isDevMode);
|
|
41
|
+
},
|
|
42
|
+
resolveId: {
|
|
43
|
+
order: "pre",
|
|
44
|
+
filter: { id: combinedQuery },
|
|
45
|
+
async handler(id, importer, options$1) {
|
|
46
|
+
const isInlineAsset = inlineAssetQuery.test(id);
|
|
47
|
+
const isNoTransform = noTransformQuery.test(id);
|
|
48
|
+
if (!isInlineAsset && !isNoTransform) return;
|
|
49
|
+
debugInlineAsset("resolveId:", {
|
|
50
|
+
id,
|
|
51
|
+
importer,
|
|
52
|
+
isInlineAsset,
|
|
53
|
+
isNoTransform
|
|
54
|
+
});
|
|
55
|
+
const basePath = id.replace(inlineAssetPattern, "").replace(noTransformPattern, "");
|
|
56
|
+
debugInlineAsset("Resolving base path:", basePath);
|
|
57
|
+
let resolvedPath = null;
|
|
58
|
+
try {
|
|
59
|
+
const resolved = await this.resolve(basePath, importer, {
|
|
60
|
+
...options$1,
|
|
61
|
+
skipSelf: true
|
|
62
|
+
});
|
|
63
|
+
if (resolved) resolvedPath = resolved.id.split("?")[0];
|
|
64
|
+
} catch {
|
|
65
|
+
if (basePath.startsWith("@") || !basePath.startsWith(".") && !basePath.startsWith("/")) {
|
|
66
|
+
const parts = basePath.split("/");
|
|
67
|
+
let packageName;
|
|
68
|
+
let subpathStartIndex;
|
|
69
|
+
if (basePath.startsWith("@")) {
|
|
70
|
+
packageName = `${parts[0]}/${parts[1]}`;
|
|
71
|
+
subpathStartIndex = 2;
|
|
72
|
+
} else {
|
|
73
|
+
packageName = parts[0];
|
|
74
|
+
subpathStartIndex = 1;
|
|
75
|
+
}
|
|
76
|
+
const subpath = parts.slice(subpathStartIndex).join("/");
|
|
77
|
+
try {
|
|
78
|
+
const basePath$1 = importer ? dirname(importer) : process.cwd();
|
|
79
|
+
resolvedPath = join(dirname(nodeRequire.resolve(`${packageName}/package.json`, { paths: [basePath$1] })), subpath);
|
|
80
|
+
debugInlineAsset("Manually resolved package import:", resolvedPath);
|
|
81
|
+
} catch (err) {
|
|
82
|
+
debugInlineAsset("Failed to manually resolve:", err);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (!resolvedPath) {
|
|
87
|
+
debugInlineAsset("Could not resolve path:", basePath, "- returning null");
|
|
88
|
+
return null;
|
|
89
|
+
}
|
|
90
|
+
if (!existsSync(resolvedPath)) {
|
|
91
|
+
debugInlineAsset("Resolved path does not exist:", resolvedPath, "- returning null");
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
debugInlineAsset("Resolved to:", resolvedPath);
|
|
95
|
+
let queryParam;
|
|
96
|
+
if (isInlineAsset) queryParam = "inline-asset-resolved";
|
|
97
|
+
else queryParam = "no-transform-resolved";
|
|
98
|
+
const resolvedId = `${resolvedPath}?${queryParam}`;
|
|
99
|
+
debugInlineAsset("Returning resolved ID:", resolvedId);
|
|
100
|
+
return {
|
|
101
|
+
id: resolvedId,
|
|
102
|
+
external: false
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
},
|
|
106
|
+
load(id) {
|
|
107
|
+
const isInlineAsset = id.includes("?inline-asset-resolved");
|
|
108
|
+
const isNoTransform = id.includes("?no-transform-resolved");
|
|
109
|
+
if (!isInlineAsset && !isNoTransform) return null;
|
|
110
|
+
let path = id.split("?")[0];
|
|
111
|
+
if (path.startsWith("/@fs/")) path = path.slice(4);
|
|
112
|
+
if (path.startsWith("\0")) path = path.slice(1);
|
|
113
|
+
debugInlineAsset("Loading file:", path, {
|
|
114
|
+
isInlineAsset,
|
|
115
|
+
isNoTransform
|
|
116
|
+
});
|
|
117
|
+
if (!existsSync(path)) throw new Error(`[inline-asset] File not found: ${path}`);
|
|
118
|
+
const fileContent = readFileSync(path);
|
|
119
|
+
debugInlineAsset("Read file:", path, `(${fileContent.length} bytes)`);
|
|
120
|
+
const isTestMode = typeof process !== "undefined" && (process.env.VITEST || process.env.NODE_ENV === "test");
|
|
121
|
+
debugInlineAsset("Test mode:", isTestMode, "Dev mode:", isDevMode);
|
|
122
|
+
if (isTestMode || isDevMode) {
|
|
123
|
+
debugInlineAsset("Using data URL for", isTestMode ? "test" : "dev", "mode:", basename(path));
|
|
124
|
+
const base64 = fileContent.toString("base64");
|
|
125
|
+
const dataUrl = `data:${{
|
|
126
|
+
js: "application/javascript",
|
|
127
|
+
mjs: "application/javascript",
|
|
128
|
+
wasm: "application/wasm",
|
|
129
|
+
json: "application/json",
|
|
130
|
+
css: "text/css",
|
|
131
|
+
html: "text/html",
|
|
132
|
+
ts: "application/typescript",
|
|
133
|
+
dts: "application/typescript"
|
|
134
|
+
}[path.split(".").pop() || ""] || "application/octet-stream"};base64,${base64}`;
|
|
135
|
+
debugInlineAsset("Returning data URL, length:", dataUrl.length);
|
|
136
|
+
return {
|
|
137
|
+
code: `export default ${JSON.stringify(dataUrl)};`,
|
|
138
|
+
map: {
|
|
139
|
+
version: 3,
|
|
140
|
+
sources: [path],
|
|
141
|
+
mappings: ""
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
const hash = createHash("sha256").update(fileContent).digest("hex").slice(0, 8);
|
|
146
|
+
const ext = path.split(".").pop() || "bin";
|
|
147
|
+
const fileName = `${basename(path, `.${ext}`)}-${hash}.${ext}`;
|
|
148
|
+
const outputPath = join(assetDir, fileName);
|
|
149
|
+
try {
|
|
150
|
+
writeFileSync(outputPath, fileContent);
|
|
151
|
+
debugInlineAsset("Wrote asset file:", outputPath);
|
|
152
|
+
} catch (err) {
|
|
153
|
+
throw new Error(`[inline-asset] Failed to write file ${outputPath}`, { cause: err });
|
|
154
|
+
}
|
|
155
|
+
const publicPrefixRegex = createRegExp(exactly("public/").at.lineStart());
|
|
156
|
+
const publicUrl = `/${outDir.replace(publicPrefixRegex, "")}/${fileName}`;
|
|
157
|
+
debugInlineAsset("Returning public URL:", publicUrl);
|
|
158
|
+
return {
|
|
159
|
+
code: `export default ${JSON.stringify(publicUrl)};`,
|
|
160
|
+
map: {
|
|
161
|
+
version: 3,
|
|
162
|
+
sources: [path],
|
|
163
|
+
mappings: ""
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
//#endregion
|
|
171
|
+
export { inlineAsset };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { createRegExp, exactly } from "magic-regexp";
|
|
2
|
+
import MagicString from "magic-string";
|
|
3
|
+
import { walk } from "oxc-walker";
|
|
4
|
+
import { existsSync, readdirSync, statSync } from "node:fs";
|
|
5
|
+
import { basename, dirname, extname, join } from "node:path";
|
|
6
|
+
import { remark } from "remark";
|
|
7
|
+
import remarkMdx from "remark-mdx";
|
|
8
|
+
|
|
9
|
+
//#region rolldown/playground.ts
|
|
10
|
+
const playground = () => {
|
|
11
|
+
const isMDX = createRegExp(exactly(".").and("mdx").at.lineEnd());
|
|
12
|
+
return {
|
|
13
|
+
name: "vite-plugin-qds-playground",
|
|
14
|
+
enforce: "pre",
|
|
15
|
+
async transform(code, id) {
|
|
16
|
+
if (!isMDX.test(id)) return;
|
|
17
|
+
try {
|
|
18
|
+
const mdast = remark().use(remarkMdx).parse(code);
|
|
19
|
+
const s = new MagicString(code);
|
|
20
|
+
let hasPlayground = false;
|
|
21
|
+
const scenariosDir = join(dirname(id), "scenarios");
|
|
22
|
+
if (!existsSync(scenariosDir) || !statSync(scenariosDir).isDirectory()) return null;
|
|
23
|
+
const scenarioFiles = readdirSync(scenariosDir).filter((file) => file.endsWith(".tsx") || file.endsWith(".ts")).map((file) => {
|
|
24
|
+
const name = basename(file, extname(file));
|
|
25
|
+
return {
|
|
26
|
+
name,
|
|
27
|
+
file,
|
|
28
|
+
componentVar: `Scenario_${name.replace(/[^a-zA-Z0-9]/g, "_")}`,
|
|
29
|
+
sourceVar: `Source_${name.replace(/[^a-zA-Z0-9]/g, "_")}`
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
if (scenarioFiles.length === 0) return null;
|
|
33
|
+
walk(mdast, { enter(node) {
|
|
34
|
+
const mdxNode = node;
|
|
35
|
+
if ((mdxNode.type === "mdxJsxFlowElement" || mdxNode.type === "mdxJsxTextElement") && mdxNode.name === "Playground") {
|
|
36
|
+
if (mdxNode.position?.start?.offset !== void 0 && mdxNode.position?.end?.offset !== void 0) {
|
|
37
|
+
if (!mdxNode.attributes.some((attr) => attr.name === "scenarios")) {
|
|
38
|
+
const scenariosArrayString = `[${scenarioFiles.map((s$1) => `{name: "${s$1.name}", component: ${s$1.componentVar}, source: ${s$1.sourceVar}}`).join(", ")}]`;
|
|
39
|
+
const insertPos$1 = mdxNode.position.start.offset + 11;
|
|
40
|
+
s.appendLeft(insertPos$1, ` scenarios={${scenariosArrayString}}`);
|
|
41
|
+
hasPlayground = true;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
} });
|
|
46
|
+
if (!hasPlayground) return null;
|
|
47
|
+
const imports = scenarioFiles.map((file) => `import ${file.componentVar} from "./scenarios/${file.file}";\nimport ${file.sourceVar} from "./scenarios/${file.file}?raw";`).join("\n");
|
|
48
|
+
let insertPos = 0;
|
|
49
|
+
if (code.startsWith("---")) {
|
|
50
|
+
const secondDelimiter = code.indexOf("---", 3);
|
|
51
|
+
if (secondDelimiter !== -1) insertPos = secondDelimiter + 3;
|
|
52
|
+
}
|
|
53
|
+
s.appendLeft(insertPos, `\n${imports}\n`);
|
|
54
|
+
return {
|
|
55
|
+
code: s.toString(),
|
|
56
|
+
map: s.generateMap({ hires: true })
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.error(`Error transforming Playground in ${id}:`, error);
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
//#endregion
|
|
67
|
+
export { playground };
|
package/lib/vite/index.qwik.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { asChild } from "../rolldown/as-child.qwik.mjs";
|
|
2
2
|
import { icons } from "../rolldown/icons.qwik.mjs";
|
|
3
|
+
import { inlineAsset } from "../rolldown/inline-asset.qwik.mjs";
|
|
3
4
|
import "../rolldown/index.qwik.mjs";
|
|
4
5
|
import { minifyContentPlugin } from "./minify-content.qwik.mjs";
|
|
5
6
|
|
|
6
|
-
export { asChild, icons, minifyContentPlugin };
|
|
7
|
+
export { asChild, icons, inlineAsset, minifyContentPlugin };
|
|
@@ -8,15 +8,16 @@ import { transform } from "oxc-transform";
|
|
|
8
8
|
/**
|
|
9
9
|
* This plugin strips types, then minifies the contents of files with the ".script." extension. We watch the components library files and update the injected scripts when the contents change. Useful for dynamic client-only code without waking up the Qwik runtime.
|
|
10
10
|
*/ function minifyContentPlugin(options) {
|
|
11
|
+
const isTestMode = typeof process !== "undefined" && (process.env.VITEST || process.env.NODE_ENV === "test");
|
|
11
12
|
const scriptsMap = {};
|
|
12
13
|
const outputFileName = options?.outputFileName || "injected-scripts.ts";
|
|
13
14
|
const outputTsPath = resolve(options?.outputDir || process.cwd(), outputFileName);
|
|
14
15
|
const partString = `.${options?.part || "script"}.`;
|
|
15
16
|
const scriptExtension = createRegExp(exactly(partString).and(oneOrMore(char)).at.lineEnd());
|
|
16
17
|
const processMap = async (id, code) => {
|
|
17
|
-
const basename = id.split(sep).join("/").split("/").pop() || "";
|
|
18
|
-
if (!scriptExtension.test(basename)) return false;
|
|
19
|
-
const [name] = basename.split(partString);
|
|
18
|
+
const basename$1 = id.split(sep).join("/").split("/").pop() || "";
|
|
19
|
+
if (!scriptExtension.test(basename$1)) return false;
|
|
20
|
+
const [name] = basename$1.split(partString);
|
|
20
21
|
if (!name) return false;
|
|
21
22
|
try {
|
|
22
23
|
scriptsMap[name] = minifySync(id, (await transform(id, code, { typescript: { onlyRemoveTypeImports: false } })).code, {
|
|
@@ -24,6 +25,7 @@ import { transform } from "oxc-transform";
|
|
|
24
25
|
mangle: { toplevel: true }
|
|
25
26
|
}).code;
|
|
26
27
|
const newFileContent = `export const INJECTED_SCRIPTS = ${JSON.stringify(scriptsMap, null, 2)} as const;`;
|
|
28
|
+
if (isTestMode) return true;
|
|
27
29
|
let shouldWrite = true;
|
|
28
30
|
if (existsSync(outputTsPath)) {
|
|
29
31
|
if (readFileSync(outputTsPath, "utf-8") === newFileContent) shouldWrite = false;
|
|
@@ -35,7 +37,7 @@ import { transform } from "oxc-transform";
|
|
|
35
37
|
return false;
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
|
-
if (!existsSync(outputTsPath)) writeFileSync(outputTsPath, "export const INJECTED_SCRIPTS = {} as const;", "utf-8");
|
|
40
|
+
if (!isTestMode && !existsSync(outputTsPath)) writeFileSync(outputTsPath, "export const INJECTED_SCRIPTS = {} as const;", "utf-8");
|
|
39
41
|
return {
|
|
40
42
|
name: "vite-plugin-script-injector",
|
|
41
43
|
enforce: "pre",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Node } from "@oxc-project/types";
|
|
2
|
+
import type { Plugin as VitePlugin } from "vite";
|
|
3
|
+
export type PropType = {
|
|
4
|
+
name: string;
|
|
5
|
+
type: "boolean" | "string" | "number" | "union" | "function" | "unknown";
|
|
6
|
+
unionValues?: string[];
|
|
7
|
+
isBindable: boolean;
|
|
8
|
+
isFunction?: boolean;
|
|
9
|
+
initialValue?: unknown;
|
|
10
|
+
comment?: string;
|
|
11
|
+
scenario?: string;
|
|
12
|
+
};
|
|
13
|
+
export type ComponentPiece = {
|
|
14
|
+
name: string;
|
|
15
|
+
props: PropType[];
|
|
16
|
+
};
|
|
17
|
+
export type ComponentMetadata = {
|
|
18
|
+
componentName: string;
|
|
19
|
+
pieces: ComponentPiece[];
|
|
20
|
+
};
|
|
21
|
+
export type ComponentPropsPluginOptions = {
|
|
22
|
+
componentsDir: string;
|
|
23
|
+
outputDir: string;
|
|
24
|
+
debug?: boolean;
|
|
25
|
+
};
|
|
26
|
+
export declare const componentProps: (options: ComponentPropsPluginOptions) => VitePlugin;
|
|
27
|
+
export declare function generateAllComponentMetadata(componentsDir: string, outputDir: string, debug: (message: string, ...data: unknown[]) => void): Promise<void>;
|
|
28
|
+
export declare function generateComponentMetadata(componentName: string, componentsDir: string, outputDir: string, debug: (message: string, ...data: unknown[]) => void): Promise<void>;
|
|
29
|
+
export declare function extractJSDoc(node: Node, source: string, propName?: string): {
|
|
30
|
+
comment?: string;
|
|
31
|
+
scenario?: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ComponentMetadata } from "./prop-extraction";
|
|
2
|
+
export type GenerateJsxOptions = {
|
|
3
|
+
metadata: ComponentMetadata;
|
|
4
|
+
selectedPieceName: string;
|
|
5
|
+
propValues: Record<string, Record<string, unknown>>;
|
|
6
|
+
isBindProps: boolean;
|
|
7
|
+
baseSource?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare function generateJsx({ metadata, selectedPieceName, propValues, isBindProps, baseSource }: GenerateJsxOptions): string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Plugin as VitePlugin } from "vite";
|
|
2
|
+
import { type ComponentPropsPluginOptions } from "./prop-extraction";
|
|
3
|
+
export type PlaygroundPluginOptions = ComponentPropsPluginOptions;
|
|
4
|
+
export declare const playground: (options: PlaygroundPluginOptions) => VitePlugin[];
|
|
5
|
+
export type { ComponentMetadata, ComponentPiece, PropType } from "./prop-extraction";
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Node } from "@oxc-project/types";
|
|
2
|
+
import type { Plugin as VitePlugin } from "vite";
|
|
3
|
+
export type PropType = {
|
|
4
|
+
name: string;
|
|
5
|
+
type: "boolean" | "string" | "number" | "union" | "function" | "unknown";
|
|
6
|
+
unionValues?: string[];
|
|
7
|
+
isBindable: boolean;
|
|
8
|
+
isFunction?: boolean;
|
|
9
|
+
initialValue?: unknown;
|
|
10
|
+
comment?: string;
|
|
11
|
+
scenario?: string;
|
|
12
|
+
};
|
|
13
|
+
export type ComponentPiece = {
|
|
14
|
+
name: string;
|
|
15
|
+
props: PropType[];
|
|
16
|
+
};
|
|
17
|
+
export type ComponentMetadata = {
|
|
18
|
+
componentName: string;
|
|
19
|
+
pieces: ComponentPiece[];
|
|
20
|
+
};
|
|
21
|
+
export type ComponentPropsPluginOptions = {
|
|
22
|
+
componentsDir: string;
|
|
23
|
+
outputDir: string;
|
|
24
|
+
debug?: boolean;
|
|
25
|
+
};
|
|
26
|
+
export declare const propExtraction: (options: ComponentPropsPluginOptions) => VitePlugin;
|
|
27
|
+
export declare function generateAllComponentMetadata(componentsDir: string, outputDir: string, debug: (message: string, ...data: unknown[]) => void): Promise<void>;
|
|
28
|
+
export declare function generateComponentMetadata(componentName: string, componentsDir: string, outputDir: string, debug: (message: string, ...data: unknown[]) => void): Promise<void>;
|
|
29
|
+
export declare function extractJSDoc(node: Node, source: string, propName?: string): {
|
|
30
|
+
comment?: string;
|
|
31
|
+
scenario?: string;
|
|
32
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -2,5 +2,7 @@ export type { AsChildPluginOptions, AsChildTypes } from "./as-child";
|
|
|
2
2
|
export { asChild } from "./as-child";
|
|
3
3
|
export type { IconsPluginOptions, PacksMap } from "./icons";
|
|
4
4
|
export { icons } from "./icons";
|
|
5
|
+
export type { InlineAssetPluginOptions } from "./inline-asset";
|
|
6
|
+
export { inlineAsset } from "./inline-asset";
|
|
5
7
|
export { inlineCssPlugin } from "./inline-css";
|
|
6
8
|
export { qwikRolldown } from "./qwik-rolldown";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Plugin } from "rolldown";
|
|
2
|
+
export type InlineAssetPluginOptions = {
|
|
3
|
+
debug?: boolean;
|
|
4
|
+
/** Directory to write inline assets (relative to project root). Defaults to 'public/.qds-inline-assets' */
|
|
5
|
+
outDir?: string;
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* Embeds file content as build-time assets, returning URLs to the inlined content.
|
|
9
|
+
* Supports both relative paths and package imports (e.g., @qwik.dev/core/dist/...).
|
|
10
|
+
*
|
|
11
|
+
* Supports two query parameters:
|
|
12
|
+
* - `?inline-asset` - Inlines the file content as an asset
|
|
13
|
+
* - `?no-transform` - Returns raw file content without any transformations
|
|
14
|
+
*
|
|
15
|
+
* @param options - Plugin configuration options
|
|
16
|
+
* @returns Rolldown/Vite-compatible plugin object
|
|
17
|
+
*/
|
|
18
|
+
export declare const inlineAsset: (options?: InlineAssetPluginOptions) => Plugin;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type { AsChildTypes } from "../vite";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export declare const readFile: () => Promise<string>;
|
|
2
|
+
export declare const readFileSync: () => string;
|
|
3
|
+
export declare const existsSync: () => boolean;
|
|
4
|
+
export declare const statSync: () => {};
|
|
5
|
+
export declare const mkdir: () => Promise<void>;
|
|
6
|
+
export declare const readdir: () => Promise<never[]>;
|
|
7
|
+
export declare const writeFile: () => Promise<void>;
|
|
8
|
+
declare const _default: {
|
|
9
|
+
readFile: () => Promise<string>;
|
|
10
|
+
readFileSync: () => string;
|
|
11
|
+
existsSync: () => boolean;
|
|
12
|
+
statSync: () => {};
|
|
13
|
+
mkdir: () => Promise<void>;
|
|
14
|
+
readdir: () => Promise<never[]>;
|
|
15
|
+
writeFile: () => Promise<void>;
|
|
16
|
+
};
|
|
17
|
+
export default _default;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
-
export type { AsChildPluginOptions, AsChildTypes, IconsPluginOptions, PacksMap } from "../rolldown";
|
|
2
|
-
export {
|
|
1
|
+
export type { AsChildPluginOptions, AsChildTypes, IconsPluginOptions, InlineAssetPluginOptions, PacksMap } from "../rolldown/index";
|
|
2
|
+
export type { Plugin as VitePlugin, PluginOption as VitePluginOption } from "vite";
|
|
3
|
+
export { asChild, icons, inlineAsset } from "../rolldown/index";
|
|
3
4
|
export { minifyContentPlugin } from "./minify-content";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qds.dev/tools",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Tools and utilities for Qwik Design System",
|
|
6
6
|
"type": "module",
|
|
@@ -28,6 +28,10 @@
|
|
|
28
28
|
"./rolldown": {
|
|
29
29
|
"import": "./lib/rolldown/index.qwik.mjs",
|
|
30
30
|
"types": "./lib-types/tools/rolldown/index.d.ts"
|
|
31
|
+
},
|
|
32
|
+
"./playground": {
|
|
33
|
+
"import": "./lib/playground/index.qwik.mjs",
|
|
34
|
+
"types": "./lib-types/tools/playground/index.d.ts"
|
|
31
35
|
}
|
|
32
36
|
},
|
|
33
37
|
"devDependencies": {
|
|
@@ -35,7 +39,7 @@
|
|
|
35
39
|
"magic-string": "^0.30.17",
|
|
36
40
|
"rolldown": "1.0.0-beta.45",
|
|
37
41
|
"typescript": "5.4.5",
|
|
38
|
-
"vite": "^7.
|
|
42
|
+
"vite": "^7.3.1"
|
|
39
43
|
},
|
|
40
44
|
"dependencies": {
|
|
41
45
|
"@iconify/json": "^2.2.382",
|