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 +15 -0
- package/dist/cli.js +86 -21
- package/dist/cli.js.map +1 -1
- package/dist/feature-installer.js +14 -5
- package/dist/feature-installer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +37 -11
- package/dist/index.js.map +1 -1
- package/dist/schema.d.ts +1 -1
- package/dist/server.d.ts +1 -1
- package/dist/worker.d.ts +1 -1
- package/features/admin-page/feature.json +3 -4
- package/features/cron/feature.json +8 -5
- package/features/tasks/src/TasksPage.tsx +1 -1
- package/features/tasks/src/tasks-schema.ts +1 -1
- package/package.json +1 -1
- package/features/cron/src/cron.ts +0 -25
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(
|
|
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: [
|
|
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
|
|
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("---
|
|
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.
|
|
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
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
if (
|
|
13792
|
-
|
|
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
|
-
`${
|
|
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,
|