@solid-stack/mason 1.0.16 → 1.0.18
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/bin.cjs +184 -9
- package/dist/bin.cjs.map +1 -1
- package/dist/bin.js +184 -9
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/commands/import.d.ts +12 -2
- package/dist/commands/import.d.ts.map +1 -1
- package/dist/index.cjs +184 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +184 -9
- package/dist/index.js.map +1 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/registry.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/bin.js
CHANGED
|
@@ -146,7 +146,7 @@ function getEffectiveMode(projectRoot, flags) {
|
|
|
146
146
|
if (flags?.registry) return "registry";
|
|
147
147
|
const config = loadMasonConfig(projectRoot);
|
|
148
148
|
if (config?.mode) return config.mode;
|
|
149
|
-
if (fs9.existsSync(path2.join(projectRoot, "index.json")) && (fs9.existsSync(path2.join(projectRoot, "features")) || fs9.existsSync(path2.join(projectRoot, "shared")))
|
|
149
|
+
if (fs9.existsSync(path2.join(projectRoot, "index.json")) && (fs9.existsSync(path2.join(projectRoot, "features")) || fs9.existsSync(path2.join(projectRoot, "shared")) || fs9.existsSync(path2.join(projectRoot, "src/features")) || fs9.existsSync(path2.join(projectRoot, "src/shared")))) {
|
|
150
150
|
return "registry";
|
|
151
151
|
}
|
|
152
152
|
return "app";
|
|
@@ -160,6 +160,9 @@ function getConfiguredFeaturesDir(projectRoot, flags) {
|
|
|
160
160
|
}
|
|
161
161
|
const mode = getEffectiveMode(projectRoot, flags);
|
|
162
162
|
if (mode === "registry") {
|
|
163
|
+
if (fs9.existsSync(path2.join(projectRoot, "src/features"))) {
|
|
164
|
+
return path2.join(projectRoot, "src/features");
|
|
165
|
+
}
|
|
163
166
|
return path2.join(projectRoot, "features");
|
|
164
167
|
}
|
|
165
168
|
if (fs9.existsSync(path2.join(projectRoot, "src/features"))) {
|
|
@@ -176,6 +179,9 @@ function getConfiguredSharedDir(projectRoot, flags) {
|
|
|
176
179
|
}
|
|
177
180
|
const mode = getEffectiveMode(projectRoot, flags);
|
|
178
181
|
if (mode === "registry") {
|
|
182
|
+
if (fs9.existsSync(path2.join(projectRoot, "src/shared"))) {
|
|
183
|
+
return path2.join(projectRoot, "src/shared");
|
|
184
|
+
}
|
|
179
185
|
return path2.join(projectRoot, "shared");
|
|
180
186
|
}
|
|
181
187
|
if (fs9.existsSync(path2.join(projectRoot, "src/shared"))) {
|
|
@@ -3403,7 +3409,14 @@ async function fetchRegistryFile(registryBase, relPath) {
|
|
|
3403
3409
|
if (token) {
|
|
3404
3410
|
headers["Authorization"] = `Bearer ${token}`;
|
|
3405
3411
|
}
|
|
3406
|
-
|
|
3412
|
+
let res = await fetch(url, { headers });
|
|
3413
|
+
if (!res.ok && res.status === 404 && !cleanRelPath.startsWith("src/")) {
|
|
3414
|
+
const srcUrl = `${registryBase.replace(/\/+$/, "")}/src/${cleanRelPath}`;
|
|
3415
|
+
const srcRes = await fetch(srcUrl, { headers });
|
|
3416
|
+
if (srcRes.ok) {
|
|
3417
|
+
res = srcRes;
|
|
3418
|
+
}
|
|
3419
|
+
}
|
|
3407
3420
|
if (!res.ok) {
|
|
3408
3421
|
let extraHint = "";
|
|
3409
3422
|
if (res.status === 404) {
|
|
@@ -3423,9 +3436,14 @@ async function fetchRegistryFile(registryBase, relPath) {
|
|
|
3423
3436
|
if (baseDir.startsWith("file://")) {
|
|
3424
3437
|
baseDir = fileURLToPath(baseDir);
|
|
3425
3438
|
}
|
|
3426
|
-
|
|
3439
|
+
let filePath = path2.resolve(baseDir, cleanRelPath);
|
|
3427
3440
|
if (!fs9.existsSync(filePath)) {
|
|
3428
|
-
|
|
3441
|
+
const inSrcPath = path2.resolve(baseDir, "src", cleanRelPath);
|
|
3442
|
+
if (fs9.existsSync(inSrcPath)) {
|
|
3443
|
+
filePath = inSrcPath;
|
|
3444
|
+
} else {
|
|
3445
|
+
throw new Error(`Registry file not found at ${filePath}`);
|
|
3446
|
+
}
|
|
3429
3447
|
}
|
|
3430
3448
|
return fs9.promises.readFile(filePath, "utf-8");
|
|
3431
3449
|
}
|
|
@@ -3593,11 +3611,18 @@ function rewriteImports(content, aliasMap) {
|
|
|
3593
3611
|
return rewritten;
|
|
3594
3612
|
}
|
|
3595
3613
|
function getModuleBaseDir(projectRoot, modType) {
|
|
3614
|
+
const mode = getEffectiveMode(projectRoot);
|
|
3615
|
+
if (mode === "registry") {
|
|
3616
|
+
return modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
|
|
3617
|
+
}
|
|
3596
3618
|
const folder = modType === "shared" ? "shared" : "features";
|
|
3597
3619
|
return path2.join(projectRoot, "src", folder);
|
|
3598
3620
|
}
|
|
3599
3621
|
function getExistingModuleDir(projectRoot, modType, modName) {
|
|
3600
3622
|
const folder = modType === "shared" ? "shared" : "features";
|
|
3623
|
+
const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
|
|
3624
|
+
const inConfigured = path2.join(configuredDir, modName);
|
|
3625
|
+
if (fs9.existsSync(inConfigured)) return inConfigured;
|
|
3601
3626
|
const inSrc = path2.join(projectRoot, "src", folder, modName);
|
|
3602
3627
|
if (fs9.existsSync(inSrc)) return inSrc;
|
|
3603
3628
|
const inRoot = path2.join(projectRoot, folder, modName);
|
|
@@ -3607,6 +3632,50 @@ function getExistingModuleDir(projectRoot, modType, modName) {
|
|
|
3607
3632
|
function checkModuleExists(projectRoot, modType, modName) {
|
|
3608
3633
|
return getExistingModuleDir(projectRoot, modType, modName) !== null;
|
|
3609
3634
|
}
|
|
3635
|
+
function getAvailableLocalModules(projectRoot, modType) {
|
|
3636
|
+
const folder = modType === "shared" ? "shared" : "features";
|
|
3637
|
+
const configuredDir = modType === "shared" ? getConfiguredSharedDir(projectRoot) : getConfiguredFeaturesDir(projectRoot);
|
|
3638
|
+
const dirs = [
|
|
3639
|
+
configuredDir,
|
|
3640
|
+
path2.join(projectRoot, "src", folder),
|
|
3641
|
+
path2.join(projectRoot, folder)
|
|
3642
|
+
];
|
|
3643
|
+
const set = /* @__PURE__ */ new Set();
|
|
3644
|
+
for (const dir of dirs) {
|
|
3645
|
+
if (fs9.existsSync(dir)) {
|
|
3646
|
+
try {
|
|
3647
|
+
const entries = fs9.readdirSync(dir, { withFileTypes: true });
|
|
3648
|
+
for (const e of entries) {
|
|
3649
|
+
if (e.isDirectory() && !e.name.startsWith(".")) {
|
|
3650
|
+
set.add(e.name);
|
|
3651
|
+
}
|
|
3652
|
+
}
|
|
3653
|
+
} catch {
|
|
3654
|
+
}
|
|
3655
|
+
}
|
|
3656
|
+
}
|
|
3657
|
+
return Array.from(set).sort();
|
|
3658
|
+
}
|
|
3659
|
+
function parseMappingFlags(raw) {
|
|
3660
|
+
if (!raw) return {};
|
|
3661
|
+
if (typeof raw === "object" && !Array.isArray(raw)) return raw;
|
|
3662
|
+
const result = {};
|
|
3663
|
+
const entries = Array.isArray(raw) ? raw : [raw];
|
|
3664
|
+
for (const entry of entries) {
|
|
3665
|
+
if (typeof entry === "string") {
|
|
3666
|
+
const idx = entry.indexOf(":");
|
|
3667
|
+
if (idx !== -1) {
|
|
3668
|
+
let key = entry.slice(0, idx).trim();
|
|
3669
|
+
let val = entry.slice(idx + 1).trim();
|
|
3670
|
+
val = val.replace(/^@\/(shared|features)\//, "").replace(/^(src\/)?(shared|features)\//, "").replace(/^\/+|\/+$/g, "").trim();
|
|
3671
|
+
if (key && val) {
|
|
3672
|
+
result[key] = val;
|
|
3673
|
+
}
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
}
|
|
3677
|
+
return result;
|
|
3678
|
+
}
|
|
3610
3679
|
async function handleImport(typeArg, nameArg, flags = {}) {
|
|
3611
3680
|
const projectRoot = findProjectRoot();
|
|
3612
3681
|
let type = typeArg?.trim().toLowerCase();
|
|
@@ -3727,7 +3796,8 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3727
3796
|
const { type: modType, name: registryName, manifest } = node;
|
|
3728
3797
|
const folder = modType === "shared" ? "shared" : "features";
|
|
3729
3798
|
if (key === rootKey) {
|
|
3730
|
-
const
|
|
3799
|
+
const aliasMap2 = parseMappingFlags(flags.alias);
|
|
3800
|
+
const programmaticAlias2 = aliasMap2[registryName] || aliasMap2[`${modType}/${registryName}`];
|
|
3731
3801
|
const targetName = programmaticAlias2 || registryName;
|
|
3732
3802
|
if (targetName !== registryName) {
|
|
3733
3803
|
globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${targetName}/`);
|
|
@@ -3742,7 +3812,36 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3742
3812
|
});
|
|
3743
3813
|
continue;
|
|
3744
3814
|
}
|
|
3745
|
-
const
|
|
3815
|
+
const aliasMap = parseMappingFlags(flags.alias);
|
|
3816
|
+
const pointToMap = {
|
|
3817
|
+
...parseMappingFlags(flags.pointTo),
|
|
3818
|
+
...parseMappingFlags(flags["point-to"]),
|
|
3819
|
+
...parseMappingFlags(flags.useExisting),
|
|
3820
|
+
...parseMappingFlags(flags["use-existing"])
|
|
3821
|
+
};
|
|
3822
|
+
const programmaticPointTo = pointToMap[registryName] || pointToMap[`${modType}/${registryName}`];
|
|
3823
|
+
if (programmaticPointTo) {
|
|
3824
|
+
if (!checkModuleExists(projectRoot, modType, programmaticPointTo)) {
|
|
3825
|
+
p14.log.error(
|
|
3826
|
+
pc14.red(
|
|
3827
|
+
`Module '${programmaticPointTo}' specified in --point-to does not exist in ${folder}.`
|
|
3828
|
+
)
|
|
3829
|
+
);
|
|
3830
|
+
process.exit(1);
|
|
3831
|
+
}
|
|
3832
|
+
globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticPointTo}/`);
|
|
3833
|
+
globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticPointTo}`);
|
|
3834
|
+
p14.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${programmaticPointTo}'`);
|
|
3835
|
+
resolutions.set(key, {
|
|
3836
|
+
type: modType,
|
|
3837
|
+
registryName,
|
|
3838
|
+
targetName: programmaticPointTo,
|
|
3839
|
+
action: "reuse",
|
|
3840
|
+
manifest
|
|
3841
|
+
});
|
|
3842
|
+
continue;
|
|
3843
|
+
}
|
|
3844
|
+
const programmaticAlias = aliasMap[registryName] || aliasMap[`${modType}/${registryName}`];
|
|
3746
3845
|
if (programmaticAlias) {
|
|
3747
3846
|
globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${programmaticAlias}/`);
|
|
3748
3847
|
globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${programmaticAlias}`);
|
|
@@ -3816,6 +3915,10 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3816
3915
|
value: "keep_existing",
|
|
3817
3916
|
label: `Keep existing local version (Recommended)`
|
|
3818
3917
|
},
|
|
3918
|
+
{
|
|
3919
|
+
value: "point_existing",
|
|
3920
|
+
label: `Point to another existing ${modType} module`
|
|
3921
|
+
},
|
|
3819
3922
|
{
|
|
3820
3923
|
value: "rename",
|
|
3821
3924
|
label: "Import fresh copy under a new name (alias)"
|
|
@@ -3838,6 +3941,78 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3838
3941
|
});
|
|
3839
3942
|
continue;
|
|
3840
3943
|
}
|
|
3944
|
+
if (choice === "point_existing" || choice === "point_to_existing") {
|
|
3945
|
+
const candidates = getAvailableLocalModules(projectRoot, modType).filter(
|
|
3946
|
+
(m) => m !== registryName
|
|
3947
|
+
);
|
|
3948
|
+
let chosenName;
|
|
3949
|
+
if (candidates.length > 0) {
|
|
3950
|
+
const selection = handleCancel(
|
|
3951
|
+
await importPrompts.select({
|
|
3952
|
+
message: `Select an existing ${modType} module to point to:`,
|
|
3953
|
+
options: [
|
|
3954
|
+
...candidates.map((m) => ({
|
|
3955
|
+
value: m,
|
|
3956
|
+
label: m
|
|
3957
|
+
})),
|
|
3958
|
+
{
|
|
3959
|
+
value: "__custom__",
|
|
3960
|
+
label: "Enter name manually..."
|
|
3961
|
+
}
|
|
3962
|
+
]
|
|
3963
|
+
})
|
|
3964
|
+
);
|
|
3965
|
+
if (selection === "__custom__") {
|
|
3966
|
+
chosenName = handleCancel(
|
|
3967
|
+
await importPrompts.text({
|
|
3968
|
+
message: `Enter the name of the existing ${modType} module:`,
|
|
3969
|
+
placeholder: `my${registryName}`,
|
|
3970
|
+
validate(val) {
|
|
3971
|
+
const v = val?.trim();
|
|
3972
|
+
if (!v) return "Name cannot be empty";
|
|
3973
|
+
if (v === registryName) {
|
|
3974
|
+
return `Name must be different from '${registryName}' (or select 'Keep existing local version')`;
|
|
3975
|
+
}
|
|
3976
|
+
if (!checkModuleExists(projectRoot, modType, v)) {
|
|
3977
|
+
return `'${v}' does not exist in ${folder}`;
|
|
3978
|
+
}
|
|
3979
|
+
}
|
|
3980
|
+
})
|
|
3981
|
+
).trim();
|
|
3982
|
+
} else {
|
|
3983
|
+
chosenName = selection;
|
|
3984
|
+
}
|
|
3985
|
+
} else {
|
|
3986
|
+
chosenName = handleCancel(
|
|
3987
|
+
await importPrompts.text({
|
|
3988
|
+
message: `Enter the name of the existing ${modType} module:`,
|
|
3989
|
+
placeholder: `my${registryName}`,
|
|
3990
|
+
validate(val) {
|
|
3991
|
+
const v = val?.trim();
|
|
3992
|
+
if (!v) return "Name cannot be empty";
|
|
3993
|
+
if (v === registryName) {
|
|
3994
|
+
return `Name must be different from '${registryName}' (or select 'Keep existing local version')`;
|
|
3995
|
+
}
|
|
3996
|
+
if (!checkModuleExists(projectRoot, modType, v)) {
|
|
3997
|
+
return `'${v}' does not exist in ${folder}`;
|
|
3998
|
+
}
|
|
3999
|
+
}
|
|
4000
|
+
})
|
|
4001
|
+
).trim();
|
|
4002
|
+
}
|
|
4003
|
+
chosenName = chosenName.replace(/^@\/(shared|features)\//, "").replace(/^(src\/)?(shared|features)\//, "").replace(/^\/+|\/+$/g, "").trim();
|
|
4004
|
+
globalAliasMap.set(`@/${folder}/${registryName}/`, `@/${folder}/${chosenName}/`);
|
|
4005
|
+
globalAliasMap.set(`@/${folder}/${registryName}`, `@/${folder}/${chosenName}`);
|
|
4006
|
+
p14.log.step(`Pointing '${modType}/${registryName}' to existing '${folder}/${chosenName}'`);
|
|
4007
|
+
resolutions.set(key, {
|
|
4008
|
+
type: modType,
|
|
4009
|
+
registryName,
|
|
4010
|
+
targetName: chosenName,
|
|
4011
|
+
action: "reuse",
|
|
4012
|
+
manifest
|
|
4013
|
+
});
|
|
4014
|
+
continue;
|
|
4015
|
+
}
|
|
3841
4016
|
if (choice === "rename") {
|
|
3842
4017
|
const newName = handleCancel(
|
|
3843
4018
|
await importPrompts.text({
|
|
@@ -3965,7 +4140,7 @@ async function handleImport(typeArg, nameArg, flags = {}) {
|
|
|
3965
4140
|
// src/cli.ts
|
|
3966
4141
|
function createCli() {
|
|
3967
4142
|
const cli = cac("mason");
|
|
3968
|
-
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").action(async (args, flags) => {
|
|
4143
|
+
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) => {
|
|
3969
4144
|
if (args && args.length > 0) {
|
|
3970
4145
|
p14.log.error(
|
|
3971
4146
|
pc14.red(
|
|
@@ -4060,7 +4235,7 @@ function createCli() {
|
|
|
4060
4235
|
cli.command(
|
|
4061
4236
|
"import [type] [name]",
|
|
4062
4237
|
"Import pre-built shared modules or features from the Solid Stack Registry"
|
|
4063
|
-
).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").example("mason import shared hasher").example("mason import feature authn").example("mason import shared").example("mason import feature").action(async (type, name, flags = {}) => {
|
|
4238
|
+
).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 = {}) => {
|
|
4064
4239
|
try {
|
|
4065
4240
|
await handleImport(type, name, flags);
|
|
4066
4241
|
} catch (err) {
|
|
@@ -4090,7 +4265,7 @@ function createCli() {
|
|
|
4090
4265
|
});
|
|
4091
4266
|
}
|
|
4092
4267
|
cli.help();
|
|
4093
|
-
cli.version("1.0.
|
|
4268
|
+
cli.version("1.0.18");
|
|
4094
4269
|
return cli;
|
|
4095
4270
|
}
|
|
4096
4271
|
function handleCliError(err) {
|