@solid-stack/mason 1.0.17 → 1.0.20

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
@@ -147,7 +147,7 @@ function getEffectiveMode(projectRoot, flags) {
147
147
  if (flags?.registry) return "registry";
148
148
  const config = loadMasonConfig(projectRoot);
149
149
  if (config?.mode) return config.mode;
150
- if (fs4.existsSync(path2.join(projectRoot, "index.json")) && (fs4.existsSync(path2.join(projectRoot, "features")) || fs4.existsSync(path2.join(projectRoot, "shared"))) && !fs4.existsSync(path2.join(projectRoot, "src"))) {
150
+ if (fs4.existsSync(path2.join(projectRoot, "index.json")) && (fs4.existsSync(path2.join(projectRoot, "features")) || fs4.existsSync(path2.join(projectRoot, "shared")) || fs4.existsSync(path2.join(projectRoot, "src/features")) || fs4.existsSync(path2.join(projectRoot, "src/shared")))) {
151
151
  return "registry";
152
152
  }
153
153
  return "app";
@@ -161,6 +161,9 @@ function getConfiguredFeaturesDir(projectRoot, flags) {
161
161
  }
162
162
  const mode = getEffectiveMode(projectRoot, flags);
163
163
  if (mode === "registry") {
164
+ if (fs4.existsSync(path2.join(projectRoot, "src/features"))) {
165
+ return path2.join(projectRoot, "src/features");
166
+ }
164
167
  return path2.join(projectRoot, "features");
165
168
  }
166
169
  if (fs4.existsSync(path2.join(projectRoot, "src/features"))) {
@@ -177,6 +180,9 @@ function getConfiguredSharedDir(projectRoot, flags) {
177
180
  }
178
181
  const mode = getEffectiveMode(projectRoot, flags);
179
182
  if (mode === "registry") {
183
+ if (fs4.existsSync(path2.join(projectRoot, "src/shared"))) {
184
+ return path2.join(projectRoot, "src/shared");
185
+ }
180
186
  return path2.join(projectRoot, "shared");
181
187
  }
182
188
  if (fs4.existsSync(path2.join(projectRoot, "src/shared"))) {
@@ -483,7 +489,14 @@ async function fetchRegistryFile(registryBase, relPath) {
483
489
  if (token) {
484
490
  headers["Authorization"] = `Bearer ${token}`;
485
491
  }
486
- const res = await fetch(url, { headers });
492
+ let res = await fetch(url, { headers });
493
+ if (!res.ok && res.status === 404 && !cleanRelPath.startsWith("src/")) {
494
+ const srcUrl = `${registryBase.replace(/\/+$/, "")}/src/${cleanRelPath}`;
495
+ const srcRes = await fetch(srcUrl, { headers });
496
+ if (srcRes.ok) {
497
+ res = srcRes;
498
+ }
499
+ }
487
500
  if (!res.ok) {
488
501
  let extraHint = "";
489
502
  if (res.status === 404) {
@@ -503,9 +516,14 @@ async function fetchRegistryFile(registryBase, relPath) {
503
516
  if (baseDir.startsWith("file://")) {
504
517
  baseDir = fileURLToPath(baseDir);
505
518
  }
506
- const filePath = path2.resolve(baseDir, cleanRelPath);
519
+ let filePath = path2.resolve(baseDir, cleanRelPath);
507
520
  if (!fs4.existsSync(filePath)) {
508
- throw new Error(`Registry file not found at ${filePath}`);
521
+ const inSrcPath = path2.resolve(baseDir, "src", cleanRelPath);
522
+ if (fs4.existsSync(inSrcPath)) {
523
+ filePath = inSrcPath;
524
+ } else {
525
+ throw new Error(`Registry file not found at ${filePath}`);
526
+ }
509
527
  }
510
528
  return fs4.promises.readFile(filePath, "utf-8");
511
529
  }
@@ -632,7 +650,7 @@ function getAllFiles(dir, baseDir = dir) {
632
650
  }
633
651
  files.push(...getAllFiles(fullPath, baseDir));
634
652
  } else if (entry.isFile()) {
635
- if (entry.name === "registry.json" || entry.name.endsWith(".test.ts") || entry.name.endsWith(".spec.ts") || entry.name.startsWith(".")) {
653
+ if (entry.name === "registry.json" || entry.name.endsWith(".test.ts") || entry.name.endsWith(".spec.ts") || entry.name.endsWith(".test.js") || entry.name.endsWith(".spec.js") || entry.name.startsWith(".")) {
636
654
  continue;
637
655
  }
638
656
  files.push(relPath);
@@ -3585,8 +3603,15 @@ async function handleCreate(type, name, flags = {}) {
3585
3603
  }
3586
3604
  var importPrompts = {
3587
3605
  select: p14.select,
3588
- text: p14.text
3606
+ text: p14.text,
3607
+ confirm: p14.confirm
3589
3608
  };
3609
+ function isTestFile(filePath) {
3610
+ const normalized = filePath.replace(/\\/g, "/");
3611
+ const parts = normalized.split("/");
3612
+ const fileName = parts[parts.length - 1] || "";
3613
+ return fileName.endsWith(".test.ts") || fileName.endsWith(".test.js") || fileName.endsWith(".spec.ts") || fileName.endsWith(".spec.js") || parts.includes("__tests__");
3614
+ }
3590
3615
  function rewriteImports(content, aliasMap) {
3591
3616
  if (aliasMap.size === 0) return content;
3592
3617
  let rewritten = content;
@@ -3600,11 +3625,18 @@ function rewriteImports(content, aliasMap) {
3600
3625
  return rewritten;
3601
3626
  }
3602
3627
  function getModuleBaseDir(projectRoot, modType) {
3628
+ const mode = getEffectiveMode(projectRoot);
3629
+ if (mode === "registry") {
3630
+ return modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
3631
+ }
3603
3632
  const folder = modType === "shared" ? "shared" : "features";
3604
3633
  return path2.join(projectRoot, "src", folder);
3605
3634
  }
3606
3635
  function getExistingModuleDir(projectRoot, modType, modName) {
3607
3636
  const folder = modType === "shared" ? "shared" : "features";
3637
+ const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
3638
+ const inConfigured = path2.join(configuredDir, modName);
3639
+ if (fs4.existsSync(inConfigured)) return inConfigured;
3608
3640
  const inSrc = path2.join(projectRoot, "src", folder, modName);
3609
3641
  if (fs4.existsSync(inSrc)) return inSrc;
3610
3642
  const inRoot = path2.join(projectRoot, folder, modName);
@@ -3616,7 +3648,9 @@ function checkModuleExists(projectRoot, modType, modName) {
3616
3648
  }
3617
3649
  function getAvailableLocalModules(projectRoot, modType) {
3618
3650
  const folder = modType === "shared" ? "shared" : "features";
3651
+ const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
3619
3652
  const dirs = [
3653
+ configuredDir,
3620
3654
  path2.join(projectRoot, "src", folder),
3621
3655
  path2.join(projectRoot, folder)
3622
3656
  ];
@@ -4044,6 +4078,22 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4044
4078
  requiredNpmPackages.add(pkg);
4045
4079
  }
4046
4080
  }
4081
+ const hasTestFiles = Array.from(nodes.values()).some(
4082
+ (node) => node.manifest.files?.some((file) => isTestFile(file))
4083
+ );
4084
+ let includeTests = true;
4085
+ if (flags.tests !== void 0) {
4086
+ includeTests = Boolean(flags.tests);
4087
+ } else if (flags.yes) {
4088
+ includeTests = true;
4089
+ } else if (hasTestFiles) {
4090
+ includeTests = handleCancel(
4091
+ await importPrompts.confirm({
4092
+ message: "Include test files?",
4093
+ initialValue: true
4094
+ })
4095
+ );
4096
+ }
4047
4097
  for (const key of orderedKeys) {
4048
4098
  const res = resolutions.get(key);
4049
4099
  if (res.action === "reuse") {
@@ -4068,6 +4118,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4068
4118
  }
4069
4119
  for (const file of res.manifest.files || []) {
4070
4120
  if (file === "registry.json") continue;
4121
+ if (!includeTests && isTestFile(file)) continue;
4071
4122
  const remoteFilePath = `${folder}/${res.registryName}/${file}`;
4072
4123
  const localFilePath = path2.join(targetDir, file);
4073
4124
  if (fs4.existsSync(localFilePath) && !isOverwrite) {
@@ -4120,7 +4171,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
4120
4171
  // src/cli.ts
4121
4172
  function createCli() {
4122
4173
  const cli = cac("mason");
4123
- cli.command("[...args]", "Interactive scaffolding and import wizard").option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing files").option("-y, --yes", "Accept defaults and skip interactive prompts").option("--registry", "Run in registry mode").option("--point-to <mapping>", "Point a dependency to an existing local module (e.g. --point-to time:mytime)").option("--alias <mapping>", "Import a dependency fresh under an alias name (e.g. --alias time:time-mason)").action(async (args, flags) => {
4174
+ cli.command("[...args]", "Interactive scaffolding and import wizard").option("-d, --dry-run", "Preview changes without writing to disk").option("-o, --overwrite", "Overwrite existing files").option("-y, --yes", "Accept defaults and skip interactive prompts").option("--registry", "Run in registry mode").option("--point-to <mapping>", "Point a dependency to an existing local module (e.g. --point-to time:mytime)").option("--alias <mapping>", "Import a dependency fresh under an alias name (e.g. --alias time:time-mason)").option("--tests", "Include test files (use --no-tests to exclude)").action(async (args, flags) => {
4124
4175
  if (args && args.length > 0) {
4125
4176
  p14.log.error(
4126
4177
  pc14.red(
@@ -4215,7 +4266,7 @@ function createCli() {
4215
4266
  cli.command(
4216
4267
  "import [type] [name]",
4217
4268
  "Import pre-built shared modules or features from the Solid Stack Registry"
4218
- ).option("-o, --overwrite", "Overwrite existing files").option("-d, --dry-run", "Preview changes without writing to disk").option("-y, --yes", "Accept defaults and skip interactive prompts").option("--registry <url>", "Registry base URL or local directory").option("--skip-install", "Skip automatic package manager dependency installation").option("--point-to <mapping>", "Point a dependency to an existing local module (e.g. --point-to time:mytime)").option("--alias <mapping>", "Import a dependency fresh under an alias name (e.g. --alias time:time-mason)").example("mason import shared hasher").example("mason import feature authn").example("mason import shared").example("mason import feature").action(async (type, name, flags = {}) => {
4269
+ ).option("-o, --overwrite", "Overwrite existing files").option("-d, --dry-run", "Preview changes without writing to disk").option("-y, --yes", "Accept defaults and skip interactive prompts").option("--registry <url>", "Registry base URL or local directory").option("--skip-install", "Skip automatic package manager dependency installation").option("--point-to <mapping>", "Point a dependency to an existing local module (e.g. --point-to time:mytime)").option("--alias <mapping>", "Import a dependency fresh under an alias name (e.g. --alias time:time-mason)").option("--tests", "Include test files (use --no-tests to exclude)").example("mason import shared hasher").example("mason import feature authn").example("mason import shared").example("mason import feature").action(async (type, name, flags = {}) => {
4219
4270
  try {
4220
4271
  await handleImport(type, name, flags);
4221
4272
  } catch (err) {
@@ -4245,7 +4296,7 @@ function createCli() {
4245
4296
  });
4246
4297
  }
4247
4298
  cli.help();
4248
- cli.version("1.0.17");
4299
+ cli.version("1.0.19");
4249
4300
  return cli;
4250
4301
  }
4251
4302
  function handleCliError(err) {