@caryhu/codemine-forge 0.0.1-alpha.2 → 0.0.1-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -24,6 +24,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
26
|
exports.createBrowserBundle = void 0;
|
|
27
|
+
const compiler_sfc_1 = require("@vue/compiler-sfc");
|
|
27
28
|
const ts = __importStar(require("typescript"));
|
|
28
29
|
const virtual_file_system_1 = require("../virtual-file-system");
|
|
29
30
|
const diagnostics_1 = require("./diagnostics");
|
|
@@ -324,234 +325,53 @@ function transformPackageModule(importer, filePath, content) {
|
|
|
324
325
|
return transformSuccess(transpileScript(importer, source));
|
|
325
326
|
}
|
|
326
327
|
function createVueSfcModule(sourcePath, source) {
|
|
327
|
-
const
|
|
328
|
-
const
|
|
329
|
-
const
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
328
|
+
const filename = sourcePath;
|
|
329
|
+
const id = `forge-vue-${hashText(sourcePath)}`;
|
|
330
|
+
const parseResult = (0, compiler_sfc_1.parse)(source, { filename });
|
|
331
|
+
if (parseResult.errors.length > 0) {
|
|
332
|
+
throw new Error(formatVueCompilerErrors(parseResult.errors));
|
|
333
|
+
}
|
|
334
|
+
const { descriptor } = parseResult;
|
|
335
|
+
const script = descriptor.script === null && descriptor.scriptSetup === null
|
|
336
|
+
? undefined
|
|
337
|
+
: (0, compiler_sfc_1.compileScript)(descriptor, {
|
|
338
|
+
genDefaultAs: "__forgeVueDefault",
|
|
339
|
+
id,
|
|
340
|
+
});
|
|
341
|
+
const scriptContent = script?.content ?? "const __forgeVueDefault = {};";
|
|
342
|
+
const template = descriptor.template === null
|
|
343
|
+
? undefined
|
|
344
|
+
: (0, compiler_sfc_1.compileTemplate)({
|
|
345
|
+
compilerOptions: {
|
|
346
|
+
bindingMetadata: script?.bindings ?? {},
|
|
347
|
+
},
|
|
348
|
+
filename,
|
|
349
|
+
id,
|
|
350
|
+
scoped: descriptor.styles.some((style) => style.scoped),
|
|
351
|
+
source: descriptor.template.content,
|
|
352
|
+
});
|
|
353
|
+
if (template?.errors !== undefined && template.errors.length > 0) {
|
|
354
|
+
throw new Error(formatVueCompilerErrors(template.errors));
|
|
355
|
+
}
|
|
356
|
+
const templateContent = template?.code ?? "function render() { return null; }";
|
|
334
357
|
return [
|
|
335
|
-
|
|
336
|
-
|
|
358
|
+
scriptContent,
|
|
359
|
+
"",
|
|
360
|
+
templateContent,
|
|
337
361
|
"",
|
|
338
|
-
"const __forgeVueComponent = {",
|
|
362
|
+
"const __forgeVueComponent = Object.assign(__forgeVueDefault, {",
|
|
339
363
|
` __file: ${JSON.stringify(sourcePath)},`,
|
|
340
|
-
"
|
|
341
|
-
|
|
342
|
-
" },",
|
|
343
|
-
" render(__forgeVueCtx) {",
|
|
344
|
-
` return ${renderExpression};`,
|
|
345
|
-
" },",
|
|
346
|
-
"};",
|
|
364
|
+
" render,",
|
|
365
|
+
"});",
|
|
347
366
|
"",
|
|
348
367
|
"export default __forgeVueComponent;",
|
|
349
368
|
"",
|
|
350
369
|
].join("\n");
|
|
351
370
|
}
|
|
352
|
-
function
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
if (requiredAttribute !== undefined &&
|
|
357
|
-
!new RegExp(`\\b${requiredAttribute}\\b`, "i").test(attributes)) {
|
|
358
|
-
continue;
|
|
359
|
-
}
|
|
360
|
-
return match[2].trim();
|
|
361
|
-
}
|
|
362
|
-
return undefined;
|
|
363
|
-
}
|
|
364
|
-
function collectVueSetupBindings(scriptSetup) {
|
|
365
|
-
const bindings = new Set();
|
|
366
|
-
for (const match of scriptSetup.matchAll(/\bimport\s+(type\s+)?([\s\S]*?)\s+from\s*["'][^"']+["']/g)) {
|
|
367
|
-
if (match[1] !== undefined) {
|
|
368
|
-
continue;
|
|
369
|
-
}
|
|
370
|
-
for (const binding of parseImportBindingNames(match[2])) {
|
|
371
|
-
bindings.add(binding);
|
|
372
|
-
}
|
|
373
|
-
}
|
|
374
|
-
const declarationPatterns = [
|
|
375
|
-
/\b(?:const|let|var)\s+([A-Za-z_$][\w$]*)/g,
|
|
376
|
-
/\bfunction\s+([A-Za-z_$][\w$]*)/g,
|
|
377
|
-
/\bclass\s+([A-Za-z_$][\w$]*)/g,
|
|
378
|
-
];
|
|
379
|
-
for (const pattern of declarationPatterns) {
|
|
380
|
-
for (const match of scriptSetup.matchAll(pattern)) {
|
|
381
|
-
bindings.add(match[1]);
|
|
382
|
-
}
|
|
383
|
-
}
|
|
384
|
-
return Array.from(bindings).sort((left, right) => left.localeCompare(right));
|
|
385
|
-
}
|
|
386
|
-
function parseImportBindingNames(importClause) {
|
|
387
|
-
const bindings = [];
|
|
388
|
-
const trimmed = importClause.trim();
|
|
389
|
-
if (trimmed.length === 0 || trimmed.startsWith("{")) {
|
|
390
|
-
bindings.push(...parseNamedImportBindings(trimmed));
|
|
391
|
-
return bindings;
|
|
392
|
-
}
|
|
393
|
-
const [defaultOrNamespace = "", ...rest] = trimmed.split(",");
|
|
394
|
-
const defaultBinding = defaultOrNamespace.trim();
|
|
395
|
-
if (defaultBinding.startsWith("* as ")) {
|
|
396
|
-
bindings.push(defaultBinding.slice(5).trim());
|
|
397
|
-
}
|
|
398
|
-
else if (/^[A-Za-z_$][\w$]*$/.test(defaultBinding)) {
|
|
399
|
-
bindings.push(defaultBinding);
|
|
400
|
-
}
|
|
401
|
-
bindings.push(...parseNamedImportBindings(rest.join(",").trim()));
|
|
402
|
-
return bindings.filter((binding) => /^[A-Za-z_$][\w$]*$/.test(binding));
|
|
403
|
-
}
|
|
404
|
-
function parseNamedImportBindings(importClause) {
|
|
405
|
-
const namedMatch = importClause.match(/\{([\s\S]*?)\}/);
|
|
406
|
-
if (namedMatch === null) {
|
|
407
|
-
return [];
|
|
408
|
-
}
|
|
409
|
-
return namedMatch[1]
|
|
410
|
-
.split(",")
|
|
411
|
-
.map((part) => part.trim())
|
|
412
|
-
.filter((part) => part.length > 0 && !part.startsWith("type "))
|
|
413
|
-
.map((part) => {
|
|
414
|
-
const aliasMatch = part.match(/\bas\s+([A-Za-z_$][\w$]*)$/);
|
|
415
|
-
return aliasMatch?.[1] ?? part;
|
|
416
|
-
})
|
|
417
|
-
.filter((binding) => /^[A-Za-z_$][\w$]*$/.test(binding));
|
|
418
|
-
}
|
|
419
|
-
function createVueRenderExpression(template) {
|
|
420
|
-
const nodes = parseVueTemplate(template);
|
|
421
|
-
const renderedChildren = nodes.map(createVueTemplateNodeExpression);
|
|
422
|
-
if (renderedChildren.length === 0) {
|
|
423
|
-
return "null";
|
|
424
|
-
}
|
|
425
|
-
return renderedChildren.length === 1
|
|
426
|
-
? renderedChildren[0]
|
|
427
|
-
: `__forgeVueH("div", null, [${renderedChildren.join(", ")}])`;
|
|
428
|
-
}
|
|
429
|
-
function parseVueTemplate(template) {
|
|
430
|
-
const root = {
|
|
431
|
-
attributes: [],
|
|
432
|
-
children: [],
|
|
433
|
-
tagName: "__root__",
|
|
434
|
-
};
|
|
435
|
-
const stack = [root];
|
|
436
|
-
const tokenPattern = /<!--[\s\S]*?-->|<\/?[^>]+>|{{[\s\S]*?}}|[^<{]+|[<{]/g;
|
|
437
|
-
for (const match of template.matchAll(tokenPattern)) {
|
|
438
|
-
const token = match[0];
|
|
439
|
-
const current = stack[stack.length - 1];
|
|
440
|
-
if (token.startsWith("<!--")) {
|
|
441
|
-
continue;
|
|
442
|
-
}
|
|
443
|
-
if (token.startsWith("</")) {
|
|
444
|
-
if (stack.length > 1) {
|
|
445
|
-
stack.pop();
|
|
446
|
-
}
|
|
447
|
-
continue;
|
|
448
|
-
}
|
|
449
|
-
if (token.startsWith("<")) {
|
|
450
|
-
const element = parseVueTemplateElementToken(token);
|
|
451
|
-
if (element === undefined) {
|
|
452
|
-
continue;
|
|
453
|
-
}
|
|
454
|
-
current.children.push({
|
|
455
|
-
attributes: element.attributes,
|
|
456
|
-
children: element.children,
|
|
457
|
-
kind: "element",
|
|
458
|
-
tagName: element.tagName,
|
|
459
|
-
});
|
|
460
|
-
if (!isSelfClosingVueTemplateToken(token)) {
|
|
461
|
-
stack.push(element);
|
|
462
|
-
}
|
|
463
|
-
continue;
|
|
464
|
-
}
|
|
465
|
-
if (token.startsWith("{{")) {
|
|
466
|
-
current.children.push({
|
|
467
|
-
expression: token.slice(2, -2).trim(),
|
|
468
|
-
kind: "interpolation",
|
|
469
|
-
});
|
|
470
|
-
continue;
|
|
471
|
-
}
|
|
472
|
-
if (token.trim().length > 0) {
|
|
473
|
-
current.children.push({
|
|
474
|
-
kind: "text",
|
|
475
|
-
value: token.replace(/\s+/g, " "),
|
|
476
|
-
});
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
return root.children;
|
|
480
|
-
}
|
|
481
|
-
function parseVueTemplateElementToken(token) {
|
|
482
|
-
const content = token
|
|
483
|
-
.slice(1, isSelfClosingVueTemplateToken(token) ? -2 : -1)
|
|
484
|
-
.trim();
|
|
485
|
-
const tagMatch = content.match(/^([A-Za-z][\w.-]*)/);
|
|
486
|
-
if (tagMatch === null) {
|
|
487
|
-
return undefined;
|
|
488
|
-
}
|
|
489
|
-
return {
|
|
490
|
-
attributes: parseVueTemplateAttributes(content.slice(tagMatch[0].length)),
|
|
491
|
-
children: [],
|
|
492
|
-
tagName: tagMatch[1],
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
function parseVueTemplateAttributes(source) {
|
|
496
|
-
const attributes = [];
|
|
497
|
-
const pattern = /([:@A-Za-z_][\w:.-]*)(?:\s*=\s*("[^"]*"|'[^']*'|[^\s"'>/]+))?/g;
|
|
498
|
-
for (const match of source.matchAll(pattern)) {
|
|
499
|
-
const name = match[1];
|
|
500
|
-
if (name.startsWith(":") ||
|
|
501
|
-
name.startsWith("@") ||
|
|
502
|
-
name.startsWith("v-")) {
|
|
503
|
-
continue;
|
|
504
|
-
}
|
|
505
|
-
const rawValue = match[2];
|
|
506
|
-
const value = rawValue === undefined
|
|
507
|
-
? true
|
|
508
|
-
: rawValue.replace(/^["']|["']$/g, "");
|
|
509
|
-
attributes.push({ name, value });
|
|
510
|
-
}
|
|
511
|
-
return attributes;
|
|
512
|
-
}
|
|
513
|
-
function createVueTemplateNodeExpression(node) {
|
|
514
|
-
switch (node.kind) {
|
|
515
|
-
case "element":
|
|
516
|
-
return createVueElementExpression(node);
|
|
517
|
-
case "interpolation":
|
|
518
|
-
return createVueInterpolationExpression(node.expression);
|
|
519
|
-
case "text":
|
|
520
|
-
return JSON.stringify(node.value);
|
|
521
|
-
}
|
|
522
|
-
}
|
|
523
|
-
function createVueElementExpression(node) {
|
|
524
|
-
const tagExpression = /^[A-Z]/.test(node.tagName)
|
|
525
|
-
? `(__forgeVueCtx[${JSON.stringify(node.tagName)}] ?? ${JSON.stringify(node.tagName)})`
|
|
526
|
-
: JSON.stringify(node.tagName);
|
|
527
|
-
const propsExpression = createVuePropsExpression(node.attributes);
|
|
528
|
-
const children = node.children.map(createVueTemplateNodeExpression);
|
|
529
|
-
const childrenExpression = children.length === 0
|
|
530
|
-
? "null"
|
|
531
|
-
: children.length === 1
|
|
532
|
-
? children[0]
|
|
533
|
-
: `[${children.join(", ")}]`;
|
|
534
|
-
return `__forgeVueH(${tagExpression}, ${propsExpression}, ${childrenExpression})`;
|
|
535
|
-
}
|
|
536
|
-
function createVuePropsExpression(attributes) {
|
|
537
|
-
if (attributes.length === 0) {
|
|
538
|
-
return "null";
|
|
539
|
-
}
|
|
540
|
-
return `{ ${attributes
|
|
541
|
-
.map((attribute) => {
|
|
542
|
-
const value = attribute.value === true ? "true" : JSON.stringify(attribute.value);
|
|
543
|
-
return `${JSON.stringify(attribute.name)}: ${value}`;
|
|
544
|
-
})
|
|
545
|
-
.join(", ")} }`;
|
|
546
|
-
}
|
|
547
|
-
function createVueInterpolationExpression(expression) {
|
|
548
|
-
if (/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*)*$/.test(expression)) {
|
|
549
|
-
return `String(__forgeVueCtx.${expression} ?? "")`;
|
|
550
|
-
}
|
|
551
|
-
return "String(\"\")";
|
|
552
|
-
}
|
|
553
|
-
function isSelfClosingVueTemplateToken(token) {
|
|
554
|
-
return /\/\s*>$/.test(token);
|
|
371
|
+
function formatVueCompilerErrors(errors) {
|
|
372
|
+
return errors
|
|
373
|
+
.map((error) => (error instanceof Error ? error.message : String(error)))
|
|
374
|
+
.join("\n");
|
|
555
375
|
}
|
|
556
376
|
function createWorkspaceCssModule(sourcePath, css) {
|
|
557
377
|
return isCssModulePath(sourcePath)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caryhu/codemine-forge",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.3",
|
|
4
4
|
"description": "Browser-side runtime layer for Codemine demos.",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"access": "public"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
+
"@vue/compiler-sfc": "3.4.0",
|
|
21
22
|
"esbuild-wasm": "^0.28.1",
|
|
22
23
|
"typescript": "4.9.5"
|
|
23
24
|
},
|