teamix-evo 0.20.2 → 0.20.4

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/index.js CHANGED
@@ -5411,6 +5411,7 @@ async function loadUiData(packageName) {
5411
5411
  init_fs();
5412
5412
  import * as path25 from "path";
5413
5413
  import * as fs20 from "fs/promises";
5414
+ import { isBuiltin } from "module";
5414
5415
  import { resolveUiEntryOrder } from "@teamix-evo/registry";
5415
5416
 
5416
5417
  // src/utils/transform-imports.ts
@@ -5466,6 +5467,12 @@ async function installUiEntries(options) {
5466
5467
  } = options;
5467
5468
  const orderedIds = resolveUiEntryOrder(manifest.entries, requested);
5468
5469
  const idToEntry = new Map(manifest.entries.map((e) => [e.id, e]));
5470
+ const sourceContents = await preflightUiEntrySources({
5471
+ manifest,
5472
+ orderedIds,
5473
+ packageRoot,
5474
+ entryPackageRoot
5475
+ });
5469
5476
  const resources = [];
5470
5477
  const npmDeps = {};
5471
5478
  let created = 0;
@@ -5494,7 +5501,12 @@ async function installUiEntries(options) {
5494
5501
  }
5495
5502
  const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
5496
5503
  const sourceAbs = path25.resolve(rootForEntry, file.source);
5497
- const raw = await fs20.readFile(sourceAbs, "utf-8");
5504
+ const raw = sourceContents.get(sourceAbs);
5505
+ if (raw === void 0) {
5506
+ throw new Error(
5507
+ `UI install preflight did not load source file "${file.source}" for entry "${entry.id}". No files were written.`
5508
+ );
5509
+ }
5498
5510
  const transformed = rewriteImports(raw, aliases, { flatten });
5499
5511
  if (exists) {
5500
5512
  const current = await fs20.readFile(targetAbs, "utf-8");
@@ -5547,6 +5559,189 @@ async function installUiEntries(options) {
5547
5559
  skipped
5548
5560
  };
5549
5561
  }
5562
+ var PROJECT_RUNTIME_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom"]);
5563
+ async function preflightUiEntrySources(options) {
5564
+ const { manifest, orderedIds, packageRoot, entryPackageRoot } = options;
5565
+ const sourceContents = /* @__PURE__ */ new Map();
5566
+ const aliasProviders = buildSourceAliasProviders(manifest.entries);
5567
+ const sourceProviders = buildRelativeSourceProviders(
5568
+ manifest.entries,
5569
+ packageRoot,
5570
+ entryPackageRoot
5571
+ );
5572
+ const issues = [];
5573
+ for (const id of orderedIds) {
5574
+ const entry = manifest.entries.find((candidate) => candidate.id === id);
5575
+ if (!entry) continue;
5576
+ const declaredRegistry = new Set(entry.registryDependencies ?? []);
5577
+ const declaredPackages = new Set(Object.keys(entry.dependencies ?? {}));
5578
+ const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
5579
+ for (const file of entry.files) {
5580
+ const sourceAbs = path25.resolve(rootForEntry, file.source);
5581
+ const source = await fs20.readFile(sourceAbs, "utf-8");
5582
+ sourceContents.set(sourceAbs, source);
5583
+ if (manifest.package !== "ui") continue;
5584
+ for (const specifier of extractModuleSpecifiers(source)) {
5585
+ if (specifier.startsWith("@/")) {
5586
+ const provider = aliasProviders.get(specifier);
5587
+ if (!provider) {
5588
+ issues.push({
5589
+ entryId: entry.id,
5590
+ source: file.source,
5591
+ message: `unresolved registry import "${specifier}"`
5592
+ });
5593
+ } else if (provider !== entry.id && !declaredRegistry.has(provider)) {
5594
+ issues.push({
5595
+ entryId: entry.id,
5596
+ source: file.source,
5597
+ message: `undeclared registry dependency "${provider}" (import "${specifier}")`
5598
+ });
5599
+ }
5600
+ continue;
5601
+ }
5602
+ if (specifier.startsWith(".")) {
5603
+ const provider = resolveRelativeProvider(
5604
+ path25.resolve(path25.dirname(sourceAbs), specifier),
5605
+ sourceProviders
5606
+ );
5607
+ if (!provider) {
5608
+ issues.push({
5609
+ entryId: entry.id,
5610
+ source: file.source,
5611
+ message: `unshipped or unresolved relative import "${specifier}"`
5612
+ });
5613
+ } else if (provider !== entry.id && !declaredRegistry.has(provider)) {
5614
+ issues.push({
5615
+ entryId: entry.id,
5616
+ source: file.source,
5617
+ message: `undeclared registry dependency "${provider}" (relative import "${specifier}")`
5618
+ });
5619
+ }
5620
+ continue;
5621
+ }
5622
+ const packageName = externalPackageName(specifier);
5623
+ if (!isBuiltin(specifier) && !PROJECT_RUNTIME_PACKAGES.has(packageName) && !declaredPackages.has(packageName)) {
5624
+ issues.push({
5625
+ entryId: entry.id,
5626
+ source: file.source,
5627
+ message: `undeclared npm dependency "${packageName}" (import "${specifier}")`
5628
+ });
5629
+ }
5630
+ }
5631
+ }
5632
+ }
5633
+ if (issues.length > 0) {
5634
+ const details = issues.sort(
5635
+ (a, b) => `${a.entryId}:${a.source}:${a.message}`.localeCompare(
5636
+ `${b.entryId}:${b.source}:${b.message}`
5637
+ )
5638
+ ).map(
5639
+ (issue) => `- Entry "${issue.entryId}" (${issue.source}): ${issue.message}`
5640
+ ).join("\n");
5641
+ throw new Error(
5642
+ [
5643
+ "UI install preflight failed. No files were written.",
5644
+ details,
5645
+ "Fix registryDependencies/dependencies in the package manifest, publish the corrected package, and retry."
5646
+ ].join("\n")
5647
+ );
5648
+ }
5649
+ return sourceContents;
5650
+ }
5651
+ function extractModuleSpecifiers(source) {
5652
+ const specifiers = /* @__PURE__ */ new Set();
5653
+ const staticPattern = /\b(?:import|export)\s+(?:type\s+)?(?:[^'";]*?\s+from\s+)?(['"])([^'"]+)\1/g;
5654
+ const dynamicPattern = /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g;
5655
+ for (const pattern of [staticPattern, dynamicPattern]) {
5656
+ let match;
5657
+ while ((match = pattern.exec(source)) !== null) {
5658
+ if (match[2]) specifiers.add(match[2]);
5659
+ }
5660
+ }
5661
+ return specifiers;
5662
+ }
5663
+ function buildSourceAliasProviders(entries) {
5664
+ const providers = /* @__PURE__ */ new Map();
5665
+ for (const entry of entries) {
5666
+ for (const file of entry.files) {
5667
+ const target = stripModuleExtension(file.targetName);
5668
+ const aliases = sourceAliases(file.targetAlias, target);
5669
+ for (const alias of aliases) {
5670
+ const current = providers.get(alias);
5671
+ if (current && current !== entry.id) {
5672
+ throw new Error(
5673
+ `UI install preflight found ambiguous source alias "${alias}" for entries "${current}" and "${entry.id}". No files were written.`
5674
+ );
5675
+ }
5676
+ providers.set(alias, entry.id);
5677
+ }
5678
+ }
5679
+ }
5680
+ return providers;
5681
+ }
5682
+ function sourceAliases(targetAlias, target) {
5683
+ switch (targetAlias) {
5684
+ case "components":
5685
+ return [`@/components/${target}`, `@/components/ui/${target}`];
5686
+ case "business":
5687
+ return [
5688
+ `@/components/business/${target}`,
5689
+ `@/business/${target}`
5690
+ ];
5691
+ case "hooks":
5692
+ return [`@/hooks/${target}`];
5693
+ case "utils":
5694
+ return [`@/utils/${target}`, `@/lib/utils/${target}`];
5695
+ case "lib":
5696
+ return [`@/lib/${target}`];
5697
+ case "blocks":
5698
+ return [`@/blocks/${target}`];
5699
+ default:
5700
+ return [];
5701
+ }
5702
+ }
5703
+ function buildRelativeSourceProviders(entries, packageRoot, entryPackageRoot) {
5704
+ const providers = /* @__PURE__ */ new Map();
5705
+ for (const entry of entries) {
5706
+ const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
5707
+ for (const file of entry.files) {
5708
+ const absolute = path25.resolve(rootForEntry, file.source);
5709
+ for (const candidate of relativeSourceCandidates(absolute)) {
5710
+ providers.set(candidate, entry.id);
5711
+ }
5712
+ }
5713
+ }
5714
+ return providers;
5715
+ }
5716
+ function resolveRelativeProvider(absolute, providers) {
5717
+ for (const candidate of relativeSourceCandidates(absolute)) {
5718
+ const provider = providers.get(candidate);
5719
+ if (provider) return provider;
5720
+ }
5721
+ return void 0;
5722
+ }
5723
+ function relativeSourceCandidates(absolute) {
5724
+ const extension = path25.extname(absolute);
5725
+ if (extension) return [absolute];
5726
+ return [
5727
+ absolute,
5728
+ `${absolute}.ts`,
5729
+ `${absolute}.tsx`,
5730
+ `${absolute}.js`,
5731
+ `${absolute}.jsx`,
5732
+ path25.join(absolute, "index.ts"),
5733
+ path25.join(absolute, "index.tsx"),
5734
+ path25.join(absolute, "index.js"),
5735
+ path25.join(absolute, "index.jsx")
5736
+ ];
5737
+ }
5738
+ function stripModuleExtension(value) {
5739
+ return value.replace(/\.(?:[cm]?[jt]sx?)$/, "");
5740
+ }
5741
+ function externalPackageName(specifier) {
5742
+ const parts = specifier.split("/");
5743
+ return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0] ?? specifier;
5744
+ }
5550
5745
  function resolveTargetPath(projectRoot, aliases, entry, file) {
5551
5746
  const aliasDir = aliases[file.targetAlias];
5552
5747
  if (!aliasDir) {
@@ -9531,7 +9726,7 @@ var initCommand5 = new Command36("init").description("\u521D\u59CB\u5316 Teamix
9531
9726
  variant: answers.variant,
9532
9727
  ides: answers.ides,
9533
9728
  force: opts.force,
9534
- skipInstall: false,
9729
+ skipInstall: shouldSkipInstall(opts.install),
9535
9730
  dryRun,
9536
9731
  onStep: (step) => {
9537
9732
  const icon = STEP_ICON[step.status];
@@ -9639,6 +9834,9 @@ async function runScaffoldPhase(cwd, variant, opts) {
9639
9834
  function shouldAutoCommitAfterInit(initialState, gitEnabled) {
9640
9835
  return initialState === "empty" && gitEnabled !== false;
9641
9836
  }
9837
+ function shouldSkipInstall(install) {
9838
+ return install === false;
9839
+ }
9642
9840
  async function autoCommitAfterInit(cwd) {
9643
9841
  let gitTopLevel;
9644
9842
  let canonicalCwd;