@atlashub/smartstack-cli 2.7.4 → 2.9.0

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
@@ -37233,7 +37233,7 @@ var require_lodash5 = __commonJS({
37233
37233
  function isObjectLike(value) {
37234
37234
  return !!value && typeof value == "object";
37235
37235
  }
37236
- function isPlainObject(value) {
37236
+ function isPlainObject2(value) {
37237
37237
  if (!isObjectLike(value) || objectToString.call(value) != objectTag || isHostObject(value)) {
37238
37238
  return false;
37239
37239
  }
@@ -37244,7 +37244,7 @@ var require_lodash5 = __commonJS({
37244
37244
  var Ctor = hasOwnProperty.call(proto2, "constructor") && proto2.constructor;
37245
37245
  return typeof Ctor == "function" && Ctor instanceof Ctor && funcToString.call(Ctor) == objectCtorString;
37246
37246
  }
37247
- module2.exports = isPlainObject;
37247
+ module2.exports = isPlainObject2;
37248
37248
  }
37249
37249
  });
37250
37250
 
@@ -37360,7 +37360,7 @@ var require_sign = __commonJS({
37360
37360
  var isBoolean = require_lodash2();
37361
37361
  var isInteger = require_lodash3();
37362
37362
  var isNumber = require_lodash4();
37363
- var isPlainObject = require_lodash5();
37363
+ var isPlainObject2 = require_lodash5();
37364
37364
  var isString = require_lodash6();
37365
37365
  var once = require_lodash7();
37366
37366
  var { KeyObject, createSecretKey, createPrivateKey } = require("crypto");
@@ -37379,7 +37379,7 @@ var require_sign = __commonJS({
37379
37379
  return isString(value) || Array.isArray(value);
37380
37380
  }, message: '"audience" must be a string or array' },
37381
37381
  algorithm: { isValid: includes.bind(null, SUPPORTED_ALGS), message: '"algorithm" must be a valid string enum value' },
37382
- header: { isValid: isPlainObject, message: '"header" must be an object' },
37382
+ header: { isValid: isPlainObject2, message: '"header" must be an object' },
37383
37383
  encoding: { isValid: isString, message: '"encoding" must be a string' },
37384
37384
  issuer: { isValid: isString, message: '"issuer" must be a string' },
37385
37385
  subject: { isValid: isString, message: '"subject" must be a string' },
@@ -37396,7 +37396,7 @@ var require_sign = __commonJS({
37396
37396
  nbf: { isValid: isNumber, message: '"nbf" should be a number of seconds' }
37397
37397
  };
37398
37398
  function validate3(schema, allowUnknown, object, parameterName) {
37399
- if (!isPlainObject(object)) {
37399
+ if (!isPlainObject2(object)) {
37400
37400
  throw new Error('Expected "' + parameterName + '" to be a plain object.');
37401
37401
  }
37402
37402
  Object.keys(object).forEach(function(key) {
@@ -44464,16 +44464,16 @@ var require_chainedTokenCredential = __commonJS({
44464
44464
  // node_modules/uuid/dist/esm-node/rng.js
44465
44465
  function rng() {
44466
44466
  if (poolPtr > rnds8Pool.length - 16) {
44467
- import_crypto3.default.randomFillSync(rnds8Pool);
44467
+ import_crypto4.default.randomFillSync(rnds8Pool);
44468
44468
  poolPtr = 0;
44469
44469
  }
44470
44470
  return rnds8Pool.slice(poolPtr, poolPtr += 16);
44471
44471
  }
44472
- var import_crypto3, rnds8Pool, poolPtr;
44472
+ var import_crypto4, rnds8Pool, poolPtr;
44473
44473
  var init_rng = __esm({
44474
44474
  "node_modules/uuid/dist/esm-node/rng.js"() {
44475
44475
  "use strict";
44476
- import_crypto3 = __toESM(require("crypto"));
44476
+ import_crypto4 = __toESM(require("crypto"));
44477
44477
  rnds8Pool = new Uint8Array(256);
44478
44478
  poolPtr = rnds8Pool.length;
44479
44479
  }
@@ -44678,13 +44678,13 @@ function md5(bytes) {
44678
44678
  } else if (typeof bytes === "string") {
44679
44679
  bytes = Buffer.from(bytes, "utf8");
44680
44680
  }
44681
- return import_crypto4.default.createHash("md5").update(bytes).digest();
44681
+ return import_crypto5.default.createHash("md5").update(bytes).digest();
44682
44682
  }
44683
- var import_crypto4, md5_default;
44683
+ var import_crypto5, md5_default;
44684
44684
  var init_md5 = __esm({
44685
44685
  "node_modules/uuid/dist/esm-node/md5.js"() {
44686
44686
  "use strict";
44687
- import_crypto4 = __toESM(require("crypto"));
44687
+ import_crypto5 = __toESM(require("crypto"));
44688
44688
  md5_default = md5;
44689
44689
  }
44690
44690
  });
@@ -44733,13 +44733,13 @@ function sha1(bytes) {
44733
44733
  } else if (typeof bytes === "string") {
44734
44734
  bytes = Buffer.from(bytes, "utf8");
44735
44735
  }
44736
- return import_crypto5.default.createHash("sha1").update(bytes).digest();
44736
+ return import_crypto6.default.createHash("sha1").update(bytes).digest();
44737
44737
  }
44738
- var import_crypto5, sha1_default;
44738
+ var import_crypto6, sha1_default;
44739
44739
  var init_sha1 = __esm({
44740
44740
  "node_modules/uuid/dist/esm-node/sha1.js"() {
44741
44741
  "use strict";
44742
- import_crypto5 = __toESM(require("crypto"));
44742
+ import_crypto6 = __toESM(require("crypto"));
44743
44743
  sha1_default = sha1;
44744
44744
  }
44745
44745
  });
@@ -116538,6 +116538,30 @@ EndGlobal
116538
116538
  if (!dryRun) {
116539
116539
  await import_fs_extra5.default.ensureDir((0, import_path6.join)(apiDir, "wwwroot"));
116540
116540
  }
116541
+ if (!dryRun) {
116542
+ for (const { proj, type } of projects) {
116543
+ if (type === "classlib") {
116544
+ const class1Path = (0, import_path6.join)(srcDir, proj, "Class1.cs");
116545
+ if (await import_fs_extra5.default.pathExists(class1Path)) {
116546
+ await import_fs_extra5.default.remove(class1Path);
116547
+ logger.info(`Removed placeholder: ${proj}/Class1.cs`);
116548
+ }
116549
+ }
116550
+ }
116551
+ const apiPlaceholders = [
116552
+ "Program.cs",
116553
+ "appsettings.json",
116554
+ "appsettings.Development.json",
116555
+ (0, import_path6.join)("Properties", "launchSettings.json")
116556
+ ];
116557
+ for (const placeholder of apiPlaceholders) {
116558
+ const placeholderPath = (0, import_path6.join)(apiDir, placeholder);
116559
+ if (await import_fs_extra5.default.pathExists(placeholderPath)) {
116560
+ await import_fs_extra5.default.remove(placeholderPath);
116561
+ logger.info(`Removed placeholder: ${projectName}.Api/${placeholder}`);
116562
+ }
116563
+ }
116564
+ }
116541
116565
  const launchSettings = {
116542
116566
  $schema: "https://json.schemastore.org/launchsettings.json",
116543
116567
  profiles: {
@@ -116558,6 +116582,15 @@ EndGlobal
116558
116582
  environmentVariables: {
116559
116583
  ASPNETCORE_ENVIRONMENT: "Development"
116560
116584
  }
116585
+ },
116586
+ Local: {
116587
+ commandName: "Project",
116588
+ dotnetRunMessages: true,
116589
+ launchBrowser: false,
116590
+ applicationUrl: "https://localhost:7142;http://localhost:5142",
116591
+ environmentVariables: {
116592
+ ASPNETCORE_ENVIRONMENT: "Development"
116593
+ }
116561
116594
  }
116562
116595
  }
116563
116596
  };
@@ -116572,17 +116605,6 @@ EndGlobal
116572
116605
  logSafeWriteResult(launchRelPath, launchResult);
116573
116606
  recordFile(state, "backend", launchRelPath, launchResult.hash);
116574
116607
  }
116575
- if (!dryRun) {
116576
- for (const { proj, type } of projects) {
116577
- if (type === "classlib") {
116578
- const class1Path = (0, import_path6.join)(srcDir, proj, "Class1.cs");
116579
- if (await import_fs_extra5.default.pathExists(class1Path)) {
116580
- await import_fs_extra5.default.remove(class1Path);
116581
- logger.info(`Removed placeholder: ${proj}/Class1.cs`);
116582
- }
116583
- }
116584
- }
116585
- }
116586
116608
  if (!dryRun) {
116587
116609
  for (const { proj } of projects) {
116588
116610
  const csprojPath = (0, import_path6.join)(srcDir, proj, `${proj}.csproj`);
@@ -124527,7 +124549,36 @@ var glob = Object.assign(glob_, {
124527
124549
  });
124528
124550
  glob.glob = glob;
124529
124551
 
124552
+ // src/lib/config-sync.ts
124553
+ var import_crypto3 = require("crypto");
124554
+ function addMissingKeys(target, template, prefix = "") {
124555
+ const added = [];
124556
+ for (const key of Object.keys(template)) {
124557
+ const path5 = prefix ? `${prefix}.${key}` : key;
124558
+ if (!(key in target)) {
124559
+ target[key] = template[key];
124560
+ added.push(path5);
124561
+ } else if (isPlainObject(target[key]) && isPlainObject(template[key])) {
124562
+ const nested = addMissingKeys(
124563
+ target[key],
124564
+ template[key],
124565
+ path5
124566
+ );
124567
+ added.push(...nested);
124568
+ }
124569
+ }
124570
+ return added;
124571
+ }
124572
+ function resolveTemplatePlaceholders(content, projectName) {
124573
+ const secret = (0, import_crypto3.randomBytes)(32).toString("hex");
124574
+ return content.replace(/\{\{ProjectName\}\}/g, projectName).replace(/\{\{GenerateRandomSecret\}\}/g, secret).replace(/\{\{ProjectDomain\}\}/g, `${projectName.toLowerCase()}.app`).replace(/\{\{ProjectNameLower\}\}/g, projectName.toLowerCase());
124575
+ }
124576
+ function isPlainObject(value) {
124577
+ return typeof value === "object" && value !== null && !Array.isArray(value);
124578
+ }
124579
+
124530
124580
  // src/commands/upgrade.ts
124581
+ var TEMPLATES_DIR3 = (0, import_path7.join)((0, import_path7.dirname)(__dirname), "templates", "project");
124531
124582
  async function getLatestNuGetVersion2(packageName, prerelease) {
124532
124583
  try {
124533
124584
  const response = await fetch(`https://api.nuget.org/v3-flatcontainer/${packageName.toLowerCase()}/index.json`);
@@ -124785,6 +124836,51 @@ async function executeMigrations(projectDir, fromVersion, toVersion, dryRun) {
124785
124836
  hasErrors
124786
124837
  };
124787
124838
  }
124839
+ async function validateProgramCs(projectDir, baseNamespace) {
124840
+ const programPath = (0, import_path7.join)(projectDir, "src", `${baseNamespace}.Api`, "Program.cs");
124841
+ if (!await import_fs_extra6.default.pathExists(programPath)) {
124842
+ return ["Program.cs not found"];
124843
+ }
124844
+ const content = await import_fs_extra6.default.readFile(programPath, "utf-8");
124845
+ const requiredCalls = [
124846
+ { pattern: /\.AddSmartStack\s*\(/, label: "AddSmartStack()" },
124847
+ { pattern: /\.InitializeSmartStackAsync\s*\(/, label: "InitializeSmartStackAsync()" },
124848
+ { pattern: /\.UseSmartStack\s*\(/, label: "UseSmartStack()" },
124849
+ { pattern: /\.MapSmartStack\s*\(/, label: "MapSmartStack()" }
124850
+ ];
124851
+ const missing = [];
124852
+ for (const { pattern, label } of requiredCalls) {
124853
+ if (!pattern.test(content)) {
124854
+ missing.push(label);
124855
+ }
124856
+ }
124857
+ return missing;
124858
+ }
124859
+ async function syncAppSettings(projectDir, baseNamespace, dryRun) {
124860
+ const appSettingsPath = (0, import_path7.join)(projectDir, "src", `${baseNamespace}.Api`, "appsettings.json");
124861
+ if (!await import_fs_extra6.default.pathExists(appSettingsPath)) {
124862
+ logger.warning("appsettings.json not found, skipping config sync");
124863
+ return [];
124864
+ }
124865
+ const templatePath = (0, import_path7.join)(TEMPLATES_DIR3, "appsettings.json.template");
124866
+ if (!await import_fs_extra6.default.pathExists(templatePath)) {
124867
+ logger.warning("appsettings.json.template not found, skipping config sync");
124868
+ return [];
124869
+ }
124870
+ const rawTemplate = await import_fs_extra6.default.readFile(templatePath, "utf-8");
124871
+ const resolvedTemplate = resolveTemplatePlaceholders(rawTemplate, baseNamespace);
124872
+ const templateJson = JSON.parse(resolvedTemplate);
124873
+ const clientContent = await import_fs_extra6.default.readFile(appSettingsPath, "utf-8");
124874
+ const clientJson = JSON.parse(clientContent);
124875
+ const added = addMissingKeys(clientJson, templateJson);
124876
+ if (added.length === 0) {
124877
+ return [];
124878
+ }
124879
+ if (!dryRun) {
124880
+ await import_fs_extra6.default.writeFile(appSettingsPath, JSON.stringify(clientJson, null, 2));
124881
+ }
124882
+ return added;
124883
+ }
124788
124884
  var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack packages to the latest version").option("--preview", "Upgrade to latest preview/prerelease version").option("--dry-run", "Show what would be upgraded without actually upgrading").action(async (options) => {
124789
124885
  logger.header("SmartStack Package Upgrade");
124790
124886
  const dryRun = options.dryRun || false;
@@ -124796,7 +124892,9 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124796
124892
  otherPkgSkipped: 0,
124797
124893
  otherPkgFailed: 0,
124798
124894
  npmUpgraded: false,
124799
- npmSkipped: false
124895
+ npmSkipped: false,
124896
+ configSynced: 0,
124897
+ programCsIssues: []
124800
124898
  };
124801
124899
  if (dryRun) {
124802
124900
  logger.warning("DRY RUN MODE - No packages will be upgraded");
@@ -124971,6 +125069,42 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124971
125069
  logger.info("No code migrations needed.");
124972
125070
  console.log();
124973
125071
  }
125072
+ logger.info("Syncing appsettings.json...");
125073
+ const addedKeys = await syncAppSettings(projectDir, config.baseNamespace, dryRun);
125074
+ result.configSynced = addedKeys.length;
125075
+ if (addedKeys.length > 0) {
125076
+ if (dryRun) {
125077
+ logger.warning(`[DRY RUN] Would add ${addedKeys.length} new setting(s) to appsettings.json`);
125078
+ }
125079
+ for (const key of addedKeys) {
125080
+ logger.info(` ${source_default.green("+")} ${key}`);
125081
+ }
125082
+ logger.success(`${addedKeys.length} new setting(s) added to appsettings.json`);
125083
+ console.log();
125084
+ } else {
125085
+ logger.info(`appsettings.json ${source_default.green("\u2713")} up to date`);
125086
+ console.log();
125087
+ }
125088
+ logger.info("Validating Program.cs...");
125089
+ result.programCsIssues = await validateProgramCs(projectDir, config.baseNamespace);
125090
+ if (result.programCsIssues.length > 0) {
125091
+ logger.error("Program.cs is missing required SmartStack calls:");
125092
+ for (const issue of result.programCsIssues) {
125093
+ logger.warning(` ${source_default.red("\u2717")} ${issue}`);
125094
+ }
125095
+ console.log();
125096
+ logger.warning("Your Program.cs must contain these 4 calls in order:");
125097
+ logger.info(` 1. builder.Services.${source_default.cyan("AddSmartStack")}(builder.Configuration);`);
125098
+ logger.info(` 2. await app.${source_default.cyan("InitializeSmartStackAsync")}();`);
125099
+ logger.info(` 3. app.${source_default.cyan("UseSmartStack")}();`);
125100
+ logger.info(` 4. app.${source_default.cyan("MapSmartStack")}();`);
125101
+ console.log();
125102
+ logger.info(`Reference template: ${source_default.cyan("ss init --dry-run")} or check SmartStack docs`);
125103
+ console.log();
125104
+ } else {
125105
+ logger.info(`Program.cs ${source_default.green("\u2713")} all SmartStack calls present`);
125106
+ console.log();
125107
+ }
124974
125108
  if (!dryRun && nugetVersion) {
124975
125109
  config.smartStackVersion = nugetVersion;
124976
125110
  const configPath = (0, import_path7.join)(projectDir, ".smartstack", "config.json");
@@ -124978,9 +125112,10 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124978
125112
  logger.success(`Updated config version to ${source_default.cyan(nugetVersion)}`);
124979
125113
  console.log();
124980
125114
  }
124981
- const totalChanged = result.nugetUpgraded + result.otherPkgUpdated + (result.npmUpgraded ? 1 : 0) + migrationSummary.totalApplied;
125115
+ const totalChanged = result.nugetUpgraded + result.otherPkgUpdated + (result.npmUpgraded ? 1 : 0) + migrationSummary.totalApplied + result.configSynced;
124982
125116
  const allUpToDate = totalChanged === 0 && result.nugetFailed === 0 && result.otherPkgFailed === 0;
124983
- if (allUpToDate) {
125117
+ const hasProgramIssues = result.programCsIssues.length > 0;
125118
+ if (allUpToDate && !hasProgramIssues) {
124984
125119
  const summary = [
124985
125120
  source_default.green.bold("Already up to date!"),
124986
125121
  "",
@@ -124990,6 +125125,16 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
124990
125125
  "All packages at latest versions."
124991
125126
  ].filter(Boolean);
124992
125127
  logger.box(summary, "success");
125128
+ } else if (allUpToDate && hasProgramIssues) {
125129
+ const summary = [
125130
+ source_default.yellow.bold("Packages up to date, but Program.cs needs attention!"),
125131
+ "",
125132
+ ` ${source_default.red("\u26A0")} Missing: ${result.programCsIssues.join(", ")}`,
125133
+ "",
125134
+ ` Fix: Ensure Program.cs contains all 4 SmartStack bootstrap calls`,
125135
+ ` Ref: ${source_default.cyan("ss init --dry-run")} to see the correct template`
125136
+ ];
125137
+ logger.box(summary, "warning");
124993
125138
  } else {
124994
125139
  const lines = [
124995
125140
  source_default.green.bold("Upgrade completed!"),
@@ -125019,12 +125164,21 @@ var upgradeCommand = new Command("upgrade").description("Upgrade SmartStack pack
125019
125164
  if (migrationSummary.totalApplied > 0) {
125020
125165
  lines.push(` ${source_default.green("\u2713")} Code migrations: ${migrationSummary.totalApplied} applied`);
125021
125166
  }
125167
+ if (result.configSynced > 0) {
125168
+ lines.push(` ${source_default.green("\u2713")} Config: ${result.configSynced} new setting(s) added`);
125169
+ }
125170
+ if (result.programCsIssues.length > 0) {
125171
+ lines.push(` ${source_default.red("\u26A0")} Program.cs: ${result.programCsIssues.length} missing call(s) - manual fix required`);
125172
+ }
125022
125173
  lines.push("");
125023
125174
  lines.push(source_default.yellow("Next steps:"));
125175
+ if (result.programCsIssues.length > 0) {
125176
+ lines.push(` ${source_default.red("!")} Fix Program.cs first (see warnings above)`);
125177
+ }
125024
125178
  lines.push(` 1. Review changes: ${source_default.cyan("git diff")}`);
125025
125179
  lines.push(` 2. Test your application`);
125026
125180
  lines.push(` 3. Commit changes: ${source_default.cyan('git add . && git commit -m "chore: upgrade SmartStack to ' + nugetVersion + '"')}`);
125027
- logger.box(lines, "success");
125181
+ logger.box(lines, result.programCsIssues.length > 0 ? "warning" : "success");
125028
125182
  }
125029
125183
  });
125030
125184