deepspace 0.19.4 → 0.20.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/CHANGELOG.md +12 -0
- package/README.md +1 -1
- package/dist/cli.js +28 -34
- package/dist/cli.js.map +1 -1
- package/dist/index.js +24 -13
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +25 -29
- package/dist/server.js +910 -232
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +25 -29
- package/dist/worker.js +877 -199
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# deepspace
|
|
2
2
|
|
|
3
|
+
## 0.20.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Harden and simplify app-file storage with race-safe quota summaries, fixed-layout recoverable multipart reservations, strict public/private scope isolation, bounded request bodies, and safe downloadable HTML/SVG/JavaScript attachments. Quota-enabled custom handlers must now provide a coordination key.
|
|
8
|
+
|
|
9
|
+
## 0.19.5
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- The CLI's documentation pointer follows the docs cutover: `deepspace app update` guidance and the npm README now link https://docs.deep.space (documentation.deep.space is retired).
|
|
14
|
+
|
|
3
15
|
## 0.19.4
|
|
4
16
|
|
|
5
17
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -134,7 +134,7 @@ DeepSpace verifies GitHub but never writes it. Inspect or transfer authority wit
|
|
|
134
134
|
`deepspace app source deepspace`. Transfers mirror branches and tags before one
|
|
135
135
|
atomic authority change; switching back uses the same commands. Commands support
|
|
136
136
|
`--json` for agents. Use `deepspace --help`, command-specific `--help`, and the
|
|
137
|
-
[public manual](https://
|
|
137
|
+
[public manual](https://docs.deep.space) for workspaces, releases, and
|
|
138
138
|
rollback.
|
|
139
139
|
|
|
140
140
|
In a container, give Git its own credentials before a private-repository
|
package/dist/cli.js
CHANGED
|
@@ -3799,13 +3799,13 @@ var MAX_UPLOAD_REQUEST_BYTES = 25 * 1024 * 1024;
|
|
|
3799
3799
|
var UPLOAD_PART_BYTES = 20 * 1024 * 1024;
|
|
3800
3800
|
var MAX_UPLOAD_PARTS = Math.ceil(MAX_APP_FILE_BYTES / UPLOAD_PART_BYTES);
|
|
3801
3801
|
var MAX_BASE64_UPLOAD_BYTES = Math.floor(MAX_UPLOAD_REQUEST_BYTES * 3 / 4);
|
|
3802
|
-
function planUploadParts(totalBytes
|
|
3802
|
+
function planUploadParts(totalBytes) {
|
|
3803
3803
|
const parts = [];
|
|
3804
|
-
for (let start = 0; start < totalBytes; start +=
|
|
3804
|
+
for (let start = 0; start < totalBytes; start += UPLOAD_PART_BYTES) {
|
|
3805
3805
|
parts.push({
|
|
3806
3806
|
partNumber: parts.length + 1,
|
|
3807
3807
|
start,
|
|
3808
|
-
end: Math.min(start +
|
|
3808
|
+
end: Math.min(start + UPLOAD_PART_BYTES, totalBytes)
|
|
3809
3809
|
});
|
|
3810
3810
|
}
|
|
3811
3811
|
return parts;
|
|
@@ -3820,20 +3820,6 @@ var ACCOUNT_STORAGE_LIMIT_BYTES = {
|
|
|
3820
3820
|
};
|
|
3821
3821
|
var REPO_STORE_LIMIT_BYTES = 256 * 1024 * 1024;
|
|
3822
3822
|
var MAX_DEPLOY_ASSET_FILE_BYTES = 25 * 1024 * 1024;
|
|
3823
|
-
var DANGEROUS_MIME_TYPES = /* @__PURE__ */ new Set([
|
|
3824
|
-
"text/html",
|
|
3825
|
-
"application/xhtml+xml",
|
|
3826
|
-
"image/svg+xml",
|
|
3827
|
-
"application/xml",
|
|
3828
|
-
"text/xml",
|
|
3829
|
-
"application/javascript",
|
|
3830
|
-
"text/javascript",
|
|
3831
|
-
"application/ecmascript",
|
|
3832
|
-
"text/ecmascript"
|
|
3833
|
-
]);
|
|
3834
|
-
function activeContentMessage(mimeType) {
|
|
3835
|
-
return `${mimeType} is not accepted: the files API serves your app's own origin, so stored HTML/SVG/JavaScript would execute there with your users' sessions. Ship it as a build asset under \`public/\` instead, where it is served as part of your app rather than as user-uploaded content.`;
|
|
3836
|
-
}
|
|
3837
3823
|
function formatBytes(bytes) {
|
|
3838
3824
|
if (bytes >= 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024 * 1024)).toFixed(1)} GiB`;
|
|
3839
3825
|
if (bytes >= 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(1)} MiB`;
|
|
@@ -8491,9 +8477,6 @@ async function uploadAppFile(baseUrl, token, appId, localPath, key, onProgress)
|
|
|
8491
8477
|
throw new ApiError(oversizeMessage(size), 0, "too_large", path);
|
|
8492
8478
|
}
|
|
8493
8479
|
const declaredType = contentTypeFor(localPath);
|
|
8494
|
-
if (DANGEROUS_MIME_TYPES.has(declaredType)) {
|
|
8495
|
-
throw new ApiError(activeContentMessage(declaredType), 0, "active_content", path);
|
|
8496
|
-
}
|
|
8497
8480
|
if (size > UPLOAD_PART_BYTES) {
|
|
8498
8481
|
return uploadInParts(baseUrl, token, appId, localPath, key, size, onProgress);
|
|
8499
8482
|
}
|
|
@@ -8514,24 +8497,35 @@ function isRetryable(err) {
|
|
|
8514
8497
|
async function uploadInParts(baseUrl, token, appId, localPath, key, size, onProgress) {
|
|
8515
8498
|
const contentType = contentTypeFor(localPath);
|
|
8516
8499
|
const initPath = filesPath(appId, `/multipart?key=${encodeKeyPath(key)}`);
|
|
8517
|
-
const
|
|
8518
|
-
|
|
8519
|
-
|
|
8520
|
-
|
|
8521
|
-
|
|
8522
|
-
|
|
8523
|
-
|
|
8524
|
-
)
|
|
8525
|
-
|
|
8526
|
-
|
|
8500
|
+
const requestId = randomUUID2();
|
|
8501
|
+
const initBody = JSON.stringify({
|
|
8502
|
+
requestId,
|
|
8503
|
+
name: basename3(localPath),
|
|
8504
|
+
mimeType: contentType,
|
|
8505
|
+
size
|
|
8506
|
+
});
|
|
8507
|
+
const sendInit = () => request(baseUrl, token, initPath, {
|
|
8508
|
+
method: "POST",
|
|
8509
|
+
headers: { "Content-Type": "application/json" },
|
|
8510
|
+
body: initBody
|
|
8511
|
+
}).then((response) => readJson(response, initPath));
|
|
8512
|
+
let session;
|
|
8513
|
+
try {
|
|
8514
|
+
session = await sendInit();
|
|
8515
|
+
} catch (error) {
|
|
8516
|
+
if (!isRetryable(error)) throw error;
|
|
8517
|
+
session = await sendInit();
|
|
8518
|
+
}
|
|
8519
|
+
const query = `uploadKey=${encodeKeyPath(session.uploadKey)}&uploadId=${encodeURIComponent(session.uploadId)}&reservationId=${encodeURIComponent(session.reservationId)}`;
|
|
8520
|
+
if (!session.uploadId || !session.uploadKey || !session.reservationId || session.partSize !== UPLOAD_PART_BYTES) {
|
|
8527
8521
|
throw new ApiError(
|
|
8528
|
-
`The platform
|
|
8522
|
+
`The platform returned an unusable part size or multipart session (${session.partSize}).`,
|
|
8529
8523
|
0,
|
|
8530
8524
|
"invalid_response",
|
|
8531
8525
|
initPath
|
|
8532
8526
|
);
|
|
8533
8527
|
}
|
|
8534
|
-
const plan = planUploadParts(size
|
|
8528
|
+
const plan = planUploadParts(size);
|
|
8535
8529
|
const file = await openAsBlob(localPath, { type: contentType });
|
|
8536
8530
|
const uploaded = [];
|
|
8537
8531
|
try {
|
|
@@ -13628,7 +13622,7 @@ import { join as join23, resolve as resolve20 } from "path";
|
|
|
13628
13622
|
// package.json
|
|
13629
13623
|
var package_default = {
|
|
13630
13624
|
name: "deepspace",
|
|
13631
|
-
version: "0.
|
|
13625
|
+
version: "0.20.0",
|
|
13632
13626
|
engines: {
|
|
13633
13627
|
node: ">=22.15.0 <23 || >=24 <25 || >=26 <27"
|
|
13634
13628
|
},
|
|
@@ -13779,7 +13773,7 @@ var package_default = {
|
|
|
13779
13773
|
|
|
13780
13774
|
// src/cli/commands/update.ts
|
|
13781
13775
|
var REGISTRY = "https://registry.npmjs.org/deepspace/latest";
|
|
13782
|
-
var DOCS_URL = "https://
|
|
13776
|
+
var DOCS_URL = "https://docs.deep.space/cli-reference/commands";
|
|
13783
13777
|
var RELEASE_DOCS_URL = `https://github.com/deepdotspace/deepspace/blob/v${package_default.version}/docs/migrations`;
|
|
13784
13778
|
var BUILD_PREVIEW_SECRETS_GUIDE = `${RELEASE_DOCS_URL}/build-preview-secrets.md`;
|
|
13785
13779
|
var USERS_SCHEMA_VISIBILITY_GUIDE = `${RELEASE_DOCS_URL}/users-schema-member-visibility.md`;
|