teamix-evo 0.20.2 → 0.20.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.
@@ -2027,6 +2027,7 @@ async function loadUiData(packageName) {
2027
2027
  // src/core/ui-installer.ts
2028
2028
  import * as path12 from "path";
2029
2029
  import * as fs10 from "fs/promises";
2030
+ import { isBuiltin } from "module";
2030
2031
  import { resolveUiEntryOrder } from "@teamix-evo/registry";
2031
2032
 
2032
2033
  // src/utils/transform-imports.ts
@@ -2080,6 +2081,12 @@ async function installUiEntries(options) {
2080
2081
  } = options;
2081
2082
  const orderedIds = resolveUiEntryOrder(manifest.entries, requested);
2082
2083
  const idToEntry = new Map(manifest.entries.map((e) => [e.id, e]));
2084
+ const sourceContents = await preflightUiEntrySources({
2085
+ manifest,
2086
+ orderedIds,
2087
+ packageRoot,
2088
+ entryPackageRoot
2089
+ });
2083
2090
  const resources = [];
2084
2091
  const npmDeps = {};
2085
2092
  let created = 0;
@@ -2108,7 +2115,12 @@ async function installUiEntries(options) {
2108
2115
  }
2109
2116
  const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
2110
2117
  const sourceAbs = path12.resolve(rootForEntry, file.source);
2111
- const raw = await fs10.readFile(sourceAbs, "utf-8");
2118
+ const raw = sourceContents.get(sourceAbs);
2119
+ if (raw === void 0) {
2120
+ throw new Error(
2121
+ `UI install preflight did not load source file "${file.source}" for entry "${entry.id}". No files were written.`
2122
+ );
2123
+ }
2112
2124
  const transformed = rewriteImports(raw, aliases, { flatten });
2113
2125
  if (exists) {
2114
2126
  const current = await fs10.readFile(targetAbs, "utf-8");
@@ -2161,6 +2173,189 @@ async function installUiEntries(options) {
2161
2173
  skipped
2162
2174
  };
2163
2175
  }
2176
+ var PROJECT_RUNTIME_PACKAGES = /* @__PURE__ */ new Set(["react", "react-dom"]);
2177
+ async function preflightUiEntrySources(options) {
2178
+ const { manifest, orderedIds, packageRoot, entryPackageRoot } = options;
2179
+ const sourceContents = /* @__PURE__ */ new Map();
2180
+ const aliasProviders = buildSourceAliasProviders(manifest.entries);
2181
+ const sourceProviders = buildRelativeSourceProviders(
2182
+ manifest.entries,
2183
+ packageRoot,
2184
+ entryPackageRoot
2185
+ );
2186
+ const issues = [];
2187
+ for (const id of orderedIds) {
2188
+ const entry = manifest.entries.find((candidate) => candidate.id === id);
2189
+ if (!entry) continue;
2190
+ const declaredRegistry = new Set(entry.registryDependencies ?? []);
2191
+ const declaredPackages = new Set(Object.keys(entry.dependencies ?? {}));
2192
+ const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
2193
+ for (const file of entry.files) {
2194
+ const sourceAbs = path12.resolve(rootForEntry, file.source);
2195
+ const source = await fs10.readFile(sourceAbs, "utf-8");
2196
+ sourceContents.set(sourceAbs, source);
2197
+ if (manifest.package !== "ui") continue;
2198
+ for (const specifier of extractModuleSpecifiers(source)) {
2199
+ if (specifier.startsWith("@/")) {
2200
+ const provider = aliasProviders.get(specifier);
2201
+ if (!provider) {
2202
+ issues.push({
2203
+ entryId: entry.id,
2204
+ source: file.source,
2205
+ message: `unresolved registry import "${specifier}"`
2206
+ });
2207
+ } else if (provider !== entry.id && !declaredRegistry.has(provider)) {
2208
+ issues.push({
2209
+ entryId: entry.id,
2210
+ source: file.source,
2211
+ message: `undeclared registry dependency "${provider}" (import "${specifier}")`
2212
+ });
2213
+ }
2214
+ continue;
2215
+ }
2216
+ if (specifier.startsWith(".")) {
2217
+ const provider = resolveRelativeProvider(
2218
+ path12.resolve(path12.dirname(sourceAbs), specifier),
2219
+ sourceProviders
2220
+ );
2221
+ if (!provider) {
2222
+ issues.push({
2223
+ entryId: entry.id,
2224
+ source: file.source,
2225
+ message: `unshipped or unresolved relative import "${specifier}"`
2226
+ });
2227
+ } else if (provider !== entry.id && !declaredRegistry.has(provider)) {
2228
+ issues.push({
2229
+ entryId: entry.id,
2230
+ source: file.source,
2231
+ message: `undeclared registry dependency "${provider}" (relative import "${specifier}")`
2232
+ });
2233
+ }
2234
+ continue;
2235
+ }
2236
+ const packageName = externalPackageName(specifier);
2237
+ if (!isBuiltin(specifier) && !PROJECT_RUNTIME_PACKAGES.has(packageName) && !declaredPackages.has(packageName)) {
2238
+ issues.push({
2239
+ entryId: entry.id,
2240
+ source: file.source,
2241
+ message: `undeclared npm dependency "${packageName}" (import "${specifier}")`
2242
+ });
2243
+ }
2244
+ }
2245
+ }
2246
+ }
2247
+ if (issues.length > 0) {
2248
+ const details = issues.sort(
2249
+ (a, b) => `${a.entryId}:${a.source}:${a.message}`.localeCompare(
2250
+ `${b.entryId}:${b.source}:${b.message}`
2251
+ )
2252
+ ).map(
2253
+ (issue) => `- Entry "${issue.entryId}" (${issue.source}): ${issue.message}`
2254
+ ).join("\n");
2255
+ throw new Error(
2256
+ [
2257
+ "UI install preflight failed. No files were written.",
2258
+ details,
2259
+ "Fix registryDependencies/dependencies in the package manifest, publish the corrected package, and retry."
2260
+ ].join("\n")
2261
+ );
2262
+ }
2263
+ return sourceContents;
2264
+ }
2265
+ function extractModuleSpecifiers(source) {
2266
+ const specifiers = /* @__PURE__ */ new Set();
2267
+ const staticPattern = /\b(?:import|export)\s+(?:type\s+)?(?:[^'";]*?\s+from\s+)?(['"])([^'"]+)\1/g;
2268
+ const dynamicPattern = /\bimport\s*\(\s*(['"])([^'"]+)\1\s*\)/g;
2269
+ for (const pattern of [staticPattern, dynamicPattern]) {
2270
+ let match;
2271
+ while ((match = pattern.exec(source)) !== null) {
2272
+ if (match[2]) specifiers.add(match[2]);
2273
+ }
2274
+ }
2275
+ return specifiers;
2276
+ }
2277
+ function buildSourceAliasProviders(entries) {
2278
+ const providers = /* @__PURE__ */ new Map();
2279
+ for (const entry of entries) {
2280
+ for (const file of entry.files) {
2281
+ const target = stripModuleExtension(file.targetName);
2282
+ const aliases = sourceAliases(file.targetAlias, target);
2283
+ for (const alias of aliases) {
2284
+ const current = providers.get(alias);
2285
+ if (current && current !== entry.id) {
2286
+ throw new Error(
2287
+ `UI install preflight found ambiguous source alias "${alias}" for entries "${current}" and "${entry.id}". No files were written.`
2288
+ );
2289
+ }
2290
+ providers.set(alias, entry.id);
2291
+ }
2292
+ }
2293
+ }
2294
+ return providers;
2295
+ }
2296
+ function sourceAliases(targetAlias, target) {
2297
+ switch (targetAlias) {
2298
+ case "components":
2299
+ return [`@/components/${target}`, `@/components/ui/${target}`];
2300
+ case "business":
2301
+ return [
2302
+ `@/components/business/${target}`,
2303
+ `@/business/${target}`
2304
+ ];
2305
+ case "hooks":
2306
+ return [`@/hooks/${target}`];
2307
+ case "utils":
2308
+ return [`@/utils/${target}`, `@/lib/utils/${target}`];
2309
+ case "lib":
2310
+ return [`@/lib/${target}`];
2311
+ case "blocks":
2312
+ return [`@/blocks/${target}`];
2313
+ default:
2314
+ return [];
2315
+ }
2316
+ }
2317
+ function buildRelativeSourceProviders(entries, packageRoot, entryPackageRoot) {
2318
+ const providers = /* @__PURE__ */ new Map();
2319
+ for (const entry of entries) {
2320
+ const rootForEntry = entryPackageRoot?.get(entry.id) ?? packageRoot;
2321
+ for (const file of entry.files) {
2322
+ const absolute = path12.resolve(rootForEntry, file.source);
2323
+ for (const candidate of relativeSourceCandidates(absolute)) {
2324
+ providers.set(candidate, entry.id);
2325
+ }
2326
+ }
2327
+ }
2328
+ return providers;
2329
+ }
2330
+ function resolveRelativeProvider(absolute, providers) {
2331
+ for (const candidate of relativeSourceCandidates(absolute)) {
2332
+ const provider = providers.get(candidate);
2333
+ if (provider) return provider;
2334
+ }
2335
+ return void 0;
2336
+ }
2337
+ function relativeSourceCandidates(absolute) {
2338
+ const extension = path12.extname(absolute);
2339
+ if (extension) return [absolute];
2340
+ return [
2341
+ absolute,
2342
+ `${absolute}.ts`,
2343
+ `${absolute}.tsx`,
2344
+ `${absolute}.js`,
2345
+ `${absolute}.jsx`,
2346
+ path12.join(absolute, "index.ts"),
2347
+ path12.join(absolute, "index.tsx"),
2348
+ path12.join(absolute, "index.js"),
2349
+ path12.join(absolute, "index.jsx")
2350
+ ];
2351
+ }
2352
+ function stripModuleExtension(value) {
2353
+ return value.replace(/\.(?:[cm]?[jt]sx?)$/, "");
2354
+ }
2355
+ function externalPackageName(specifier) {
2356
+ const parts = specifier.split("/");
2357
+ return specifier.startsWith("@") ? parts.slice(0, 2).join("/") : parts[0] ?? specifier;
2358
+ }
2164
2359
  function resolveTargetPath(projectRoot, aliases, entry, file) {
2165
2360
  const aliasDir = aliases[file.targetAlias];
2166
2361
  if (!aliasDir) {