deepspace 0.19.1 → 0.19.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # deepspace
2
2
 
3
+ ## 0.19.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Publish the manual app-update migration guides in the public release mirror and link each updater result to its version-matched guide.
8
+
9
+ ## 0.19.2
10
+
11
+ ### Patch Changes
12
+
13
+ - Harden post-release upgrade and scaffold behavior: pin only real package
14
+ dependencies, expose PresenceRoom offline state, restrict fresh user rows to
15
+ their owners, wire feature roles and cron tasks correctly, and remove generated
16
+ build-preview secrets from deploy output while guiding existing Vite configs.
17
+
3
18
  ## 0.19.1
4
19
 
5
20
  ### Patch Changes
package/dist/cli.js CHANGED
@@ -3869,7 +3869,7 @@ function describeFilesFailure(status3, body) {
3869
3869
  import * as p6 from "@clack/prompts";
3870
3870
  import { execSync as execSync2 } from "child_process";
3871
3871
  import { createHash as createHash2 } from "crypto";
3872
- import { existsSync as existsSync14, readFileSync as readFileSync17, readdirSync as readdirSync4 } from "fs";
3872
+ import { existsSync as existsSync14, lstatSync as lstatSync2, readFileSync as readFileSync17, readdirSync as readdirSync4, unlinkSync as unlinkSync2 } from "fs";
3873
3873
  import { dirname as dirname7, join as join15, resolve as resolve11 } from "path";
3874
3874
 
3875
3875
  // src/documentation/deploy.ts
@@ -4409,6 +4409,16 @@ function findWorkerOwnedNotFoundBlockers(source, file) {
4409
4409
 
4410
4410
  // src/cli/commands/deploy/build.ts
4411
4411
  var RESERVED_RUN_WORKER_FIRST2 = new Set(RESERVED_RUN_WORKER_FIRST);
4412
+ function removeBuildDevVars(workerDir) {
4413
+ const path = join15(workerDir, ".dev.vars");
4414
+ if (!existsSync14(path)) return false;
4415
+ const stat = lstatSync2(path);
4416
+ if (!stat.isFile() || stat.isSymbolicLink()) {
4417
+ throw new Error(`Refusing unsafe build secret path: ${path}`);
4418
+ }
4419
+ unlinkSync2(path);
4420
+ return true;
4421
+ }
4412
4422
  function declaredCompatibilityDate(config) {
4413
4423
  const declared = config.compatibility_date;
4414
4424
  return typeof declared === "string" && /^\d{4}-\d{2}-\d{2}$/.test(declared) ? declared : null;
@@ -4465,6 +4475,11 @@ async function buildDeployBundle(options) {
4465
4475
  );
4466
4476
  }
4467
4477
  const workerDir = dirname7(outputWranglerPath);
4478
+ try {
4479
+ removeBuildDevVars(workerDir);
4480
+ } catch (error) {
4481
+ output.die(errorMessage(error), "build_output_unsafe");
4482
+ }
4468
4483
  const workerBundlePath = join15(workerDir, outputConfig.main);
4469
4484
  const clientDir = outputConfig.assets?.directory ? resolve11(workerDir, outputConfig.assets.directory) : null;
4470
4485
  if (!existsSync14(workerBundlePath)) {
@@ -7292,7 +7307,9 @@ function integrateCode(config, targetDir, emit) {
7292
7307
  if (insertion.import && !content.includes(insertion.import)) {
7293
7308
  const importIndex = content.search(/^import\s/m);
7294
7309
  content = `${content.slice(0, importIndex < 0 ? 0 : importIndex)}${insertion.import}
7295
- ${content.slice(importIndex < 0 ? 0 : importIndex)}`;
7310
+ ${content.slice(
7311
+ importIndex < 0 ? 0 : importIndex
7312
+ )}`;
7296
7313
  }
7297
7314
  const currentMarkerIndex = content.indexOf(insertion.marker);
7298
7315
  const insertAt = insertion.placement === "before" ? currentMarkerIndex : currentMarkerIndex + insertion.marker.length;
@@ -7446,15 +7463,22 @@ ${css}`;
7446
7463
  return unresolved;
7447
7464
  }
7448
7465
  function unresolvedRoute(route, config, reason, emit) {
7466
+ const roles = routeRolesSuffix(route);
7449
7467
  emit("");
7450
7468
  emit(" Add manually to src/nav.ts:");
7451
- emit(` { path: '${route.path}', label: '${config.name}' },`);
7469
+ emit(` { path: '${route.path}', label: '${config.name}'${roles} },`);
7452
7470
  return {
7453
7471
  area: "nav",
7454
7472
  reason,
7455
- steps: [`Add { path: '${route.path}', label: '${config.name}' } to the exported nav array.`]
7473
+ steps: [
7474
+ `Add { path: '${route.path}', label: '${config.name}'${roles} } to the exported nav array.`
7475
+ ]
7456
7476
  };
7457
7477
  }
7478
+ function routeRolesSuffix(route) {
7479
+ const roles = route.roles?.length ? route.roles : route.protected === false ? [] : ["member"];
7480
+ return roles.length ? `, roles: [${roles.map((role) => `'${role}' as Role`).join(", ")}]` : "";
7481
+ }
7458
7482
  function integrateRoute(config, targetDir, emit) {
7459
7483
  if (!config.route) return [];
7460
7484
  const navPath = join17(targetDir, "src", "nav.ts");
@@ -7478,7 +7502,7 @@ function integrateRoute(config, targetDir, emit) {
7478
7502
  )
7479
7503
  ];
7480
7504
  }
7481
- const roles = config.route.protected === false ? "" : ", roles: ['member' as Role]";
7505
+ const roles = routeRolesSuffix(config.route);
7482
7506
  const entry = ` { path: '${routePath}', label: '${config.name}'${roles} },`;
7483
7507
  content = content.replace(NAV_MARKER, `${NAV_MARKER}
7484
7508
  ${entry}`);
@@ -7674,7 +7698,7 @@ function installFeature(options) {
7674
7698
  );
7675
7699
  if (config.instructions?.length) {
7676
7700
  emit("");
7677
- emit("--- Manual wiring needed ---");
7701
+ emit("--- Next steps ---");
7678
7702
  emit("");
7679
7703
  config.instructions.forEach((instruction, index) => {
7680
7704
  emit(`${index + 1}. ${instruction}`);
@@ -8017,6 +8041,7 @@ Create one with: deepspace app create <name>`,
8017
8041
  }
8018
8042
  if (!outcome.ok) {
8019
8043
  throw new Refusal(outcome.error, outcome.code, {
8044
+ actionRequired: outcome.code === "manual_integration_required",
8020
8045
  ..."data" in outcome ? { extra: outcome.data } : {}
8021
8046
  });
8022
8047
  }
@@ -13603,7 +13628,7 @@ import { join as join23, resolve as resolve20 } from "path";
13603
13628
  // package.json
13604
13629
  var package_default = {
13605
13630
  name: "deepspace",
13606
- version: "0.19.1",
13631
+ version: "0.19.3",
13607
13632
  engines: {
13608
13633
  node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
13609
13634
  },
@@ -13755,6 +13780,9 @@ var package_default = {
13755
13780
  // src/cli/commands/update.ts
13756
13781
  var REGISTRY = "https://registry.npmjs.org/deepspace/latest";
13757
13782
  var DOCS_URL = "https://documentation.deep.space/cli-reference/commands";
13783
+ var RELEASE_DOCS_URL = `https://github.com/deepdotspace/deepspace/blob/v${package_default.version}/docs/migrations`;
13784
+ var BUILD_PREVIEW_SECRETS_GUIDE = `${RELEASE_DOCS_URL}/build-preview-secrets.md`;
13785
+ var USERS_SCHEMA_VISIBILITY_GUIDE = `${RELEASE_DOCS_URL}/users-schema-member-visibility.md`;
13758
13786
  var COMPATIBLE_AI_VERSION = package_default.dependencies.ai;
13759
13787
  var OLDEST_SUPPORTED_MINOR = 12;
13760
13788
  function parseVersion(raw) {
@@ -13780,18 +13808,45 @@ function readAppSdkVersion(appDir) {
13780
13808
  function pinSdkVersion(appDir, version) {
13781
13809
  const path = join23(appDir, "package.json");
13782
13810
  const source = readFileSync27(path, "utf8");
13783
- let updated = source.replace(
13784
- /("deepspace"\s*:\s*")[^"]+(")/,
13785
- (_match, head, tail) => `${head}^${version}${tail}`
13786
- );
13787
- updated = updated.replace(
13788
- /("ai"\s*:\s*")[^"]+(")/,
13789
- (_match, head, tail) => `${head}${COMPATIBLE_AI_VERSION}${tail}`
13790
- );
13791
- if (updated === source) return false;
13792
- writeFileSync8(path, updated);
13811
+ const manifest = JSON.parse(source);
13812
+ const dependencies = manifest.dependencies;
13813
+ if (!dependencies || typeof dependencies !== "object" || Array.isArray(dependencies)) return false;
13814
+ let changed = false;
13815
+ if (Object.prototype.hasOwnProperty.call(dependencies, "deepspace") && typeof dependencies.deepspace === "string" && dependencies.deepspace !== `^${version}`) {
13816
+ dependencies.deepspace = `^${version}`;
13817
+ changed = true;
13818
+ }
13819
+ if (Object.prototype.hasOwnProperty.call(dependencies, "ai") && typeof dependencies.ai === "string" && dependencies.ai !== COMPATIBLE_AI_VERSION) {
13820
+ dependencies.ai = COMPATIBLE_AI_VERSION;
13821
+ changed = true;
13822
+ }
13823
+ if (!changed) return false;
13824
+ const eol = source.includes("\r\n") ? "\r\n" : "\n";
13825
+ const indent = source.match(/\r?\n([\t ]+)"/)?.[1] ?? " ";
13826
+ const finalEol = source.endsWith("\n") ? eol : "";
13827
+ writeFileSync8(path, JSON.stringify(manifest, null, indent).replaceAll("\n", eol) + finalEol);
13793
13828
  return true;
13794
13829
  }
13830
+ function buildPreviewSecretsUpgradeInstruction(appDir) {
13831
+ const configName = [
13832
+ "vite.config.ts",
13833
+ "vite.config.mts",
13834
+ "vite.config.js",
13835
+ "vite.config.mjs"
13836
+ ].find((candidate) => existsSync25(join23(appDir, candidate)));
13837
+ if (!configName) return null;
13838
+ const source = readFileSync27(join23(appDir, configName), "utf8");
13839
+ if (source.includes("deepspace-remove-build-preview-secrets")) return null;
13840
+ return `${configName}: add the build-preview secret cleanup from ${BUILD_PREVIEW_SECRETS_GUIDE}; app update left this app-owned file unchanged.`;
13841
+ }
13842
+ function usersSchemaVisibilityUpgradeInstruction(appDir) {
13843
+ const schemaName = "src/schemas/users-schema.ts";
13844
+ const path = join23(appDir, schemaName);
13845
+ if (!existsSync25(path)) return null;
13846
+ const source = readFileSync27(path, "utf8");
13847
+ if (!/\bmember\s*:\s*\{[^}]*\bread\s*:\s*true\b/s.test(source)) return null;
13848
+ return `${schemaName}: review the member user-row visibility change at ${USERS_SCHEMA_VISIBILITY_GUIDE}; app update left this app-owned schema unchanged.`;
13849
+ }
13795
13850
  async function latestPublishedVersion() {
13796
13851
  const response = await fetch(REGISTRY, { signal: AbortSignal.timeout(15e3) }).catch(
13797
13852
  (error) => {
@@ -13881,27 +13936,36 @@ var update_default = defineDeepspaceCommand({
13881
13936
  }
13882
13937
  const dryRun = args["dry-run"] === true;
13883
13938
  const plan = planAppMigrations(appDir);
13939
+ const previewSecretsInstruction = buildPreviewSecretsUpgradeInstruction(appDir);
13940
+ const usersSchemaInstruction = usersSchemaVisibilityUpgradeInstruction(appDir);
13941
+ const manualInstructions = [previewSecretsInstruction, usersSchemaInstruction].filter(
13942
+ (instruction) => instruction !== null
13943
+ );
13884
13944
  const pinned = dryRun ? false : pinSdkVersion(appDir, targetRaw);
13885
13945
  if (!dryRun && plan.edits.length) applyAppMigrationPlan(appDir, plan);
13886
13946
  if (!args.json) {
13887
13947
  p34.log.info(`deepspace ${currentRaw} \u2192 ${targetRaw}`);
13888
13948
  if (pinned) p34.log.success("package.json now asks for the current SDK");
13949
+ for (const instruction of manualInstructions) p34.log.warn(instruction);
13889
13950
  if (!plan.pending.length && !plan.blockers.length) {
13890
- p34.log.success("No source changes required.");
13951
+ p34.log.success("No automatic source changes required.");
13891
13952
  }
13892
13953
  reportPlan(plan, !dryRun);
13893
13954
  }
13894
- if (plan.blockers.length) {
13955
+ if (plan.blockers.length || manualInstructions.length) {
13956
+ const remaining = plan.blockers.length + manualInstructions.length;
13895
13957
  throw new Refusal(
13896
- `${plan.blockers.length} change(s) need a human or agent edit; each is listed above with its file, line, and the change required.`,
13958
+ `${remaining} change(s) need a human or agent edit; follow the returned manual instructions and blockers.`,
13897
13959
  "manual_changes_required",
13898
13960
  {
13961
+ ...pinned ? { action: cliAction("npm", "install") } : {},
13899
13962
  actionRequired: true,
13900
13963
  extra: {
13901
13964
  currentVersion: currentRaw,
13902
13965
  targetVersion: targetRaw,
13903
13966
  applied: plan.pending.map((migration) => migration.id),
13904
- blockers: plan.blockers
13967
+ blockers: plan.blockers,
13968
+ manualInstructions
13905
13969
  }
13906
13970
  }
13907
13971
  );
@@ -13912,6 +13976,7 @@ var update_default = defineDeepspaceCommand({
13912
13976
  targetVersion: targetRaw,
13913
13977
  pinned,
13914
13978
  dryRun,
13979
+ manualInstructions,
13915
13980
  applied: plan.pending.map((migration) => ({
13916
13981
  id: migration.id,
13917
13982
  description: migration.description,