vitral 0.3.0 → 0.5.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/angular.d.ts +2 -2
- package/dist/angular.js +7 -7
- package/dist/auto.js +7 -7
- package/dist/{capture-JYFERAPL.js → capture-TT5WBLJ6.js} +1 -1
- package/dist/channel-2YPYGX3J.js +95 -0
- package/dist/{chunk-AKNNHQ2H.js → chunk-463H6B56.js} +5 -0
- package/dist/{chunk-IHTUM6LT.js → chunk-4Z77XNBR.js} +2 -2
- package/dist/chunk-54CBIZES.js +105 -0
- package/dist/{chunk-TD4S3IHA.js → chunk-5JNV45BB.js} +10 -8
- package/dist/{chunk-SDB5AZEI.js → chunk-C3QOBAUE.js} +2 -2
- package/dist/chunk-DAESKNQ6.js +207 -0
- package/dist/{chunk-3YXI3G34.js → chunk-K6EG7DMO.js} +16 -7
- package/dist/{chunk-ZAC6QQI6.js → chunk-KU6HF2EW.js} +4 -4
- package/dist/{chunk-I3VSKSAZ.js → chunk-KZBH5MPD.js} +29 -27
- package/dist/chunk-NZEQGRBL.js +93 -0
- package/dist/chunk-PY7P5BF4.js +404 -0
- package/dist/{chunk-GNHCZRQP.js → chunk-TW7KYJQ6.js} +1 -1
- package/dist/{chunk-AH7KNMBW.js → chunk-UYOPJ4XQ.js} +1 -1
- package/dist/cli.js +1522 -37
- package/dist/devtools.d.ts +32 -2
- package/dist/devtools.js +27 -12
- package/dist/dict.d.ts +69 -0
- package/dist/dict.js +8 -0
- package/dist/edge.d.ts +118 -0
- package/dist/edge.js +398 -0
- package/dist/element.d.ts +12 -3
- package/dist/element.js +7 -7
- package/dist/embed.js +2 -0
- package/dist/{events-D5gs7rff.d.ts → events-0rxFlWJJ.d.ts} +1 -1
- package/dist/expose-IAKYHJXF.js +15 -0
- package/dist/federation.d.ts +89 -0
- package/dist/federation.js +101 -0
- package/dist/hydrate-YVZDJ2V7.js +168 -0
- package/dist/iframe.js +7 -7
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -5
- package/dist/otel.d.ts +29 -1
- package/dist/otel.js +13 -1
- package/dist/overrides-NP754HY7.js +27 -0
- package/dist/preact.d.ts +4 -4
- package/dist/preact.js +6 -6
- package/dist/prefetch.d.ts +25 -0
- package/dist/prefetch.js +178 -0
- package/dist/react.d.ts +3 -3
- package/dist/react.js +6 -6
- package/dist/reframe-LQL4DZYP.js +251 -0
- package/dist/routes.d.ts +2 -2
- package/dist/routes.js +5 -5
- package/dist/{shadow-6HELCHCJ.js → shadow-S4SKHTA7.js} +66 -5
- package/dist/single-spa.d.ts +40 -0
- package/dist/single-spa.js +52 -0
- package/dist/{slot-DqXTwGbs.d.ts → slot-D49L1rdU.d.ts} +1 -1
- package/dist/solid.d.ts +3 -3
- package/dist/solid.js +6 -6
- package/dist/{sri-JMX6JLQP.js → sri-576GTDIA.js} +41 -10
- package/dist/svelte.d.ts +4 -4
- package/dist/svelte.js +6 -6
- package/dist/testing.d.ts +171 -3
- package/dist/testing.js +193 -6
- package/dist/{types-Czvm-siZ.d.ts → types-DUtcF3HO.d.ts} +124 -5
- package/dist/vitals.d.ts +29 -0
- package/dist/vitals.js +152 -0
- package/dist/vite.d.ts +18 -0
- package/dist/vite.js +329 -417
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +6 -6
- package/package.json +170 -21
- package/dist/chunk-DXORSF4X.js +0 -42
- package/dist/expose-JUOUN5N5.js +0 -15
- package/dist/overrides-NZAIUGK5.js +0 -15
|
@@ -3,20 +3,21 @@ import {
|
|
|
3
3
|
loadFile,
|
|
4
4
|
registerSrc,
|
|
5
5
|
resolveEntry
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-5JNV45BB.js";
|
|
7
7
|
import {
|
|
8
8
|
injectStyles
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KU6HF2EW.js";
|
|
10
10
|
import {
|
|
11
11
|
metric
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-TW7KYJQ6.js";
|
|
13
13
|
import {
|
|
14
14
|
RemoteError,
|
|
15
|
+
ctxHooks,
|
|
15
16
|
fail,
|
|
16
17
|
isRemoteError,
|
|
17
18
|
mounted,
|
|
18
19
|
report
|
|
19
|
-
} from "./chunk-
|
|
20
|
+
} from "./chunk-463H6B56.js";
|
|
20
21
|
import {
|
|
21
22
|
protocol
|
|
22
23
|
} from "./chunk-GNPFWISJ.js";
|
|
@@ -47,9 +48,6 @@ function scopedEvents() {
|
|
|
47
48
|
};
|
|
48
49
|
}
|
|
49
50
|
|
|
50
|
-
// src/core/hooks.ts
|
|
51
|
-
var ctxHooks = {};
|
|
52
|
-
|
|
53
51
|
// src/core/navigate.ts
|
|
54
52
|
function navigate(url, options = {}) {
|
|
55
53
|
const target = new URL(url, location.href);
|
|
@@ -121,7 +119,7 @@ var noop = () => {
|
|
|
121
119
|
async function checkUpdates() {
|
|
122
120
|
const p = protocol();
|
|
123
121
|
const found = [];
|
|
124
|
-
const { splitName } = await import("./expose-
|
|
122
|
+
const { splitName } = await import("./expose-IAKYHJXF.js");
|
|
125
123
|
const remotes = /* @__PURE__ */ new Map();
|
|
126
124
|
for (const name of live.keys()) {
|
|
127
125
|
const root = splitName(name)[0];
|
|
@@ -165,27 +163,26 @@ function setFrameMounter(mounter) {
|
|
|
165
163
|
async function mountOnce(target, name, props, options) {
|
|
166
164
|
const p = protocol();
|
|
167
165
|
await p.pending();
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
}
|
|
172
|
-
const { module: mod, ...resolved } = await load(name, options.isolate, options.priority);
|
|
166
|
+
const isolate = options.isolate ?? registered(name)?.isolate ?? p.settings().isolate;
|
|
167
|
+
if (isolate === "iframe") return (frames ?? (await import("./reframe-LQL4DZYP.js")).noFrames)(target, name, props, options).catch(fail);
|
|
168
|
+
const { module: mod, ...resolved } = await (isolate == "reframe" ? (await import("./reframe-LQL4DZYP.js")).load : load)(name, isolate, options.priority);
|
|
173
169
|
const untrack = track(name, resolved);
|
|
174
|
-
|
|
170
|
+
ctxHooks.watch?.(name);
|
|
175
171
|
const label = resolved.name ?? name;
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
shadowRoot.appendChild(el);
|
|
184
|
-
} else {
|
|
185
|
-
target.appendChild(el);
|
|
186
|
-
}
|
|
172
|
+
const make = (options2) => {
|
|
173
|
+
const el2 = document.createElement("div", options2);
|
|
174
|
+
el2.setAttribute("data-vitral-root", label);
|
|
175
|
+
if (resolved.scope) el2.setAttribute("data-vitral-scope", resolved.scope);
|
|
176
|
+
el2.style.display = "contents";
|
|
177
|
+
return el2;
|
|
178
|
+
};
|
|
187
179
|
let t = performance.now();
|
|
188
|
-
const [release, portal = document.body
|
|
180
|
+
const [release, portal = document.body, shadowRoot = null, registry = customElements, el = target.appendChild(make())] = await injectStyles(
|
|
181
|
+
resolved,
|
|
182
|
+
isolate > "q" && target,
|
|
183
|
+
make,
|
|
184
|
+
options.styles
|
|
185
|
+
);
|
|
189
186
|
metric(name, "css", t);
|
|
190
187
|
t = performance.now();
|
|
191
188
|
const scoped = scopedEvents();
|
|
@@ -196,13 +193,14 @@ async function mountOnce(target, name, props, options) {
|
|
|
196
193
|
events: scoped.bus,
|
|
197
194
|
shadowRoot,
|
|
198
195
|
portalContainer: portal,
|
|
196
|
+
customElements: registry,
|
|
199
197
|
reportError(e) {
|
|
200
198
|
const err = report(isRemoteError(e) ? e : new RemoteError("RENDER_FAILED", label, String(e?.message ?? e), e), resolved);
|
|
201
199
|
if (options.onError) options.onError(err);
|
|
202
200
|
else console.error(err);
|
|
203
201
|
},
|
|
204
202
|
navigate,
|
|
205
|
-
protocol:
|
|
203
|
+
protocol: p.protocol,
|
|
206
204
|
onActivate: on("vitral:activate"),
|
|
207
205
|
onDeactivate: on("vitral:deactivate")
|
|
208
206
|
};
|
|
@@ -610,13 +608,17 @@ function serializeShared(values) {
|
|
|
610
608
|
|
|
611
609
|
export {
|
|
612
610
|
events,
|
|
611
|
+
scopedEvents,
|
|
613
612
|
navigate,
|
|
614
613
|
track,
|
|
615
614
|
refresh,
|
|
615
|
+
refreshable,
|
|
616
616
|
checkUpdates,
|
|
617
617
|
watchUpdates,
|
|
618
618
|
mountRemote,
|
|
619
619
|
setFrameMounter,
|
|
620
|
+
mountOnce,
|
|
621
|
+
registered,
|
|
620
622
|
createSlot,
|
|
621
623
|
defineRemote,
|
|
622
624
|
html,
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/dict.ts
|
|
2
|
+
var VARY = "Accept-Encoding, Available-Dictionary";
|
|
3
|
+
var HASH = /-[\w-]{8}(\.[a-z]+)$/;
|
|
4
|
+
var ESPECIAIS = /[\\+*?:{}()]/g;
|
|
5
|
+
function dictMatch(pathname) {
|
|
6
|
+
const i = pathname.lastIndexOf("/") + 1;
|
|
7
|
+
const dir = pathname.slice(0, i).replace(ESPECIAIS, "\\$&");
|
|
8
|
+
const name = pathname.slice(i);
|
|
9
|
+
const m = HASH.exec(name);
|
|
10
|
+
if (!m) return dir + name.replace(ESPECIAIS, "\\$&");
|
|
11
|
+
return dir + name.slice(0, m.index).replace(ESPECIAIS, "\\$&") + "-*" + m[1];
|
|
12
|
+
}
|
|
13
|
+
function accepted(header) {
|
|
14
|
+
const out = /* @__PURE__ */ new Set();
|
|
15
|
+
for (const part of (header ?? "").split(",")) {
|
|
16
|
+
const [name, ...params] = part.trim().toLowerCase().split(";");
|
|
17
|
+
if (!name || params.some((p) => /^\s*q\s*=\s*0(\.0*)?\s*$/.test(p))) continue;
|
|
18
|
+
out.add(name.trim());
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
function createDict(o) {
|
|
23
|
+
const base = (o.base ?? "/").replace(/\/?$/, "/");
|
|
24
|
+
const cacheControl = o.cacheControl ?? "public, max-age=31536000, immutable";
|
|
25
|
+
const lookup = (pathname) => {
|
|
26
|
+
if (!pathname.startsWith(base)) return void 0;
|
|
27
|
+
let rel;
|
|
28
|
+
try {
|
|
29
|
+
rel = decodeURIComponent(pathname.slice(base.length));
|
|
30
|
+
} catch {
|
|
31
|
+
return void 0;
|
|
32
|
+
}
|
|
33
|
+
return Object.prototype.hasOwnProperty.call(o.index.files, rel) ? o.index.files[rel] : void 0;
|
|
34
|
+
};
|
|
35
|
+
const headers = (pathname) => lookup(pathname) ? { "Use-As-Dictionary": `match="${dictMatch(pathname)}"`, Vary: VARY } : void 0;
|
|
36
|
+
const choose = (pathname, method, available, encoding) => {
|
|
37
|
+
if (method && method !== "GET" && method !== "HEAD") return void 0;
|
|
38
|
+
const file = lookup(pathname);
|
|
39
|
+
const hash = available?.trim();
|
|
40
|
+
if (!file || !hash || !Object.prototype.hasOwnProperty.call(file.deltas, hash)) return void 0;
|
|
41
|
+
const variant = file.deltas[hash];
|
|
42
|
+
const ok = accepted(encoding);
|
|
43
|
+
const enc = variant.dcz && ok.has("dcz") ? "dcz" : variant.dcb && ok.has("dcb") ? "dcb" : void 0;
|
|
44
|
+
if (!enc) return void 0;
|
|
45
|
+
return {
|
|
46
|
+
path: variant[enc],
|
|
47
|
+
head: {
|
|
48
|
+
"Content-Type": file.type,
|
|
49
|
+
"Content-Encoding": enc,
|
|
50
|
+
"Cache-Control": cacheControl,
|
|
51
|
+
"Use-As-Dictionary": `match="${dictMatch(pathname)}"`,
|
|
52
|
+
Vary: VARY
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
return {
|
|
57
|
+
headers,
|
|
58
|
+
async fetch(request) {
|
|
59
|
+
const url = new URL(request.url);
|
|
60
|
+
const hit = choose(url.pathname, request.method, request.headers.get("available-dictionary"), request.headers.get("accept-encoding"));
|
|
61
|
+
if (!hit) return void 0;
|
|
62
|
+
const body = await o.read(hit.path);
|
|
63
|
+
if (body == null) return void 0;
|
|
64
|
+
const init = { headers: hit.head, encodeBody: "manual" };
|
|
65
|
+
return new Response(request.method === "HEAD" ? null : body, init);
|
|
66
|
+
},
|
|
67
|
+
node(req, res, next) {
|
|
68
|
+
const pathname = new URL(req.url ?? "/", "http://x").pathname;
|
|
69
|
+
const one = (v) => Array.isArray(v) ? v.join(",") : v;
|
|
70
|
+
const hit = choose(pathname, req.method, one(req.headers["available-dictionary"]), one(req.headers["accept-encoding"]));
|
|
71
|
+
if (!hit) {
|
|
72
|
+
const h = headers(pathname);
|
|
73
|
+
if (h) for (const [k, v] of Object.entries(h)) res.setHeader(k, v);
|
|
74
|
+
return next();
|
|
75
|
+
}
|
|
76
|
+
Promise.resolve(o.read(hit.path)).then(async (body) => {
|
|
77
|
+
if (body == null) {
|
|
78
|
+
const h = headers(pathname);
|
|
79
|
+
for (const [k, v] of Object.entries(h)) res.setHeader(k, v);
|
|
80
|
+
return next();
|
|
81
|
+
}
|
|
82
|
+
const bytes = typeof body === "string" || body instanceof Uint8Array ? body : new Uint8Array(await new Response(body).arrayBuffer());
|
|
83
|
+
res.writeHead(200, hit.head);
|
|
84
|
+
res.end(req.method === "HEAD" ? void 0 : bytes);
|
|
85
|
+
}).catch(next);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export {
|
|
91
|
+
dictMatch,
|
|
92
|
+
createDict
|
|
93
|
+
};
|
|
@@ -0,0 +1,404 @@
|
|
|
1
|
+
// src/vite/types.ts
|
|
2
|
+
import { createRequire as createRequire2 } from "module";
|
|
3
|
+
import { join as join2 } from "path";
|
|
4
|
+
|
|
5
|
+
// src/vite/oxc.ts
|
|
6
|
+
import { existsSync, readFileSync } from "fs";
|
|
7
|
+
import { createRequire } from "module";
|
|
8
|
+
import { dirname, join, resolve } from "path";
|
|
9
|
+
import { pathToFileURL } from "url";
|
|
10
|
+
async function loadOxc(root) {
|
|
11
|
+
const req = createRequire(join(root, "package.json"));
|
|
12
|
+
const ids = [() => req.resolve("oxc-transform"), () => createRequire(req.resolve("vite/package.json")).resolve("rolldown/experimental")];
|
|
13
|
+
for (const id of ids) {
|
|
14
|
+
try {
|
|
15
|
+
const mod = await import(pathToFileURL(id()).href);
|
|
16
|
+
if (typeof mod.isolatedDeclarationSync === "function") return mod;
|
|
17
|
+
} catch {
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
return null;
|
|
21
|
+
}
|
|
22
|
+
var GLOBAL = /^(Date|RegExp|Error|Map|Set|WeakMap|WeakSet|Promise|PromiseLike|Record|Partial|Required|Readonly|Pick|Omit|URL|URLSearchParams|Blob|File|FormData|Headers|AbortSignal|EventTarget|Node|Element|Document|DocumentFragment|ShadowRoot|Window|(HTML|SVG)\w*Element|\w*Event)$/;
|
|
23
|
+
var IDENT = /^[A-Za-z_$][\w$]*$/;
|
|
24
|
+
var Unsupported = class extends Error {
|
|
25
|
+
};
|
|
26
|
+
var unsupported = () => {
|
|
27
|
+
throw new Unsupported();
|
|
28
|
+
};
|
|
29
|
+
function propsFromOxc(ts, oxc, file) {
|
|
30
|
+
try {
|
|
31
|
+
const reader = new Reader(ts, oxc);
|
|
32
|
+
const scope = reader.scope(file);
|
|
33
|
+
const props = reader.defaultProps(scope);
|
|
34
|
+
return props ? reader.print(props.node, props.scope, 0, { top: true }) : "Record<string, unknown>";
|
|
35
|
+
} catch {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var Reader = class {
|
|
40
|
+
constructor(ts, oxc) {
|
|
41
|
+
this.ts = ts;
|
|
42
|
+
this.oxc = oxc;
|
|
43
|
+
this.scopes = /* @__PURE__ */ new Map();
|
|
44
|
+
this.seen = /* @__PURE__ */ new Set();
|
|
45
|
+
}
|
|
46
|
+
/** Declarações de um arquivo: `.d.ts` como está, o resto pelo Oxc. */
|
|
47
|
+
scope(file) {
|
|
48
|
+
const cached = this.scopes.get(file);
|
|
49
|
+
if (cached) return cached;
|
|
50
|
+
const { ts } = this;
|
|
51
|
+
let code = readFileSync(file, "utf8");
|
|
52
|
+
if (!/\.d\.[cm]?ts$/.test(file)) {
|
|
53
|
+
const out = this.oxc.isolatedDeclarationSync(file, code, {});
|
|
54
|
+
if (out.errors.length) unsupported();
|
|
55
|
+
code = out.code;
|
|
56
|
+
}
|
|
57
|
+
const source = ts.createSourceFile(file + ".d.ts", code, ts.ScriptTarget.Latest, true, ts.ScriptKind.TS);
|
|
58
|
+
const scope = { file, types: /* @__PURE__ */ new Map(), values: /* @__PURE__ */ new Map(), imports: /* @__PURE__ */ new Map() };
|
|
59
|
+
const isDefault = (n) => ts.canHaveModifiers(n) && !!ts.getModifiers(n)?.some((m) => m.kind === ts.SyntaxKind.DefaultKeyword);
|
|
60
|
+
let defaultName;
|
|
61
|
+
for (const st of source.statements) {
|
|
62
|
+
if (ts.isInterfaceDeclaration(st) || ts.isTypeAliasDeclaration(st)) {
|
|
63
|
+
if (scope.types.has(st.name.text)) unsupported();
|
|
64
|
+
scope.types.set(st.name.text, st);
|
|
65
|
+
} else if (ts.isImportDeclaration(st) && ts.isStringLiteral(st.moduleSpecifier)) {
|
|
66
|
+
const from = st.moduleSpecifier.text;
|
|
67
|
+
const clause = st.importClause;
|
|
68
|
+
if (clause?.name) scope.imports.set(clause.name.text, { from, name: "default" });
|
|
69
|
+
const bindings = clause?.namedBindings;
|
|
70
|
+
if (bindings && ts.isNamespaceImport(bindings)) scope.imports.set(bindings.name.text, { from, name: "*" });
|
|
71
|
+
if (bindings && ts.isNamedImports(bindings)) for (const el of bindings.elements) scope.imports.set(el.name.text, { from, name: (el.propertyName ?? el.name).text });
|
|
72
|
+
} else if (ts.isFunctionDeclaration(st) || ts.isClassDeclaration(st)) {
|
|
73
|
+
if (isDefault(st)) scope.default ??= st;
|
|
74
|
+
else if (st.name && !scope.values.has(st.name.text)) scope.values.set(st.name.text, st);
|
|
75
|
+
} else if (ts.isVariableStatement(st)) {
|
|
76
|
+
for (const d of st.declarationList.declarations) if (ts.isIdentifier(d.name)) scope.values.set(d.name.text, d);
|
|
77
|
+
} else if (ts.isExportAssignment(st) && !st.isExportEquals) {
|
|
78
|
+
defaultName = ts.isIdentifier(st.expression) ? st.expression.text : unsupported();
|
|
79
|
+
} else if (ts.isExportDeclaration(st) && !st.moduleSpecifier && st.exportClause && ts.isNamedExports(st.exportClause)) {
|
|
80
|
+
const el = st.exportClause.elements.find((e) => e.name.text === "default");
|
|
81
|
+
if (el) defaultName = (el.propertyName ?? el.name).text;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (defaultName) scope.default = scope.values.get(defaultName);
|
|
85
|
+
this.scopes.set(file, scope);
|
|
86
|
+
return scope;
|
|
87
|
+
}
|
|
88
|
+
/** `mount(el, props)`, componente-função `(props)` ou classe com `props`. `undefined`: sem props. */
|
|
89
|
+
defaultProps(scope) {
|
|
90
|
+
const { ts } = this;
|
|
91
|
+
const node = scope.default ?? unsupported();
|
|
92
|
+
const param = (params, i) => {
|
|
93
|
+
const p = params[i];
|
|
94
|
+
return p && { node: p.type ?? unsupported(), scope };
|
|
95
|
+
};
|
|
96
|
+
if (ts.isFunctionDeclaration(node)) return param(node.parameters, 0);
|
|
97
|
+
if (ts.isClassDeclaration(node)) {
|
|
98
|
+
if (node.heritageClauses?.length) unsupported();
|
|
99
|
+
const props = node.members.find((m) => ts.isPropertyDeclaration(m) && m.name.getText() === "props");
|
|
100
|
+
return props && { node: props.type ?? unsupported(), scope };
|
|
101
|
+
}
|
|
102
|
+
if (ts.isVariableDeclaration(node)) return this.propsOfType(node.type ?? unsupported(), scope);
|
|
103
|
+
return unsupported();
|
|
104
|
+
}
|
|
105
|
+
propsOfType(node, scope) {
|
|
106
|
+
const { ts } = this;
|
|
107
|
+
const param = (params, i, at2) => {
|
|
108
|
+
const p = params[i];
|
|
109
|
+
return p && { node: p.type ?? unsupported(), scope: at2 };
|
|
110
|
+
};
|
|
111
|
+
if (ts.isParenthesizedTypeNode(node)) return this.propsOfType(node.type, scope);
|
|
112
|
+
if (ts.isFunctionTypeNode(node)) return param(node.parameters, 0, scope);
|
|
113
|
+
let members;
|
|
114
|
+
let at = scope;
|
|
115
|
+
if (ts.isTypeLiteralNode(node)) members = node.members;
|
|
116
|
+
else if (ts.isTypeReferenceNode(node) && ts.isIdentifier(node.typeName) && !node.typeArguments) {
|
|
117
|
+
const found = this.lookup(node.typeName.text, scope);
|
|
118
|
+
if (!found || found === "package" || found.decl.typeParameters) return unsupported();
|
|
119
|
+
if (ts.isTypeAliasDeclaration(found.decl)) return this.propsOfType(found.decl.type, found.scope);
|
|
120
|
+
if (found.decl.heritageClauses?.length) unsupported();
|
|
121
|
+
members = found.decl.members;
|
|
122
|
+
at = found.scope;
|
|
123
|
+
} else return unsupported();
|
|
124
|
+
const mount = members.find((m) => m.name?.getText() === "mount");
|
|
125
|
+
if (mount) {
|
|
126
|
+
if (ts.isMethodSignature(mount)) return param(mount.parameters, 1, at);
|
|
127
|
+
if (ts.isPropertySignature(mount) && mount.type) return this.mountProps(mount.type, at);
|
|
128
|
+
return unsupported();
|
|
129
|
+
}
|
|
130
|
+
const call = members.find(ts.isCallSignatureDeclaration);
|
|
131
|
+
if (call) return param(call.parameters, 0, at);
|
|
132
|
+
if (members.some(ts.isConstructSignatureDeclaration)) unsupported();
|
|
133
|
+
return void 0;
|
|
134
|
+
}
|
|
135
|
+
mountProps(node, scope) {
|
|
136
|
+
const { ts } = this;
|
|
137
|
+
if (ts.isParenthesizedTypeNode(node)) return this.mountProps(node.type, scope);
|
|
138
|
+
if (!ts.isFunctionTypeNode(node)) return unsupported();
|
|
139
|
+
const p = node.parameters[1];
|
|
140
|
+
return p && { node: p.type ?? unsupported(), scope };
|
|
141
|
+
}
|
|
142
|
+
/** Acha um tipo pelo nome: no arquivo, num import relativo ou num pacote. */
|
|
143
|
+
lookup(name, scope) {
|
|
144
|
+
const decl = scope.types.get(name);
|
|
145
|
+
if (decl) return { decl, scope };
|
|
146
|
+
const imp = scope.imports.get(name);
|
|
147
|
+
if (!imp) return void 0;
|
|
148
|
+
if (!imp.from.startsWith(".")) return "package";
|
|
149
|
+
if (imp.name === "default" || imp.name === "*") return unsupported();
|
|
150
|
+
const found = this.lookup(imp.name, this.scope(resolveFile(scope.file, imp.from)));
|
|
151
|
+
return found ?? unsupported();
|
|
152
|
+
}
|
|
153
|
+
print(node, scope, depth, opts = {}) {
|
|
154
|
+
const { ts } = this;
|
|
155
|
+
const K = ts.SyntaxKind;
|
|
156
|
+
switch (node.kind) {
|
|
157
|
+
case K.AnyKeyword:
|
|
158
|
+
case K.UnknownKeyword:
|
|
159
|
+
return "unknown";
|
|
160
|
+
case K.StringKeyword:
|
|
161
|
+
case K.NumberKeyword:
|
|
162
|
+
case K.BooleanKeyword:
|
|
163
|
+
case K.BigIntKeyword:
|
|
164
|
+
case K.SymbolKeyword:
|
|
165
|
+
case K.UndefinedKeyword:
|
|
166
|
+
case K.VoidKeyword:
|
|
167
|
+
case K.NeverKeyword:
|
|
168
|
+
return node.getText();
|
|
169
|
+
}
|
|
170
|
+
if (ts.isLiteralTypeNode(node)) {
|
|
171
|
+
const lit = node.literal;
|
|
172
|
+
if (ts.isStringLiteral(lit)) return JSON.stringify(lit.text);
|
|
173
|
+
if (lit.kind === K.NullKeyword || lit.kind === K.TrueKeyword || lit.kind === K.FalseKeyword || ts.isNumericLiteral(lit) || ts.isPrefixUnaryExpression(lit)) return lit.getText();
|
|
174
|
+
return unsupported();
|
|
175
|
+
}
|
|
176
|
+
if (ts.isParenthesizedTypeNode(node)) return this.print(node.type, scope, depth, opts);
|
|
177
|
+
if (ts.isUnionTypeNode(node)) {
|
|
178
|
+
const types = opts.nonNull ? node.types.filter((t) => t.kind !== K.UndefinedKeyword && !(ts.isLiteralTypeNode(t) && t.literal.kind === K.NullKeyword)) : node.types;
|
|
179
|
+
const parts = [...new Set(types.map((t) => this.print(t, scope, depth)))];
|
|
180
|
+
if (parts.includes("true") && parts.includes("false")) parts.splice(parts.indexOf("true"), 1, "boolean"), parts.splice(parts.indexOf("false"), 1);
|
|
181
|
+
return parts.join(" | ");
|
|
182
|
+
}
|
|
183
|
+
if (ts.isIntersectionTypeNode(node)) {
|
|
184
|
+
return node.types.map((t) => {
|
|
185
|
+
const s = this.print(t, scope, depth);
|
|
186
|
+
return ts.isUnionTypeNode(t) ? `(${s})` : s;
|
|
187
|
+
}).join(" & ");
|
|
188
|
+
}
|
|
189
|
+
if (depth > 6) return "unknown";
|
|
190
|
+
if (ts.isArrayTypeNode(node)) return `Array<${this.print(node.elementType, scope, depth + 1)}>`;
|
|
191
|
+
if (ts.isTypeOperatorNode(node) && node.operator === K.ReadonlyKeyword && (ts.isArrayTypeNode(node.type) || ts.isTupleTypeNode(node.type))) return this.print(node.type, scope, depth);
|
|
192
|
+
if (ts.isTupleTypeNode(node)) {
|
|
193
|
+
if (node.elements.some((e) => ts.isNamedTupleMember(e) || ts.isOptionalTypeNode(e) || ts.isRestTypeNode(e))) unsupported();
|
|
194
|
+
return `[${node.elements.map((e) => this.print(e, scope, depth + 1)).join(", ")}]`;
|
|
195
|
+
}
|
|
196
|
+
if (ts.isTypeLiteralNode(node)) return this.object(node.members, scope, depth, !!opts.top);
|
|
197
|
+
if (ts.isFunctionTypeNode(node)) return this.signature(node, scope, depth);
|
|
198
|
+
if (ts.isTypeReferenceNode(node)) return this.reference(node, scope, depth, opts);
|
|
199
|
+
return unsupported();
|
|
200
|
+
}
|
|
201
|
+
reference(node, scope, depth, opts) {
|
|
202
|
+
const { ts } = this;
|
|
203
|
+
if (!ts.isIdentifier(node.typeName)) return unsupported();
|
|
204
|
+
const name = node.typeName.text;
|
|
205
|
+
const args = node.typeArguments ?? [];
|
|
206
|
+
const found = this.lookup(name, scope);
|
|
207
|
+
if (found === "package") return "unknown";
|
|
208
|
+
if (found) {
|
|
209
|
+
if (args.length || found.decl.typeParameters) unsupported();
|
|
210
|
+
if (this.seen.has(found.decl)) return "unknown";
|
|
211
|
+
this.seen.add(found.decl);
|
|
212
|
+
try {
|
|
213
|
+
const decl = found.decl;
|
|
214
|
+
if (ts.isTypeAliasDeclaration(decl)) return this.print(decl.type, found.scope, depth, opts);
|
|
215
|
+
if (decl.heritageClauses?.length) unsupported();
|
|
216
|
+
return this.object(decl.members, found.scope, depth, !!opts.top);
|
|
217
|
+
} finally {
|
|
218
|
+
this.seen.delete(found.decl);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
if ((name === "Array" || name === "ReadonlyArray") && args.length === 1) return `Array<${this.print(args[0], scope, depth + 1)}>`;
|
|
222
|
+
if (!GLOBAL.test(name)) return unsupported();
|
|
223
|
+
return args.length ? `${name}<${args.map((t) => this.print(t, scope, depth + 1)).join(", ")}>` : name;
|
|
224
|
+
}
|
|
225
|
+
object(members, scope, depth, top) {
|
|
226
|
+
const { ts } = this;
|
|
227
|
+
const fields = [];
|
|
228
|
+
const calls = [];
|
|
229
|
+
let index;
|
|
230
|
+
for (const m of members) {
|
|
231
|
+
if (ts.isPropertySignature(m) || ts.isMethodSignature(m)) {
|
|
232
|
+
const name = ts.isIdentifier(m.name) || ts.isStringLiteral(m.name) || ts.isNumericLiteral(m.name) ? m.name.text : unsupported();
|
|
233
|
+
if (top && name === "vitral") continue;
|
|
234
|
+
const optional = m.questionToken ? "?" : "";
|
|
235
|
+
const key = IDENT.test(name) ? name : JSON.stringify(name);
|
|
236
|
+
const type = ts.isMethodSignature(m) ? this.signature(m, scope, depth + 1) : m.type ? this.print(m.type, scope, depth + 1, { nonNull: !!optional }) : "unknown";
|
|
237
|
+
fields.push(`${key}${optional}: ${type}`);
|
|
238
|
+
} else if (ts.isIndexSignatureDeclaration(m)) {
|
|
239
|
+
const key = m.parameters[0]?.type;
|
|
240
|
+
if (!key || key.kind !== ts.SyntaxKind.StringKeyword) unsupported();
|
|
241
|
+
index = `[key: string]: ${this.print(m.type, scope, depth + 1)}`;
|
|
242
|
+
} else if (ts.isCallSignatureDeclaration(m)) {
|
|
243
|
+
calls.push(this.signature(m, scope, depth));
|
|
244
|
+
} else unsupported();
|
|
245
|
+
}
|
|
246
|
+
if (calls.length && !fields.length) return calls[0];
|
|
247
|
+
if (index) fields.push(index);
|
|
248
|
+
for (const c of calls) fields.push(c.replace(" =>", ":"));
|
|
249
|
+
return fields.length ? `{ ${fields.join("; ")} }` : "{}";
|
|
250
|
+
}
|
|
251
|
+
signature(sig, scope, depth) {
|
|
252
|
+
const { ts } = this;
|
|
253
|
+
if (sig.typeParameters?.length || !sig.type) unsupported();
|
|
254
|
+
const params = sig.parameters.map((p, i) => {
|
|
255
|
+
if (p.dotDotDotToken || ts.isIdentifier(p.name) && p.name.text === "this") unsupported();
|
|
256
|
+
const name = ts.isIdentifier(p.name) && IDENT.test(p.name.text) ? p.name.text : `a${i}`;
|
|
257
|
+
const type = p.type ? this.print(p.type, scope, depth + 1) : "unknown";
|
|
258
|
+
return `${name}: ${p.questionToken || p.initializer ? `${type} | undefined` : type}`;
|
|
259
|
+
});
|
|
260
|
+
return `(${params.join(", ")}) => ${this.print(sig.type, scope, depth + 1)}`;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
function resolveFile(from, spec) {
|
|
264
|
+
const base = resolve(dirname(from), spec);
|
|
265
|
+
const stem = base.replace(/\.[cm]?jsx?$/, "");
|
|
266
|
+
const candidates = [base, ...[".ts", ".tsx", ".mts", ".cts", ".d.ts"].map((ext) => stem + ext), ...["index.ts", "index.tsx", "index.d.ts"].map((f) => join(base, f))];
|
|
267
|
+
const file = candidates.find((f) => /\.[cm]?tsx?$/.test(f) && existsSync(f));
|
|
268
|
+
return file ?? unsupported();
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// src/vite/types.ts
|
|
272
|
+
function typesFile(name, props) {
|
|
273
|
+
return `// Props do remote ${JSON.stringify(name)}, geradas pelo vitral. N\xE3o edite.
|
|
274
|
+
export type Props = ${props}
|
|
275
|
+
`;
|
|
276
|
+
}
|
|
277
|
+
async function loadTs(root) {
|
|
278
|
+
const api = (ts) => typeof ts?.createProgram === "function" ? ts : null;
|
|
279
|
+
try {
|
|
280
|
+
const ts = api(createRequire2(join2(root, "package.json"))("typescript"));
|
|
281
|
+
if (ts) return ts;
|
|
282
|
+
} catch {
|
|
283
|
+
}
|
|
284
|
+
try {
|
|
285
|
+
return api((await import("typescript")).default);
|
|
286
|
+
} catch {
|
|
287
|
+
return null;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
async function extractProps(root, file) {
|
|
291
|
+
if (!/\.[cm]?[jt]sx?$/.test(file)) return null;
|
|
292
|
+
const ts = await loadTs(root);
|
|
293
|
+
if (!ts) return null;
|
|
294
|
+
const oxc = /\.[cm]?tsx?$/.test(file) ? await loadOxc(root) : null;
|
|
295
|
+
const fast = oxc && propsFromOxc(ts, oxc, file);
|
|
296
|
+
if (fast) return fast;
|
|
297
|
+
const configPath = ts.findConfigFile(root, ts.sys.fileExists);
|
|
298
|
+
const base = configPath ? ts.parseJsonConfigFileContent(ts.readConfigFile(configPath, ts.sys.readFile).config, ts.sys, root).options : {};
|
|
299
|
+
const options = {
|
|
300
|
+
target: ts.ScriptTarget.ES2022,
|
|
301
|
+
module: ts.ModuleKind.ESNext,
|
|
302
|
+
moduleResolution: ts.ModuleResolutionKind.Bundler,
|
|
303
|
+
jsx: ts.JsxEmit.Preserve,
|
|
304
|
+
strict: true,
|
|
305
|
+
...base,
|
|
306
|
+
allowJs: true,
|
|
307
|
+
skipLibCheck: true,
|
|
308
|
+
noEmit: true
|
|
309
|
+
};
|
|
310
|
+
const program = ts.createProgram([file], options);
|
|
311
|
+
const checker = program.getTypeChecker();
|
|
312
|
+
const source = program.getSourceFile(file);
|
|
313
|
+
const moduleSymbol = source && checker.getSymbolAtLocation(source);
|
|
314
|
+
let symbol = moduleSymbol && checker.getExportsOfModule(moduleSymbol).find((s) => s.escapedName === "default");
|
|
315
|
+
if (!source || !symbol) return null;
|
|
316
|
+
if (symbol.flags & ts.SymbolFlags.Alias) symbol = checker.getAliasedSymbol(symbol);
|
|
317
|
+
const type = checker.getTypeOfSymbolAtLocation(symbol, source);
|
|
318
|
+
const props = propsOf(checker, type, source);
|
|
319
|
+
return props ? new Printer(ts, checker, program).print(props, 0, true) : "Record<string, unknown>";
|
|
320
|
+
}
|
|
321
|
+
function propsOf(checker, type, at) {
|
|
322
|
+
const param = (t, i) => {
|
|
323
|
+
const p = t.getCallSignatures()[0]?.parameters[i];
|
|
324
|
+
return p && checker.getTypeOfSymbolAtLocation(p, at);
|
|
325
|
+
};
|
|
326
|
+
const mount = type.getProperty("mount");
|
|
327
|
+
if (mount) return param(checker.getTypeOfSymbolAtLocation(mount, at), 1);
|
|
328
|
+
if (type.getCallSignatures().length) return param(type, 0);
|
|
329
|
+
const ctor = type.getConstructSignatures()[0];
|
|
330
|
+
const props = ctor?.getReturnType().getProperty("props");
|
|
331
|
+
return props && checker.getTypeOfSymbolAtLocation(props, at);
|
|
332
|
+
}
|
|
333
|
+
var Printer = class {
|
|
334
|
+
constructor(ts, checker, program) {
|
|
335
|
+
this.ts = ts;
|
|
336
|
+
this.checker = checker;
|
|
337
|
+
this.program = program;
|
|
338
|
+
this.seen = /* @__PURE__ */ new Set();
|
|
339
|
+
}
|
|
340
|
+
/** Declarado na lib padrão (Date, Map…): vale em qualquer projeto pelo nome. */
|
|
341
|
+
fromLib(type) {
|
|
342
|
+
const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
|
|
343
|
+
return !!decl && this.program.isSourceFileDefaultLibrary(decl.getSourceFile());
|
|
344
|
+
}
|
|
345
|
+
fromPackage(type) {
|
|
346
|
+
const decl = (type.aliasSymbol ?? type.getSymbol())?.declarations?.[0];
|
|
347
|
+
return !!decl && /[/\\]node_modules[/\\]/.test(decl.getSourceFile().fileName);
|
|
348
|
+
}
|
|
349
|
+
print(type, depth, top = false) {
|
|
350
|
+
const { ts, checker } = this;
|
|
351
|
+
const f = type.flags;
|
|
352
|
+
if (f & (ts.TypeFlags.Any | ts.TypeFlags.Unknown)) return "unknown";
|
|
353
|
+
if (f & (ts.TypeFlags.StringLike | ts.TypeFlags.NumberLike | ts.TypeFlags.BooleanLike | ts.TypeFlags.BigIntLike | ts.TypeFlags.Null | ts.TypeFlags.Undefined | ts.TypeFlags.Void | ts.TypeFlags.Never | ts.TypeFlags.ESSymbolLike)) {
|
|
354
|
+
return checker.typeToString(type);
|
|
355
|
+
}
|
|
356
|
+
if (type.isUnion()) {
|
|
357
|
+
const parts = [...new Set(type.types.map((t) => this.print(t, depth)))];
|
|
358
|
+
if (parts.includes("true") && parts.includes("false")) parts.splice(parts.indexOf("true"), 1, "boolean"), parts.splice(parts.indexOf("false"), 1);
|
|
359
|
+
return parts.join(" | ");
|
|
360
|
+
}
|
|
361
|
+
if (type.isIntersection()) return type.types.map((t) => this.wrap(t, depth)).join(" & ");
|
|
362
|
+
if (depth > 6 || this.seen.has(type)) return "unknown";
|
|
363
|
+
if (checker.isArrayType(type)) return `Array<${this.print(checker.getTypeArguments(type)[0], depth + 1)}>`;
|
|
364
|
+
if (checker.isTupleType(type)) return `[${checker.getTypeArguments(type).map((t) => this.print(t, depth + 1)).join(", ")}]`;
|
|
365
|
+
if (this.fromLib(type)) {
|
|
366
|
+
const args = type.aliasTypeArguments ?? (type.objectFlags & ts.ObjectFlags.Reference ? checker.getTypeArguments(type) : []);
|
|
367
|
+
const name = (type.aliasSymbol ?? type.getSymbol()).name;
|
|
368
|
+
return args.length ? `${name}<${args.map((t) => this.print(t, depth + 1)).join(", ")}>` : checker.typeToString(type);
|
|
369
|
+
}
|
|
370
|
+
if (this.fromPackage(type)) return "unknown";
|
|
371
|
+
this.seen.add(type);
|
|
372
|
+
try {
|
|
373
|
+
const calls = type.getCallSignatures();
|
|
374
|
+
const props = checker.getPropertiesOfType(type).filter((p) => !(top && p.name === "vitral"));
|
|
375
|
+
if (calls.length && !props.length) return this.signature(calls[0], depth);
|
|
376
|
+
const fields = props.map((p) => {
|
|
377
|
+
const optional = p.flags & ts.SymbolFlags.Optional ? "?" : "";
|
|
378
|
+
const key = /^[A-Za-z_$][\w$]*$/.test(p.name) ? p.name : JSON.stringify(p.name);
|
|
379
|
+
const t = checker.getTypeOfSymbol(p);
|
|
380
|
+
return `${key}${optional}: ${this.print(optional ? checker.getNonNullableType(t) : t, depth + 1)}`;
|
|
381
|
+
});
|
|
382
|
+
const index = type.getStringIndexType();
|
|
383
|
+
if (index) fields.push(`[key: string]: ${this.print(index, depth + 1)}`);
|
|
384
|
+
for (const c of calls) fields.push(this.signature(c, depth).replace(" =>", ":"));
|
|
385
|
+
return fields.length ? `{ ${fields.join("; ")} }` : "{}";
|
|
386
|
+
} finally {
|
|
387
|
+
this.seen.delete(type);
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
wrap(type, depth) {
|
|
391
|
+
const s = this.print(type, depth);
|
|
392
|
+
return type.isUnion() ? `(${s})` : s;
|
|
393
|
+
}
|
|
394
|
+
signature(sig, depth) {
|
|
395
|
+
const params = sig.parameters.map((p, i) => `${/^[A-Za-z_$][\w$]*$/.test(p.name) ? p.name : `a${i}`}: ${this.print(this.checker.getTypeOfSymbol(p), depth + 1)}`);
|
|
396
|
+
return `(${params.join(", ")}) => ${this.print(sig.getReturnType(), depth + 1)}`;
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
|
|
400
|
+
export {
|
|
401
|
+
typesFile,
|
|
402
|
+
loadTs,
|
|
403
|
+
extractProps
|
|
404
|
+
};
|