svelte-origin 1.0.0-next.20 → 1.0.0-next.22
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.
Potentially problematic release.
This version of svelte-origin might be problematic. Click here for more details.
- package/dist/aliases.d.ts +1 -0
- package/dist/cli.js +194 -2
- package/dist/index.js +194 -2
- package/dist/plugin.js +379 -2
- package/dist/post-process.js +194 -2
- package/dist/preprocess.js +384 -2
- package/dist/transform/schema.d.ts +17 -0
- package/dist/vite-dts.js +174 -1
- package/package.json +1 -1
package/dist/preprocess.js
CHANGED
|
@@ -1969,6 +1969,7 @@ function transformOriginDefinition(content, svelteImports) {
|
|
|
1969
1969
|
let attrsContent = "";
|
|
1970
1970
|
let contentWithoutAttrs = bodyContent;
|
|
1971
1971
|
let attrPropertyName = "props";
|
|
1972
|
+
let propsRef = null;
|
|
1972
1973
|
if (attrsMatch) {
|
|
1973
1974
|
attrPropertyName = attrsMatch[1];
|
|
1974
1975
|
const attrsStart = attrsMatch.index;
|
|
@@ -1999,13 +2000,31 @@ function transformOriginDefinition(content, svelteImports) {
|
|
|
1999
2000
|
}
|
|
2000
2001
|
contentWithoutAttrs = bodyContent.slice(0, attrsStart) + bodyContent.slice(cutEnd);
|
|
2001
2002
|
}
|
|
2003
|
+
} else {
|
|
2004
|
+
const externalRefMatch = bodyContent.match(/(\w+)\s*:\s*(\w+)\s*,/);
|
|
2005
|
+
if (externalRefMatch) {
|
|
2006
|
+
const propName = externalRefMatch[1];
|
|
2007
|
+
const refName = externalRefMatch[2];
|
|
2008
|
+
if ((propName === "props" || propName === "attrs") && /^[A-Z]/.test(refName) && !["$state", "$derived", "$effect", "$bindable"].includes(refName)) {
|
|
2009
|
+
attrPropertyName = propName;
|
|
2010
|
+
propsRef = refName;
|
|
2011
|
+
const refStart = externalRefMatch.index;
|
|
2012
|
+
const refEnd = refStart + externalRefMatch[0].length;
|
|
2013
|
+
contentWithoutAttrs = bodyContent.slice(0, refStart) + bodyContent.slice(refEnd);
|
|
2014
|
+
}
|
|
2015
|
+
}
|
|
2002
2016
|
}
|
|
2003
2017
|
const attrDetails = parseAttrsSource(attrsContent);
|
|
2004
2018
|
const { body: createFnBody, attachments } = transformOriginBody(contentWithoutAttrs.trim(), parents, attrDetails, attrPropertyName, svelteImports);
|
|
2005
2019
|
const parentsCode = parents.length > 0 ? `[${parents.join(", ")}]` : "undefined";
|
|
2006
2020
|
let configCode = `{
|
|
2007
2021
|
__attrSchema: ${attrSchemaCode},
|
|
2008
|
-
__parents: ${parentsCode}
|
|
2022
|
+
__parents: ${parentsCode},`;
|
|
2023
|
+
if (propsRef) {
|
|
2024
|
+
configCode += `
|
|
2025
|
+
__propsRef: ${propsRef},`;
|
|
2026
|
+
}
|
|
2027
|
+
configCode += `
|
|
2009
2028
|
__create: (__inputAttrs${parents.length > 0 ? ", __super" : ""}) => {
|
|
2010
2029
|
${createFnBody}
|
|
2011
2030
|
}`;
|
|
@@ -2232,7 +2251,83 @@ function transformStandaloneAttrsDefinition(content) {
|
|
|
2232
2251
|
|
|
2233
2252
|
// src/transform/schema.ts
|
|
2234
2253
|
function parseOriginSchemaFromSource(source, exportName) {
|
|
2235
|
-
const
|
|
2254
|
+
const sourceResult = parseSourceOrigin(source, exportName);
|
|
2255
|
+
if (sourceResult)
|
|
2256
|
+
return sourceResult;
|
|
2257
|
+
const compiledResult = parseCompiledOrigin(source, exportName);
|
|
2258
|
+
if (compiledResult)
|
|
2259
|
+
return compiledResult;
|
|
2260
|
+
return null;
|
|
2261
|
+
}
|
|
2262
|
+
function parseAttrsSchemaFromSource(source, exportName) {
|
|
2263
|
+
const sourceResult = parseSourceAttrs(source, exportName);
|
|
2264
|
+
if (sourceResult)
|
|
2265
|
+
return sourceResult;
|
|
2266
|
+
const compiledResult = parseCompiledAttrs(source, exportName);
|
|
2267
|
+
if (compiledResult)
|
|
2268
|
+
return compiledResult;
|
|
2269
|
+
return null;
|
|
2270
|
+
}
|
|
2271
|
+
function parseSourceAttrs(source, exportName) {
|
|
2272
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*\\$attrs\\s*\\(`, "s");
|
|
2273
|
+
const match = exportPattern.exec(source);
|
|
2274
|
+
if (!match)
|
|
2275
|
+
return null;
|
|
2276
|
+
const attrsStart = match.index + match[0].length - 1;
|
|
2277
|
+
const attrsEnd = findMatchingBracket(source, attrsStart);
|
|
2278
|
+
if (attrsEnd === -1)
|
|
2279
|
+
return null;
|
|
2280
|
+
let attrsContent = source.slice(attrsStart + 1, attrsEnd).trim();
|
|
2281
|
+
let parentNames = [];
|
|
2282
|
+
if (attrsContent.startsWith("[")) {
|
|
2283
|
+
const closeBracket = findMatchingBracket(attrsContent, 0, "[", "]");
|
|
2284
|
+
if (closeBracket !== -1) {
|
|
2285
|
+
const parentsContent = attrsContent.slice(1, closeBracket);
|
|
2286
|
+
parentNames = parentsContent.split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
2287
|
+
let i = closeBracket + 1;
|
|
2288
|
+
while (i < attrsContent.length && /[\s,]/.test(attrsContent[i]))
|
|
2289
|
+
i++;
|
|
2290
|
+
attrsContent = attrsContent.slice(i);
|
|
2291
|
+
}
|
|
2292
|
+
}
|
|
2293
|
+
if (!attrsContent.startsWith("{")) {
|
|
2294
|
+
return { attrs: [], parentNames };
|
|
2295
|
+
}
|
|
2296
|
+
const objEnd = findMatchingBracket(attrsContent, 0, "{", "}");
|
|
2297
|
+
if (objEnd === -1)
|
|
2298
|
+
return { attrs: [], parentNames };
|
|
2299
|
+
const objContent = attrsContent.slice(1, objEnd);
|
|
2300
|
+
const attrs = parseAttrsContent(objContent);
|
|
2301
|
+
return { attrs, parentNames };
|
|
2302
|
+
}
|
|
2303
|
+
function parseCompiledAttrs(source, exportName) {
|
|
2304
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*__createAttrs\\s*\\(\\s*\\{`, "s");
|
|
2305
|
+
const match = exportPattern.exec(source);
|
|
2306
|
+
if (!match)
|
|
2307
|
+
return null;
|
|
2308
|
+
const braceStart = match.index + match[0].length - 1;
|
|
2309
|
+
const braceEnd = findMatchingBracket(source, braceStart, "{", "}");
|
|
2310
|
+
if (braceEnd === -1)
|
|
2311
|
+
return null;
|
|
2312
|
+
const configContent = source.slice(braceStart + 1, braceEnd);
|
|
2313
|
+
const schemaMatch = configContent.match(/__attrSchema\s*:\s*\{/);
|
|
2314
|
+
if (!schemaMatch)
|
|
2315
|
+
return { attrs: [], parentNames: [] };
|
|
2316
|
+
const schemaStart = schemaMatch.index + schemaMatch[0].length - 1;
|
|
2317
|
+
const schemaEnd = findMatchingBracket(configContent, schemaStart, "{", "}");
|
|
2318
|
+
if (schemaEnd === -1)
|
|
2319
|
+
return { attrs: [], parentNames: [] };
|
|
2320
|
+
const schemaContent = configContent.slice(schemaStart + 1, schemaEnd);
|
|
2321
|
+
const attrs = parseCompiledAttrSchema(schemaContent);
|
|
2322
|
+
const parentsMatch = configContent.match(/__parents\s*:\s*\[([^\]]*)\]/);
|
|
2323
|
+
let parentNames = [];
|
|
2324
|
+
if (parentsMatch && parentsMatch[1].trim()) {
|
|
2325
|
+
parentNames = parentsMatch[1].split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
2326
|
+
}
|
|
2327
|
+
return { attrs, parentNames };
|
|
2328
|
+
}
|
|
2329
|
+
function parseSourceOrigin(source, exportName) {
|
|
2330
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*\\$origin\\s*\\(`, "s");
|
|
2236
2331
|
const match = exportPattern.exec(source);
|
|
2237
2332
|
if (!match)
|
|
2238
2333
|
return null;
|
|
@@ -2256,6 +2351,13 @@ function parseOriginSchemaFromSource(source, exportName) {
|
|
|
2256
2351
|
}
|
|
2257
2352
|
const attrsMatch = bodyContent.match(/(\w+)\s*:\s*\$attrs\s*\(\s*\{/);
|
|
2258
2353
|
if (!attrsMatch) {
|
|
2354
|
+
const externalRefMatch = bodyContent.match(/(?:props|attrs)\s*:\s*([A-Z]\w*)\b/);
|
|
2355
|
+
if (externalRefMatch) {
|
|
2356
|
+
const propsRef = externalRefMatch[1];
|
|
2357
|
+
if (!["Object", "Array", "String", "Number", "Boolean"].includes(propsRef)) {
|
|
2358
|
+
return { attrs: [], parentNames, propsRef };
|
|
2359
|
+
}
|
|
2360
|
+
}
|
|
2259
2361
|
return { attrs: [], parentNames };
|
|
2260
2362
|
}
|
|
2261
2363
|
const attrsStart = attrsMatch.index;
|
|
@@ -2268,6 +2370,96 @@ function parseOriginSchemaFromSource(source, exportName) {
|
|
|
2268
2370
|
const attrs = parseAttrsContent(attrsContent);
|
|
2269
2371
|
return { attrs, parentNames };
|
|
2270
2372
|
}
|
|
2373
|
+
function parseCompiledOrigin(source, exportName) {
|
|
2374
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*__createOrigin\\s*\\(\\s*\\{`, "s");
|
|
2375
|
+
const match = exportPattern.exec(source);
|
|
2376
|
+
if (!match)
|
|
2377
|
+
return null;
|
|
2378
|
+
const braceStart = match.index + match[0].length - 1;
|
|
2379
|
+
const braceEnd = findMatchingBracket(source, braceStart, "{", "}");
|
|
2380
|
+
if (braceEnd === -1)
|
|
2381
|
+
return null;
|
|
2382
|
+
const configContent = source.slice(braceStart + 1, braceEnd);
|
|
2383
|
+
const schemaMatch = configContent.match(/__attrSchema\s*:\s*\{/);
|
|
2384
|
+
if (!schemaMatch)
|
|
2385
|
+
return { attrs: [], parentNames: [] };
|
|
2386
|
+
const schemaStart = schemaMatch.index + schemaMatch[0].length - 1;
|
|
2387
|
+
const schemaEnd = findMatchingBracket(configContent, schemaStart, "{", "}");
|
|
2388
|
+
if (schemaEnd === -1)
|
|
2389
|
+
return { attrs: [], parentNames: [] };
|
|
2390
|
+
const schemaContent = configContent.slice(schemaStart + 1, schemaEnd);
|
|
2391
|
+
const attrs = parseCompiledAttrSchema(schemaContent);
|
|
2392
|
+
const parentsMatch = configContent.match(/__parents\s*:\s*\[([^\]]*)\]/);
|
|
2393
|
+
let parentNames = [];
|
|
2394
|
+
if (parentsMatch && parentsMatch[1].trim()) {
|
|
2395
|
+
parentNames = parentsMatch[1].split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
2396
|
+
}
|
|
2397
|
+
const propsRefMatch = configContent.match(/__propsRef\s*:\s*(\w+)/);
|
|
2398
|
+
const propsRef = propsRefMatch ? propsRefMatch[1] : undefined;
|
|
2399
|
+
return { attrs, parentNames, propsRef };
|
|
2400
|
+
}
|
|
2401
|
+
function parseCompiledAttrSchema(content) {
|
|
2402
|
+
const result = [];
|
|
2403
|
+
let pos = 0;
|
|
2404
|
+
while (pos < content.length) {
|
|
2405
|
+
while (pos < content.length && /[\s,]/.test(content[pos]))
|
|
2406
|
+
pos++;
|
|
2407
|
+
if (pos >= content.length)
|
|
2408
|
+
break;
|
|
2409
|
+
if (content.slice(pos, pos + 2) === "/*") {
|
|
2410
|
+
const endComment = content.indexOf("*/", pos + 2);
|
|
2411
|
+
if (endComment !== -1) {
|
|
2412
|
+
pos = endComment + 2;
|
|
2413
|
+
continue;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
const keyMatch = content.slice(pos).match(/^(\w+)\s*:/);
|
|
2417
|
+
if (!keyMatch)
|
|
2418
|
+
break;
|
|
2419
|
+
const key = keyMatch[1];
|
|
2420
|
+
pos += keyMatch[0].length;
|
|
2421
|
+
while (pos < content.length && /\s/.test(content[pos]))
|
|
2422
|
+
pos++;
|
|
2423
|
+
if (content[pos] !== "{")
|
|
2424
|
+
break;
|
|
2425
|
+
const valueStart = pos;
|
|
2426
|
+
const valueEnd = findMatchingBracket(content, valueStart, "{", "}");
|
|
2427
|
+
if (valueEnd === -1)
|
|
2428
|
+
break;
|
|
2429
|
+
const valueContent = content.slice(valueStart + 1, valueEnd);
|
|
2430
|
+
let defaultValue = "undefined";
|
|
2431
|
+
let bindable = false;
|
|
2432
|
+
let hasDefault = false;
|
|
2433
|
+
const defaultMatch = valueContent.match(/\bdefault\s*:\s*/);
|
|
2434
|
+
if (defaultMatch) {
|
|
2435
|
+
const defaultStart = defaultMatch.index + defaultMatch[0].length;
|
|
2436
|
+
let depth = 0;
|
|
2437
|
+
let i = defaultStart;
|
|
2438
|
+
while (i < valueContent.length) {
|
|
2439
|
+
const char = valueContent[i];
|
|
2440
|
+
if (char === "{" || char === "(" || char === "[")
|
|
2441
|
+
depth++;
|
|
2442
|
+
else if (char === "}" || char === ")" || char === "]")
|
|
2443
|
+
depth--;
|
|
2444
|
+
else if (char === "," && depth === 0)
|
|
2445
|
+
break;
|
|
2446
|
+
i++;
|
|
2447
|
+
}
|
|
2448
|
+
defaultValue = valueContent.slice(defaultStart, i).trim();
|
|
2449
|
+
}
|
|
2450
|
+
const bindableMatch = valueContent.match(/\bbindable\s*:\s*(true|false)/);
|
|
2451
|
+
if (bindableMatch) {
|
|
2452
|
+
bindable = bindableMatch[1] === "true";
|
|
2453
|
+
}
|
|
2454
|
+
const hasDefaultMatch = valueContent.match(/\bhasDefault\s*:\s*(true|false)/);
|
|
2455
|
+
if (hasDefaultMatch) {
|
|
2456
|
+
hasDefault = hasDefaultMatch[1] === "true";
|
|
2457
|
+
}
|
|
2458
|
+
result.push({ key, defaultValue, bindable, hasDefault });
|
|
2459
|
+
pos = valueEnd + 1;
|
|
2460
|
+
}
|
|
2461
|
+
return result;
|
|
2462
|
+
}
|
|
2271
2463
|
function parseAttrsContent(content) {
|
|
2272
2464
|
const result = [];
|
|
2273
2465
|
const parts = splitByTopLevelCommas(content);
|
|
@@ -3162,6 +3354,108 @@ function resolveImportPath(importPath, aliases, importerDir) {
|
|
|
3162
3354
|
return join(aliasPath, remainder);
|
|
3163
3355
|
}
|
|
3164
3356
|
}
|
|
3357
|
+
const npmResolved = resolveNpmPackageImport(importPath, importerDir);
|
|
3358
|
+
if (npmResolved) {
|
|
3359
|
+
return npmResolved;
|
|
3360
|
+
}
|
|
3361
|
+
return null;
|
|
3362
|
+
}
|
|
3363
|
+
function resolveNpmPackageImport(importPath, importerDir) {
|
|
3364
|
+
if (importPath.startsWith(".") || importPath.startsWith("/") || /^[a-zA-Z]:/.test(importPath)) {
|
|
3365
|
+
return null;
|
|
3366
|
+
}
|
|
3367
|
+
let packageName;
|
|
3368
|
+
let subpath;
|
|
3369
|
+
if (importPath.startsWith("@")) {
|
|
3370
|
+
const parts = importPath.split("/");
|
|
3371
|
+
if (parts.length < 2)
|
|
3372
|
+
return null;
|
|
3373
|
+
packageName = `${parts[0]}/${parts[1]}`;
|
|
3374
|
+
subpath = parts.slice(2).join("/");
|
|
3375
|
+
} else {
|
|
3376
|
+
const slashIndex = importPath.indexOf("/");
|
|
3377
|
+
if (slashIndex === -1) {
|
|
3378
|
+
packageName = importPath;
|
|
3379
|
+
subpath = "";
|
|
3380
|
+
} else {
|
|
3381
|
+
packageName = importPath.slice(0, slashIndex);
|
|
3382
|
+
subpath = importPath.slice(slashIndex + 1);
|
|
3383
|
+
}
|
|
3384
|
+
}
|
|
3385
|
+
let currentDir = importerDir;
|
|
3386
|
+
const root = isAbsolute(importerDir) ? (importerDir.match(/^[a-zA-Z]:[/\\]/) || ["/"])[0] : "/";
|
|
3387
|
+
while (currentDir !== root && currentDir !== dirname(currentDir)) {
|
|
3388
|
+
const nodeModulesDir = join(currentDir, "node_modules");
|
|
3389
|
+
const packageDir = join(nodeModulesDir, packageName);
|
|
3390
|
+
if (existsSync(packageDir)) {
|
|
3391
|
+
const packageJsonPath = join(packageDir, "package.json");
|
|
3392
|
+
const exportKey = subpath ? `./${subpath}` : ".";
|
|
3393
|
+
if (existsSync(packageJsonPath)) {
|
|
3394
|
+
try {
|
|
3395
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
3396
|
+
if (packageJson.exports) {
|
|
3397
|
+
const resolvedExport = resolvePackageExports(packageJson.exports, exportKey);
|
|
3398
|
+
if (resolvedExport) {
|
|
3399
|
+
return join(packageDir, resolvedExport);
|
|
3400
|
+
}
|
|
3401
|
+
}
|
|
3402
|
+
if (!subpath) {
|
|
3403
|
+
const mainEntry = packageJson.module || packageJson.main || "index.js";
|
|
3404
|
+
return join(packageDir, mainEntry);
|
|
3405
|
+
}
|
|
3406
|
+
} catch {}
|
|
3407
|
+
}
|
|
3408
|
+
if (subpath) {
|
|
3409
|
+
const resolvedSubpath = join(packageDir, subpath);
|
|
3410
|
+
return resolvedSubpath;
|
|
3411
|
+
}
|
|
3412
|
+
return join(packageDir, "index.js");
|
|
3413
|
+
}
|
|
3414
|
+
currentDir = dirname(currentDir);
|
|
3415
|
+
}
|
|
3416
|
+
return null;
|
|
3417
|
+
}
|
|
3418
|
+
function resolvePackageExports(exports, subpath) {
|
|
3419
|
+
if (typeof exports === "string") {
|
|
3420
|
+
return subpath === "." ? exports : null;
|
|
3421
|
+
}
|
|
3422
|
+
if (typeof exports !== "object" || exports === null) {
|
|
3423
|
+
return null;
|
|
3424
|
+
}
|
|
3425
|
+
const exportEntry = exports[subpath];
|
|
3426
|
+
if (exportEntry) {
|
|
3427
|
+
return resolveExportCondition(exportEntry);
|
|
3428
|
+
}
|
|
3429
|
+
if (subpath === "." && exports["."]) {
|
|
3430
|
+
return resolveExportCondition(exports["."]);
|
|
3431
|
+
}
|
|
3432
|
+
if (subpath === ".") {
|
|
3433
|
+
const resolved = resolveExportCondition(exports);
|
|
3434
|
+
if (resolved)
|
|
3435
|
+
return resolved;
|
|
3436
|
+
}
|
|
3437
|
+
return null;
|
|
3438
|
+
}
|
|
3439
|
+
function resolveExportCondition(condition) {
|
|
3440
|
+
if (typeof condition === "string") {
|
|
3441
|
+
return condition;
|
|
3442
|
+
}
|
|
3443
|
+
if (typeof condition !== "object" || condition === null) {
|
|
3444
|
+
return null;
|
|
3445
|
+
}
|
|
3446
|
+
const condObj = condition;
|
|
3447
|
+
const preferredConditions = ["svelte", "import", "module", "default", "require"];
|
|
3448
|
+
for (const cond of preferredConditions) {
|
|
3449
|
+
if (cond in condObj) {
|
|
3450
|
+
const value = condObj[cond];
|
|
3451
|
+
if (typeof value === "string") {
|
|
3452
|
+
return value;
|
|
3453
|
+
}
|
|
3454
|
+
const resolved = resolveExportCondition(value);
|
|
3455
|
+
if (resolved)
|
|
3456
|
+
return resolved;
|
|
3457
|
+
}
|
|
3458
|
+
}
|
|
3165
3459
|
return null;
|
|
3166
3460
|
}
|
|
3167
3461
|
function resolveFilePath(basePath) {
|
|
@@ -3269,6 +3563,25 @@ async function resolveSchema(importPath, exportName, importerId, cache, debug, a
|
|
|
3269
3563
|
}
|
|
3270
3564
|
}
|
|
3271
3565
|
}
|
|
3566
|
+
if (schema.propsRef) {
|
|
3567
|
+
const propsRefImportPath = findImportPath(source, schema.propsRef);
|
|
3568
|
+
if (propsRefImportPath) {
|
|
3569
|
+
if (debug) {
|
|
3570
|
+
console.log(`[svelte-origin-preprocess] Resolving propsRef: ${schema.propsRef} from ${propsRefImportPath}`);
|
|
3571
|
+
}
|
|
3572
|
+
const propsRefSchema = await resolveAttrsSchema(propsRefImportPath, schema.propsRef, filePath, cache, debug, aliases);
|
|
3573
|
+
if (propsRefSchema) {
|
|
3574
|
+
for (const attr of propsRefSchema.attrs) {
|
|
3575
|
+
const existingIndex = mergedAttrs.findIndex((a) => a.key === attr.key);
|
|
3576
|
+
if (existingIndex === -1) {
|
|
3577
|
+
mergedAttrs.push(attr);
|
|
3578
|
+
} else {
|
|
3579
|
+
mergedAttrs[existingIndex] = attr;
|
|
3580
|
+
}
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3272
3585
|
for (const attr of schema.attrs) {
|
|
3273
3586
|
const existingIndex = mergedAttrs.findIndex((a) => a.key === attr.key);
|
|
3274
3587
|
if (existingIndex !== -1) {
|
|
@@ -3294,6 +3607,75 @@ async function resolveSchema(importPath, exportName, importerId, cache, debug, a
|
|
|
3294
3607
|
return null;
|
|
3295
3608
|
}
|
|
3296
3609
|
}
|
|
3610
|
+
async function resolveAttrsSchema(importPath, exportName, importerId, cache, debug, aliases) {
|
|
3611
|
+
const cacheKey = `attrs::${importPath}::${exportName}`;
|
|
3612
|
+
if (cache.has(cacheKey)) {
|
|
3613
|
+
if (debug) {
|
|
3614
|
+
console.log(`[svelte-origin-preprocess] Cache hit for ${cacheKey}`);
|
|
3615
|
+
}
|
|
3616
|
+
return cache.get(cacheKey) || null;
|
|
3617
|
+
}
|
|
3618
|
+
try {
|
|
3619
|
+
const importerDir = dirname2(importerId);
|
|
3620
|
+
if (debug) {
|
|
3621
|
+
console.log(`[svelte-origin-preprocess] Resolving attrs: ${exportName} from ${importPath}`);
|
|
3622
|
+
}
|
|
3623
|
+
const resolvedPath = resolveImportPath(importPath, aliases, importerDir);
|
|
3624
|
+
if (!resolvedPath) {
|
|
3625
|
+
cache.set(cacheKey, null);
|
|
3626
|
+
return null;
|
|
3627
|
+
}
|
|
3628
|
+
const filePath = resolveFilePath(resolvedPath);
|
|
3629
|
+
if (!filePath) {
|
|
3630
|
+
cache.set(cacheKey, null);
|
|
3631
|
+
return null;
|
|
3632
|
+
}
|
|
3633
|
+
const source = readFileSync2(filePath, "utf-8");
|
|
3634
|
+
const schema = parseAttrsSchemaFromSource(source, exportName);
|
|
3635
|
+
if (!schema) {
|
|
3636
|
+
cache.set(cacheKey, null);
|
|
3637
|
+
return null;
|
|
3638
|
+
}
|
|
3639
|
+
const mergedAttrs = [];
|
|
3640
|
+
for (const parentName of schema.parentNames) {
|
|
3641
|
+
const parentImportPath = findImportPath(source, parentName);
|
|
3642
|
+
if (parentImportPath) {
|
|
3643
|
+
const parentSchema = await resolveAttrsSchema(parentImportPath, parentName, filePath, cache, debug, aliases);
|
|
3644
|
+
if (parentSchema) {
|
|
3645
|
+
for (const attr of parentSchema.attrs) {
|
|
3646
|
+
const existingIndex = mergedAttrs.findIndex((a) => a.key === attr.key);
|
|
3647
|
+
if (existingIndex === -1) {
|
|
3648
|
+
mergedAttrs.push(attr);
|
|
3649
|
+
}
|
|
3650
|
+
}
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
}
|
|
3654
|
+
for (const attr of schema.attrs) {
|
|
3655
|
+
const existingIndex = mergedAttrs.findIndex((a) => a.key === attr.key);
|
|
3656
|
+
if (existingIndex !== -1) {
|
|
3657
|
+
mergedAttrs[existingIndex] = attr;
|
|
3658
|
+
} else {
|
|
3659
|
+
mergedAttrs.push(attr);
|
|
3660
|
+
}
|
|
3661
|
+
}
|
|
3662
|
+
const mergedSchema = {
|
|
3663
|
+
attrs: mergedAttrs,
|
|
3664
|
+
parentNames: schema.parentNames
|
|
3665
|
+
};
|
|
3666
|
+
if (debug) {
|
|
3667
|
+
console.log(`[svelte-origin-preprocess] Resolved attrs schema for ${exportName}:`, mergedSchema.attrs.map((a) => a.key));
|
|
3668
|
+
}
|
|
3669
|
+
cache.set(cacheKey, mergedSchema);
|
|
3670
|
+
return mergedSchema;
|
|
3671
|
+
} catch (error) {
|
|
3672
|
+
if (debug) {
|
|
3673
|
+
console.error(`[svelte-origin-preprocess] Error resolving attrs schema for ${importPath}:`, error);
|
|
3674
|
+
}
|
|
3675
|
+
cache.set(cacheKey, null);
|
|
3676
|
+
return null;
|
|
3677
|
+
}
|
|
3678
|
+
}
|
|
3297
3679
|
function svelteOriginPreprocess(options = {}) {
|
|
3298
3680
|
const {
|
|
3299
3681
|
debug = false,
|
|
@@ -19,6 +19,8 @@ export interface ParsedAttrInfo {
|
|
|
19
19
|
export interface ParsedOriginSchema {
|
|
20
20
|
attrs: ParsedAttrInfo[];
|
|
21
21
|
parentNames: string[];
|
|
22
|
+
/** Reference to external $attrs factory (e.g., 'TextAttrs' when props: TextAttrs is used) */
|
|
23
|
+
propsRef?: string;
|
|
22
24
|
}
|
|
23
25
|
/**
|
|
24
26
|
* Parse an origin's schema from its source code.
|
|
@@ -40,6 +42,21 @@ export interface ParsedOriginSchema {
|
|
|
40
42
|
* @returns Parsed schema or null if not found
|
|
41
43
|
*/
|
|
42
44
|
export declare function parseOriginSchemaFromSource(source: string, exportName: string): ParsedOriginSchema | null;
|
|
45
|
+
/**
|
|
46
|
+
* Parse an $attrs factory's schema from its source code.
|
|
47
|
+
*
|
|
48
|
+
* Looks for patterns like:
|
|
49
|
+
* ```ts
|
|
50
|
+
* export const TextAttrs = $attrs({ ... })
|
|
51
|
+
* export const TextAttrs = $attrs([BaseAttrs], { ... })
|
|
52
|
+
* ```
|
|
53
|
+
*
|
|
54
|
+
* Or compiled:
|
|
55
|
+
* ```js
|
|
56
|
+
* export var TextAttrs = __createAttrs({ __attrSchema: {...}, __parents: [...] })
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
export declare function parseAttrsSchemaFromSource(source: string, exportName: string): ParsedOriginSchema | null;
|
|
43
60
|
/**
|
|
44
61
|
* Generate $props() destructuring code from parsed attrs
|
|
45
62
|
*
|
package/dist/vite-dts.js
CHANGED
|
@@ -202,7 +202,83 @@ function findMatchingBracket(source, openIndex, openChar = "(", closeChar = ")")
|
|
|
202
202
|
|
|
203
203
|
// src/transform/schema.ts
|
|
204
204
|
function parseOriginSchemaFromSource(source, exportName) {
|
|
205
|
-
const
|
|
205
|
+
const sourceResult = parseSourceOrigin(source, exportName);
|
|
206
|
+
if (sourceResult)
|
|
207
|
+
return sourceResult;
|
|
208
|
+
const compiledResult = parseCompiledOrigin(source, exportName);
|
|
209
|
+
if (compiledResult)
|
|
210
|
+
return compiledResult;
|
|
211
|
+
return null;
|
|
212
|
+
}
|
|
213
|
+
function parseAttrsSchemaFromSource(source, exportName) {
|
|
214
|
+
const sourceResult = parseSourceAttrs(source, exportName);
|
|
215
|
+
if (sourceResult)
|
|
216
|
+
return sourceResult;
|
|
217
|
+
const compiledResult = parseCompiledAttrs(source, exportName);
|
|
218
|
+
if (compiledResult)
|
|
219
|
+
return compiledResult;
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
function parseSourceAttrs(source, exportName) {
|
|
223
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*\\$attrs\\s*\\(`, "s");
|
|
224
|
+
const match = exportPattern.exec(source);
|
|
225
|
+
if (!match)
|
|
226
|
+
return null;
|
|
227
|
+
const attrsStart = match.index + match[0].length - 1;
|
|
228
|
+
const attrsEnd = findMatchingBracket(source, attrsStart);
|
|
229
|
+
if (attrsEnd === -1)
|
|
230
|
+
return null;
|
|
231
|
+
let attrsContent = source.slice(attrsStart + 1, attrsEnd).trim();
|
|
232
|
+
let parentNames = [];
|
|
233
|
+
if (attrsContent.startsWith("[")) {
|
|
234
|
+
const closeBracket = findMatchingBracket(attrsContent, 0, "[", "]");
|
|
235
|
+
if (closeBracket !== -1) {
|
|
236
|
+
const parentsContent = attrsContent.slice(1, closeBracket);
|
|
237
|
+
parentNames = parentsContent.split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
238
|
+
let i = closeBracket + 1;
|
|
239
|
+
while (i < attrsContent.length && /[\s,]/.test(attrsContent[i]))
|
|
240
|
+
i++;
|
|
241
|
+
attrsContent = attrsContent.slice(i);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
if (!attrsContent.startsWith("{")) {
|
|
245
|
+
return { attrs: [], parentNames };
|
|
246
|
+
}
|
|
247
|
+
const objEnd = findMatchingBracket(attrsContent, 0, "{", "}");
|
|
248
|
+
if (objEnd === -1)
|
|
249
|
+
return { attrs: [], parentNames };
|
|
250
|
+
const objContent = attrsContent.slice(1, objEnd);
|
|
251
|
+
const attrs = parseAttrsContent(objContent);
|
|
252
|
+
return { attrs, parentNames };
|
|
253
|
+
}
|
|
254
|
+
function parseCompiledAttrs(source, exportName) {
|
|
255
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*__createAttrs\\s*\\(\\s*\\{`, "s");
|
|
256
|
+
const match = exportPattern.exec(source);
|
|
257
|
+
if (!match)
|
|
258
|
+
return null;
|
|
259
|
+
const braceStart = match.index + match[0].length - 1;
|
|
260
|
+
const braceEnd = findMatchingBracket(source, braceStart, "{", "}");
|
|
261
|
+
if (braceEnd === -1)
|
|
262
|
+
return null;
|
|
263
|
+
const configContent = source.slice(braceStart + 1, braceEnd);
|
|
264
|
+
const schemaMatch = configContent.match(/__attrSchema\s*:\s*\{/);
|
|
265
|
+
if (!schemaMatch)
|
|
266
|
+
return { attrs: [], parentNames: [] };
|
|
267
|
+
const schemaStart = schemaMatch.index + schemaMatch[0].length - 1;
|
|
268
|
+
const schemaEnd = findMatchingBracket(configContent, schemaStart, "{", "}");
|
|
269
|
+
if (schemaEnd === -1)
|
|
270
|
+
return { attrs: [], parentNames: [] };
|
|
271
|
+
const schemaContent = configContent.slice(schemaStart + 1, schemaEnd);
|
|
272
|
+
const attrs = parseCompiledAttrSchema(schemaContent);
|
|
273
|
+
const parentsMatch = configContent.match(/__parents\s*:\s*\[([^\]]*)\]/);
|
|
274
|
+
let parentNames = [];
|
|
275
|
+
if (parentsMatch && parentsMatch[1].trim()) {
|
|
276
|
+
parentNames = parentsMatch[1].split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
277
|
+
}
|
|
278
|
+
return { attrs, parentNames };
|
|
279
|
+
}
|
|
280
|
+
function parseSourceOrigin(source, exportName) {
|
|
281
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*\\$origin\\s*\\(`, "s");
|
|
206
282
|
const match = exportPattern.exec(source);
|
|
207
283
|
if (!match)
|
|
208
284
|
return null;
|
|
@@ -226,6 +302,13 @@ function parseOriginSchemaFromSource(source, exportName) {
|
|
|
226
302
|
}
|
|
227
303
|
const attrsMatch = bodyContent.match(/(\w+)\s*:\s*\$attrs\s*\(\s*\{/);
|
|
228
304
|
if (!attrsMatch) {
|
|
305
|
+
const externalRefMatch = bodyContent.match(/(?:props|attrs)\s*:\s*([A-Z]\w*)\b/);
|
|
306
|
+
if (externalRefMatch) {
|
|
307
|
+
const propsRef = externalRefMatch[1];
|
|
308
|
+
if (!["Object", "Array", "String", "Number", "Boolean"].includes(propsRef)) {
|
|
309
|
+
return { attrs: [], parentNames, propsRef };
|
|
310
|
+
}
|
|
311
|
+
}
|
|
229
312
|
return { attrs: [], parentNames };
|
|
230
313
|
}
|
|
231
314
|
const attrsStart = attrsMatch.index;
|
|
@@ -238,6 +321,96 @@ function parseOriginSchemaFromSource(source, exportName) {
|
|
|
238
321
|
const attrs = parseAttrsContent(attrsContent);
|
|
239
322
|
return { attrs, parentNames };
|
|
240
323
|
}
|
|
324
|
+
function parseCompiledOrigin(source, exportName) {
|
|
325
|
+
const exportPattern = new RegExp(`export\\s+(?:const|var|let)\\s+${exportName}\\s*=\\s*__createOrigin\\s*\\(\\s*\\{`, "s");
|
|
326
|
+
const match = exportPattern.exec(source);
|
|
327
|
+
if (!match)
|
|
328
|
+
return null;
|
|
329
|
+
const braceStart = match.index + match[0].length - 1;
|
|
330
|
+
const braceEnd = findMatchingBracket(source, braceStart, "{", "}");
|
|
331
|
+
if (braceEnd === -1)
|
|
332
|
+
return null;
|
|
333
|
+
const configContent = source.slice(braceStart + 1, braceEnd);
|
|
334
|
+
const schemaMatch = configContent.match(/__attrSchema\s*:\s*\{/);
|
|
335
|
+
if (!schemaMatch)
|
|
336
|
+
return { attrs: [], parentNames: [] };
|
|
337
|
+
const schemaStart = schemaMatch.index + schemaMatch[0].length - 1;
|
|
338
|
+
const schemaEnd = findMatchingBracket(configContent, schemaStart, "{", "}");
|
|
339
|
+
if (schemaEnd === -1)
|
|
340
|
+
return { attrs: [], parentNames: [] };
|
|
341
|
+
const schemaContent = configContent.slice(schemaStart + 1, schemaEnd);
|
|
342
|
+
const attrs = parseCompiledAttrSchema(schemaContent);
|
|
343
|
+
const parentsMatch = configContent.match(/__parents\s*:\s*\[([^\]]*)\]/);
|
|
344
|
+
let parentNames = [];
|
|
345
|
+
if (parentsMatch && parentsMatch[1].trim()) {
|
|
346
|
+
parentNames = parentsMatch[1].split(",").map((p) => p.trim()).filter((p) => p && /^\w+$/.test(p));
|
|
347
|
+
}
|
|
348
|
+
const propsRefMatch = configContent.match(/__propsRef\s*:\s*(\w+)/);
|
|
349
|
+
const propsRef = propsRefMatch ? propsRefMatch[1] : undefined;
|
|
350
|
+
return { attrs, parentNames, propsRef };
|
|
351
|
+
}
|
|
352
|
+
function parseCompiledAttrSchema(content) {
|
|
353
|
+
const result = [];
|
|
354
|
+
let pos = 0;
|
|
355
|
+
while (pos < content.length) {
|
|
356
|
+
while (pos < content.length && /[\s,]/.test(content[pos]))
|
|
357
|
+
pos++;
|
|
358
|
+
if (pos >= content.length)
|
|
359
|
+
break;
|
|
360
|
+
if (content.slice(pos, pos + 2) === "/*") {
|
|
361
|
+
const endComment = content.indexOf("*/", pos + 2);
|
|
362
|
+
if (endComment !== -1) {
|
|
363
|
+
pos = endComment + 2;
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
const keyMatch = content.slice(pos).match(/^(\w+)\s*:/);
|
|
368
|
+
if (!keyMatch)
|
|
369
|
+
break;
|
|
370
|
+
const key = keyMatch[1];
|
|
371
|
+
pos += keyMatch[0].length;
|
|
372
|
+
while (pos < content.length && /\s/.test(content[pos]))
|
|
373
|
+
pos++;
|
|
374
|
+
if (content[pos] !== "{")
|
|
375
|
+
break;
|
|
376
|
+
const valueStart = pos;
|
|
377
|
+
const valueEnd = findMatchingBracket(content, valueStart, "{", "}");
|
|
378
|
+
if (valueEnd === -1)
|
|
379
|
+
break;
|
|
380
|
+
const valueContent = content.slice(valueStart + 1, valueEnd);
|
|
381
|
+
let defaultValue = "undefined";
|
|
382
|
+
let bindable = false;
|
|
383
|
+
let hasDefault = false;
|
|
384
|
+
const defaultMatch = valueContent.match(/\bdefault\s*:\s*/);
|
|
385
|
+
if (defaultMatch) {
|
|
386
|
+
const defaultStart = defaultMatch.index + defaultMatch[0].length;
|
|
387
|
+
let depth = 0;
|
|
388
|
+
let i = defaultStart;
|
|
389
|
+
while (i < valueContent.length) {
|
|
390
|
+
const char = valueContent[i];
|
|
391
|
+
if (char === "{" || char === "(" || char === "[")
|
|
392
|
+
depth++;
|
|
393
|
+
else if (char === "}" || char === ")" || char === "]")
|
|
394
|
+
depth--;
|
|
395
|
+
else if (char === "," && depth === 0)
|
|
396
|
+
break;
|
|
397
|
+
i++;
|
|
398
|
+
}
|
|
399
|
+
defaultValue = valueContent.slice(defaultStart, i).trim();
|
|
400
|
+
}
|
|
401
|
+
const bindableMatch = valueContent.match(/\bbindable\s*:\s*(true|false)/);
|
|
402
|
+
if (bindableMatch) {
|
|
403
|
+
bindable = bindableMatch[1] === "true";
|
|
404
|
+
}
|
|
405
|
+
const hasDefaultMatch = valueContent.match(/\bhasDefault\s*:\s*(true|false)/);
|
|
406
|
+
if (hasDefaultMatch) {
|
|
407
|
+
hasDefault = hasDefaultMatch[1] === "true";
|
|
408
|
+
}
|
|
409
|
+
result.push({ key, defaultValue, bindable, hasDefault });
|
|
410
|
+
pos = valueEnd + 1;
|
|
411
|
+
}
|
|
412
|
+
return result;
|
|
413
|
+
}
|
|
241
414
|
function parseAttrsContent(content) {
|
|
242
415
|
const result = [];
|
|
243
416
|
const parts = splitByTopLevelCommas(content);
|