deepspace 0.19.1 → 0.19.2
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 +9 -0
- package/dist/cli.js +85 -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,14 @@
|
|
|
1
1
|
# deepspace
|
|
2
2
|
|
|
3
|
+
## 0.19.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Harden post-release upgrade and scaffold behavior: pin only real package
|
|
8
|
+
dependencies, expose PresenceRoom offline state, restrict fresh user rows to
|
|
9
|
+
their owners, wire feature roles and cron tasks correctly, and remove generated
|
|
10
|
+
build-preview secrets from deploy output while guiding existing Vite configs.
|
|
11
|
+
|
|
3
12
|
## 0.19.1
|
|
4
13
|
|
|
5
14
|
### 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.2",
|
|
13607
13632
|
engines: {
|
|
13608
13633
|
node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
|
|
13609
13634
|
},
|
|
@@ -13755,6 +13780,8 @@ 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 BUILD_PREVIEW_SECRETS_GUIDE = "https://github.com/deepdotspace/deepspace-sdk/blob/main/docs/migrations/build-preview-secrets.md";
|
|
13784
|
+
var USERS_SCHEMA_VISIBILITY_GUIDE = "https://github.com/deepdotspace/deepspace-sdk/blob/main/docs/migrations/users-schema-member-visibility.md";
|
|
13758
13785
|
var COMPATIBLE_AI_VERSION = package_default.dependencies.ai;
|
|
13759
13786
|
var OLDEST_SUPPORTED_MINOR = 12;
|
|
13760
13787
|
function parseVersion(raw) {
|
|
@@ -13780,18 +13807,45 @@ function readAppSdkVersion(appDir) {
|
|
|
13780
13807
|
function pinSdkVersion(appDir, version) {
|
|
13781
13808
|
const path = join23(appDir, "package.json");
|
|
13782
13809
|
const source = readFileSync27(path, "utf8");
|
|
13783
|
-
|
|
13784
|
-
|
|
13785
|
-
|
|
13786
|
-
|
|
13787
|
-
|
|
13788
|
-
|
|
13789
|
-
|
|
13790
|
-
|
|
13791
|
-
if (
|
|
13792
|
-
|
|
13810
|
+
const manifest = JSON.parse(source);
|
|
13811
|
+
const dependencies = manifest.dependencies;
|
|
13812
|
+
if (!dependencies || typeof dependencies !== "object" || Array.isArray(dependencies)) return false;
|
|
13813
|
+
let changed = false;
|
|
13814
|
+
if (Object.prototype.hasOwnProperty.call(dependencies, "deepspace") && typeof dependencies.deepspace === "string" && dependencies.deepspace !== `^${version}`) {
|
|
13815
|
+
dependencies.deepspace = `^${version}`;
|
|
13816
|
+
changed = true;
|
|
13817
|
+
}
|
|
13818
|
+
if (Object.prototype.hasOwnProperty.call(dependencies, "ai") && typeof dependencies.ai === "string" && dependencies.ai !== COMPATIBLE_AI_VERSION) {
|
|
13819
|
+
dependencies.ai = COMPATIBLE_AI_VERSION;
|
|
13820
|
+
changed = true;
|
|
13821
|
+
}
|
|
13822
|
+
if (!changed) return false;
|
|
13823
|
+
const eol = source.includes("\r\n") ? "\r\n" : "\n";
|
|
13824
|
+
const indent = source.match(/\r?\n([\t ]+)"/)?.[1] ?? " ";
|
|
13825
|
+
const finalEol = source.endsWith("\n") ? eol : "";
|
|
13826
|
+
writeFileSync8(path, JSON.stringify(manifest, null, indent).replaceAll("\n", eol) + finalEol);
|
|
13793
13827
|
return true;
|
|
13794
13828
|
}
|
|
13829
|
+
function buildPreviewSecretsUpgradeInstruction(appDir) {
|
|
13830
|
+
const configName = [
|
|
13831
|
+
"vite.config.ts",
|
|
13832
|
+
"vite.config.mts",
|
|
13833
|
+
"vite.config.js",
|
|
13834
|
+
"vite.config.mjs"
|
|
13835
|
+
].find((candidate) => existsSync25(join23(appDir, candidate)));
|
|
13836
|
+
if (!configName) return null;
|
|
13837
|
+
const source = readFileSync27(join23(appDir, configName), "utf8");
|
|
13838
|
+
if (source.includes("deepspace-remove-build-preview-secrets")) return null;
|
|
13839
|
+
return `${configName}: add the build-preview secret cleanup from ${BUILD_PREVIEW_SECRETS_GUIDE}; app update left this app-owned file unchanged.`;
|
|
13840
|
+
}
|
|
13841
|
+
function usersSchemaVisibilityUpgradeInstruction(appDir) {
|
|
13842
|
+
const schemaName = "src/schemas/users-schema.ts";
|
|
13843
|
+
const path = join23(appDir, schemaName);
|
|
13844
|
+
if (!existsSync25(path)) return null;
|
|
13845
|
+
const source = readFileSync27(path, "utf8");
|
|
13846
|
+
if (!/\bmember\s*:\s*\{[^}]*\bread\s*:\s*true\b/s.test(source)) return null;
|
|
13847
|
+
return `${schemaName}: review the member user-row visibility change at ${USERS_SCHEMA_VISIBILITY_GUIDE}; app update left this app-owned schema unchanged.`;
|
|
13848
|
+
}
|
|
13795
13849
|
async function latestPublishedVersion() {
|
|
13796
13850
|
const response = await fetch(REGISTRY, { signal: AbortSignal.timeout(15e3) }).catch(
|
|
13797
13851
|
(error) => {
|
|
@@ -13881,27 +13935,36 @@ var update_default = defineDeepspaceCommand({
|
|
|
13881
13935
|
}
|
|
13882
13936
|
const dryRun = args["dry-run"] === true;
|
|
13883
13937
|
const plan = planAppMigrations(appDir);
|
|
13938
|
+
const previewSecretsInstruction = buildPreviewSecretsUpgradeInstruction(appDir);
|
|
13939
|
+
const usersSchemaInstruction = usersSchemaVisibilityUpgradeInstruction(appDir);
|
|
13940
|
+
const manualInstructions = [previewSecretsInstruction, usersSchemaInstruction].filter(
|
|
13941
|
+
(instruction) => instruction !== null
|
|
13942
|
+
);
|
|
13884
13943
|
const pinned = dryRun ? false : pinSdkVersion(appDir, targetRaw);
|
|
13885
13944
|
if (!dryRun && plan.edits.length) applyAppMigrationPlan(appDir, plan);
|
|
13886
13945
|
if (!args.json) {
|
|
13887
13946
|
p34.log.info(`deepspace ${currentRaw} \u2192 ${targetRaw}`);
|
|
13888
13947
|
if (pinned) p34.log.success("package.json now asks for the current SDK");
|
|
13948
|
+
for (const instruction of manualInstructions) p34.log.warn(instruction);
|
|
13889
13949
|
if (!plan.pending.length && !plan.blockers.length) {
|
|
13890
|
-
p34.log.success("No source changes required.");
|
|
13950
|
+
p34.log.success("No automatic source changes required.");
|
|
13891
13951
|
}
|
|
13892
13952
|
reportPlan(plan, !dryRun);
|
|
13893
13953
|
}
|
|
13894
|
-
if (plan.blockers.length) {
|
|
13954
|
+
if (plan.blockers.length || manualInstructions.length) {
|
|
13955
|
+
const remaining = plan.blockers.length + manualInstructions.length;
|
|
13895
13956
|
throw new Refusal(
|
|
13896
|
-
`${
|
|
13957
|
+
`${remaining} change(s) need a human or agent edit; follow the returned manual instructions and blockers.`,
|
|
13897
13958
|
"manual_changes_required",
|
|
13898
13959
|
{
|
|
13960
|
+
...pinned ? { action: cliAction("npm", "install") } : {},
|
|
13899
13961
|
actionRequired: true,
|
|
13900
13962
|
extra: {
|
|
13901
13963
|
currentVersion: currentRaw,
|
|
13902
13964
|
targetVersion: targetRaw,
|
|
13903
13965
|
applied: plan.pending.map((migration) => migration.id),
|
|
13904
|
-
blockers: plan.blockers
|
|
13966
|
+
blockers: plan.blockers,
|
|
13967
|
+
manualInstructions
|
|
13905
13968
|
}
|
|
13906
13969
|
}
|
|
13907
13970
|
);
|
|
@@ -13912,6 +13975,7 @@ var update_default = defineDeepspaceCommand({
|
|
|
13912
13975
|
targetVersion: targetRaw,
|
|
13913
13976
|
pinned,
|
|
13914
13977
|
dryRun,
|
|
13978
|
+
manualInstructions,
|
|
13915
13979
|
applied: plan.pending.map((migration) => ({
|
|
13916
13980
|
id: migration.id,
|
|
13917
13981
|
description: migration.description,
|