@sasjs/api 0.12.0 → 0.13.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/build/browser.js +96 -6
- package/build/cjs/corpus/deploy.js +89 -0
- package/build/cjs/host/dispatch.js +6 -0
- package/build/cjs/routes/overlay.js +1 -5
- package/build/esm/corpus/deploy.d.ts.map +1 -1
- package/build/esm/corpus/deploy.js +89 -0
- package/build/esm/host/dispatch.d.ts.map +1 -1
- package/build/esm/host/dispatch.js +6 -0
- package/build/esm/routes/overlay.d.ts.map +1 -1
- package/build/esm/routes/overlay.js +1 -5
- package/package.json +1 -1
package/build/browser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* @sasjs/api 0.
|
|
1
|
+
/* @sasjs/api 0.13.0 - the SASjs Server API, for a service worker. https://github.com/sasjs/api */
|
|
2
2
|
"use strict";
|
|
3
3
|
var SASjsApi = (() => {
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
@@ -2514,7 +2514,6 @@ var SASjsApi = (() => {
|
|
|
2514
2514
|
var HOST_CONFIG = "The body is the host's own configuration - ports, run times and providers - which a mock states for itself and this package cannot know.";
|
|
2515
2515
|
var HOST_OWNED = "The host owns this report: it describes the host's own process and files, which a browser build has no equivalent of.";
|
|
2516
2516
|
var WEB_BUNDLE = "The host serves its own web bundle; there is no API decision here for this package to answer.";
|
|
2517
|
-
var ARCHIVE = "Expanding the uploaded archive is the host's transport work - multer and a zip library on the server, `DecompressionStream` in a worker - and the host hands this package the tree it produces, which is the same tree `POST /SASjsApi/drive/deploy` takes.";
|
|
2518
2517
|
var success = { status: "success" };
|
|
2519
2518
|
var user = {
|
|
2520
2519
|
uid: "",
|
|
@@ -2642,10 +2641,7 @@ var SASjsApi = (() => {
|
|
|
2642
2641
|
500: { status: "failure", message: "Deployment failed!" }
|
|
2643
2642
|
}
|
|
2644
2643
|
},
|
|
2645
|
-
"POST /SASjsApi/drive/deploy/upload": {
|
|
2646
|
-
implemented: false,
|
|
2647
|
-
reason: ARCHIVE
|
|
2648
|
-
},
|
|
2644
|
+
"POST /SASjsApi/drive/deploy/upload": { implemented: true },
|
|
2649
2645
|
// `404` is a pair - the registry name and the appLoc it was published from -
|
|
2650
2646
|
// that matches no entry, and the drive's content is deliberately left alone.
|
|
2651
2647
|
"DELETE /SASjsApi/drive/deploy": { implemented: true },
|
|
@@ -2966,6 +2962,11 @@ var SASjsApi = (() => {
|
|
|
2966
2962
|
String(request.body?.newPath || "")
|
|
2967
2963
|
)
|
|
2968
2964
|
};
|
|
2965
|
+
// The archive is the host's transport - multer and a zip library on a
|
|
2966
|
+
// server, `DecompressionStream` in a worker - and it hands this the same tree
|
|
2967
|
+
// `POST /deploy` takes. The deploy cap is measured on that tree, after
|
|
2968
|
+
// expansion, which is why the two share this path rather than reading bytes.
|
|
2969
|
+
case "POST /SASjsApi/drive/deploy/upload":
|
|
2969
2970
|
case "POST /SASjsApi/drive/deploy": {
|
|
2970
2971
|
await drive.deploy(String(body.appLoc ?? ""), body.fileTree);
|
|
2971
2972
|
return { status: 200, body: DEPLOY_SUCCESS };
|
|
@@ -3234,6 +3235,7 @@ var SASjsApi = (() => {
|
|
|
3234
3235
|
}
|
|
3235
3236
|
};
|
|
3236
3237
|
var HANDLED_ROUTES = [
|
|
3238
|
+
"POST /SASjsApi/drive/deploy/upload",
|
|
3237
3239
|
"DELETE /SASjsApi/drive/deploy",
|
|
3238
3240
|
"GET /SASjsApi/session/{sessionId}",
|
|
3239
3241
|
"GET /SASjsApi/session/{sessionId}/log",
|
|
@@ -4958,6 +4960,11 @@ var SASjsApi = (() => {
|
|
|
4958
4960
|
|
|
4959
4961
|
// src/corpus/deploy.ts
|
|
4960
4962
|
var SUBJECT = { userId: "user-admin", clientId: "web_app" };
|
|
4963
|
+
var manyMembers2 = (count) => Array.from({ length: count }, (_, at) => ({
|
|
4964
|
+
name: `file-${at}.txt`,
|
|
4965
|
+
type: "file",
|
|
4966
|
+
code: ""
|
|
4967
|
+
}));
|
|
4961
4968
|
var DEPLOY_CORPUS = [
|
|
4962
4969
|
{
|
|
4963
4970
|
id: "deploy-unpublish",
|
|
@@ -5002,6 +5009,89 @@ var SASjsApi = (() => {
|
|
|
5002
5009
|
body: { streamServiceName: "myApp", appLoc: "/Public/not-an-app" }
|
|
5003
5010
|
},
|
|
5004
5011
|
expect: { status: 404, error: "No such app stream entry." }
|
|
5012
|
+
},
|
|
5013
|
+
// ------------------------------------------- the uploaded-archive route
|
|
5014
|
+
// The archive is expanded by the host, so what arrives here is the same tree
|
|
5015
|
+
// `POST /deploy` takes - which is why every answer below matches its twin.
|
|
5016
|
+
{
|
|
5017
|
+
id: "upload-tree",
|
|
5018
|
+
route: "POST /SASjsApi/drive/deploy/upload",
|
|
5019
|
+
description: "writes the tree an uploaded archive expanded to",
|
|
5020
|
+
request: {
|
|
5021
|
+
subject: SUBJECT,
|
|
5022
|
+
body: {
|
|
5023
|
+
appLoc: "/Public/apps/uploaded",
|
|
5024
|
+
fileTree: {
|
|
5025
|
+
members: [
|
|
5026
|
+
{ name: "index.html", type: "file", code: "PGgxPkhlbGxvPC9oMT4=" }
|
|
5027
|
+
]
|
|
5028
|
+
}
|
|
5029
|
+
}
|
|
5030
|
+
},
|
|
5031
|
+
expect: {
|
|
5032
|
+
status: 200,
|
|
5033
|
+
body: {
|
|
5034
|
+
status: "success",
|
|
5035
|
+
message: "Files deployed successfully to @sasjs/server."
|
|
5036
|
+
}
|
|
5037
|
+
}
|
|
5038
|
+
},
|
|
5039
|
+
{
|
|
5040
|
+
id: "upload-refused-by-shape",
|
|
5041
|
+
route: "POST /SASjsApi/drive/deploy/upload",
|
|
5042
|
+
description: "refuses an expansion that is not a tree",
|
|
5043
|
+
request: {
|
|
5044
|
+
subject: SUBJECT,
|
|
5045
|
+
body: { appLoc: "/Public/apps/bad", fileTree: { members: 1 } }
|
|
5046
|
+
},
|
|
5047
|
+
expect: {
|
|
5048
|
+
status: 400,
|
|
5049
|
+
body: {
|
|
5050
|
+
status: "failure",
|
|
5051
|
+
message: "Provided not supported data format."
|
|
5052
|
+
},
|
|
5053
|
+
error: "Provided not supported data format."
|
|
5054
|
+
}
|
|
5055
|
+
},
|
|
5056
|
+
{
|
|
5057
|
+
id: "upload-refused-by-entry-count",
|
|
5058
|
+
route: "POST /SASjsApi/drive/deploy/upload",
|
|
5059
|
+
description: "applies the deploy cap to the expanded tree, not the bytes",
|
|
5060
|
+
request: {
|
|
5061
|
+
subject: SUBJECT,
|
|
5062
|
+
body: {
|
|
5063
|
+
appLoc: "/Public/apps/many",
|
|
5064
|
+
fileTree: { members: manyMembers2(10001) }
|
|
5065
|
+
}
|
|
5066
|
+
},
|
|
5067
|
+
expect: {
|
|
5068
|
+
status: 413,
|
|
5069
|
+
body: {
|
|
5070
|
+
status: "failure",
|
|
5071
|
+
message: "The file tree exceeds the deploy limit: 10001 entries (maximum 10000)."
|
|
5072
|
+
},
|
|
5073
|
+
error: "The file tree exceeds the deploy limit: 10001 entries (maximum 10000)."
|
|
5074
|
+
}
|
|
5075
|
+
},
|
|
5076
|
+
{
|
|
5077
|
+
id: "upload-refused-by-store",
|
|
5078
|
+
route: "POST /SASjsApi/drive/deploy/upload",
|
|
5079
|
+
description: "answers the routes 500 when the drive refuses the write",
|
|
5080
|
+
unwritable: true,
|
|
5081
|
+
request: {
|
|
5082
|
+
subject: SUBJECT,
|
|
5083
|
+
body: {
|
|
5084
|
+
appLoc: "/Public/apps/demo",
|
|
5085
|
+
fileTree: {
|
|
5086
|
+
members: [{ name: "run", type: "service", code: "%put hi;" }]
|
|
5087
|
+
}
|
|
5088
|
+
}
|
|
5089
|
+
},
|
|
5090
|
+
expect: {
|
|
5091
|
+
status: 500,
|
|
5092
|
+
body: { status: "failure", message: "Deployment failed!" },
|
|
5093
|
+
error: "Deployment failed!"
|
|
5094
|
+
}
|
|
5005
5095
|
}
|
|
5006
5096
|
];
|
|
5007
5097
|
|
|
@@ -2,6 +2,12 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.DEPLOY_CORPUS = void 0;
|
|
4
4
|
const SUBJECT = { userId: 'user-admin', clientId: 'web_app' };
|
|
5
|
+
/** A tree of `count` file members, for the deploy cap. */
|
|
6
|
+
const manyMembers = (count) => Array.from({ length: count }, (_, at) => ({
|
|
7
|
+
name: `file-${at}.txt`,
|
|
8
|
+
type: 'file',
|
|
9
|
+
code: ''
|
|
10
|
+
}));
|
|
5
11
|
exports.DEPLOY_CORPUS = [
|
|
6
12
|
{
|
|
7
13
|
id: 'deploy-unpublish',
|
|
@@ -46,5 +52,88 @@ exports.DEPLOY_CORPUS = [
|
|
|
46
52
|
body: { streamServiceName: 'myApp', appLoc: '/Public/not-an-app' }
|
|
47
53
|
},
|
|
48
54
|
expect: { status: 404, error: 'No such app stream entry.' }
|
|
55
|
+
},
|
|
56
|
+
// ------------------------------------------- the uploaded-archive route
|
|
57
|
+
// The archive is expanded by the host, so what arrives here is the same tree
|
|
58
|
+
// `POST /deploy` takes - which is why every answer below matches its twin.
|
|
59
|
+
{
|
|
60
|
+
id: 'upload-tree',
|
|
61
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
62
|
+
description: 'writes the tree an uploaded archive expanded to',
|
|
63
|
+
request: {
|
|
64
|
+
subject: SUBJECT,
|
|
65
|
+
body: {
|
|
66
|
+
appLoc: '/Public/apps/uploaded',
|
|
67
|
+
fileTree: {
|
|
68
|
+
members: [
|
|
69
|
+
{ name: 'index.html', type: 'file', code: 'PGgxPkhlbGxvPC9oMT4=' }
|
|
70
|
+
]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
expect: {
|
|
75
|
+
status: 200,
|
|
76
|
+
body: {
|
|
77
|
+
status: 'success',
|
|
78
|
+
message: 'Files deployed successfully to @sasjs/server.'
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: 'upload-refused-by-shape',
|
|
84
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
85
|
+
description: 'refuses an expansion that is not a tree',
|
|
86
|
+
request: {
|
|
87
|
+
subject: SUBJECT,
|
|
88
|
+
body: { appLoc: '/Public/apps/bad', fileTree: { members: 1 } }
|
|
89
|
+
},
|
|
90
|
+
expect: {
|
|
91
|
+
status: 400,
|
|
92
|
+
body: {
|
|
93
|
+
status: 'failure',
|
|
94
|
+
message: 'Provided not supported data format.'
|
|
95
|
+
},
|
|
96
|
+
error: 'Provided not supported data format.'
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
id: 'upload-refused-by-entry-count',
|
|
101
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
102
|
+
description: 'applies the deploy cap to the expanded tree, not the bytes',
|
|
103
|
+
request: {
|
|
104
|
+
subject: SUBJECT,
|
|
105
|
+
body: {
|
|
106
|
+
appLoc: '/Public/apps/many',
|
|
107
|
+
fileTree: { members: manyMembers(10001) }
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
expect: {
|
|
111
|
+
status: 413,
|
|
112
|
+
body: {
|
|
113
|
+
status: 'failure',
|
|
114
|
+
message: 'The file tree exceeds the deploy limit: 10001 entries (maximum 10000).'
|
|
115
|
+
},
|
|
116
|
+
error: 'The file tree exceeds the deploy limit: 10001 entries (maximum 10000).'
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
id: 'upload-refused-by-store',
|
|
121
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
122
|
+
description: 'answers the routes 500 when the drive refuses the write',
|
|
123
|
+
unwritable: true,
|
|
124
|
+
request: {
|
|
125
|
+
subject: SUBJECT,
|
|
126
|
+
body: {
|
|
127
|
+
appLoc: '/Public/apps/demo',
|
|
128
|
+
fileTree: {
|
|
129
|
+
members: [{ name: 'run', type: 'service', code: '%put hi;' }]
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
},
|
|
133
|
+
expect: {
|
|
134
|
+
status: 500,
|
|
135
|
+
body: { status: 'failure', message: 'Deployment failed!' },
|
|
136
|
+
error: 'Deployment failed!'
|
|
137
|
+
}
|
|
49
138
|
}
|
|
50
139
|
];
|
|
@@ -170,6 +170,11 @@ const dispatch = async (services, routeId, request = {}) => {
|
|
|
170
170
|
status: 200,
|
|
171
171
|
body: await drive.rename(String(request.body?.oldPath || ''), String(request.body?.newPath || ''))
|
|
172
172
|
};
|
|
173
|
+
// The archive is the host's transport - multer and a zip library on a
|
|
174
|
+
// server, `DecompressionStream` in a worker - and it hands this the same tree
|
|
175
|
+
// `POST /deploy` takes. The deploy cap is measured on that tree, after
|
|
176
|
+
// expansion, which is why the two share this path rather than reading bytes.
|
|
177
|
+
case 'POST /SASjsApi/drive/deploy/upload':
|
|
173
178
|
case 'POST /SASjsApi/drive/deploy': {
|
|
174
179
|
// `streamWebFolder` is the host's: publishing an app stream is not a drive
|
|
175
180
|
// operation, and a host that has no app stream ignores it.
|
|
@@ -396,6 +401,7 @@ const dispatch = async (services, routeId, request = {}) => {
|
|
|
396
401
|
exports.dispatch = dispatch;
|
|
397
402
|
/** Whether a route is one `dispatch` can answer today. */
|
|
398
403
|
exports.HANDLED_ROUTES = [
|
|
404
|
+
'POST /SASjsApi/drive/deploy/upload',
|
|
399
405
|
'DELETE /SASjsApi/drive/deploy',
|
|
400
406
|
'GET /SASjsApi/session/{sessionId}',
|
|
401
407
|
'GET /SASjsApi/session/{sessionId}/log',
|
|
@@ -30,7 +30,6 @@ const RUNTIME = 'Starting a program needs a runtime port, which this package doe
|
|
|
30
30
|
const HOST_CONFIG = "The body is the host's own configuration - ports, run times and providers - which a mock states for itself and this package cannot know.";
|
|
31
31
|
const HOST_OWNED = "The host owns this report: it describes the host's own process and files, which a browser build has no equivalent of.";
|
|
32
32
|
const WEB_BUNDLE = 'The host serves its own web bundle; there is no API decision here for this package to answer.';
|
|
33
|
-
const ARCHIVE = "Expanding the uploaded archive is the host's transport work - multer and a zip library on the server, `DecompressionStream` in a worker - and the host hands this package the tree it produces, which is the same tree `POST /SASjsApi/drive/deploy` takes.";
|
|
34
33
|
const success = { status: 'success' };
|
|
35
34
|
const user = {
|
|
36
35
|
uid: '',
|
|
@@ -158,10 +157,7 @@ exports.OVERLAY = {
|
|
|
158
157
|
500: { status: 'failure', message: 'Deployment failed!' }
|
|
159
158
|
}
|
|
160
159
|
},
|
|
161
|
-
'POST /SASjsApi/drive/deploy/upload': {
|
|
162
|
-
implemented: false,
|
|
163
|
-
reason: ARCHIVE
|
|
164
|
-
},
|
|
160
|
+
'POST /SASjsApi/drive/deploy/upload': { implemented: true },
|
|
165
161
|
// `404` is a pair - the registry name and the appLoc it was published from -
|
|
166
162
|
// that matches no entry, and the drive's content is deliberately left alone.
|
|
167
163
|
'DELETE /SASjsApi/drive/deploy': { implemented: true },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/corpus/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../../src/corpus/deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAW5C,eAAO,MAAM,aAAa,EAAE,UAAU,EAmIrC,CAAA"}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
const SUBJECT = { userId: 'user-admin', clientId: 'web_app' };
|
|
2
|
+
/** A tree of `count` file members, for the deploy cap. */
|
|
3
|
+
const manyMembers = (count) => Array.from({ length: count }, (_, at) => ({
|
|
4
|
+
name: `file-${at}.txt`,
|
|
5
|
+
type: 'file',
|
|
6
|
+
code: ''
|
|
7
|
+
}));
|
|
2
8
|
export const DEPLOY_CORPUS = [
|
|
3
9
|
{
|
|
4
10
|
id: 'deploy-unpublish',
|
|
@@ -43,5 +49,88 @@ export const DEPLOY_CORPUS = [
|
|
|
43
49
|
body: { streamServiceName: 'myApp', appLoc: '/Public/not-an-app' }
|
|
44
50
|
},
|
|
45
51
|
expect: { status: 404, error: 'No such app stream entry.' }
|
|
52
|
+
},
|
|
53
|
+
// ------------------------------------------- the uploaded-archive route
|
|
54
|
+
// The archive is expanded by the host, so what arrives here is the same tree
|
|
55
|
+
// `POST /deploy` takes - which is why every answer below matches its twin.
|
|
56
|
+
{
|
|
57
|
+
id: 'upload-tree',
|
|
58
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
59
|
+
description: 'writes the tree an uploaded archive expanded to',
|
|
60
|
+
request: {
|
|
61
|
+
subject: SUBJECT,
|
|
62
|
+
body: {
|
|
63
|
+
appLoc: '/Public/apps/uploaded',
|
|
64
|
+
fileTree: {
|
|
65
|
+
members: [
|
|
66
|
+
{ name: 'index.html', type: 'file', code: 'PGgxPkhlbGxvPC9oMT4=' }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
},
|
|
71
|
+
expect: {
|
|
72
|
+
status: 200,
|
|
73
|
+
body: {
|
|
74
|
+
status: 'success',
|
|
75
|
+
message: 'Files deployed successfully to @sasjs/server.'
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
id: 'upload-refused-by-shape',
|
|
81
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
82
|
+
description: 'refuses an expansion that is not a tree',
|
|
83
|
+
request: {
|
|
84
|
+
subject: SUBJECT,
|
|
85
|
+
body: { appLoc: '/Public/apps/bad', fileTree: { members: 1 } }
|
|
86
|
+
},
|
|
87
|
+
expect: {
|
|
88
|
+
status: 400,
|
|
89
|
+
body: {
|
|
90
|
+
status: 'failure',
|
|
91
|
+
message: 'Provided not supported data format.'
|
|
92
|
+
},
|
|
93
|
+
error: 'Provided not supported data format.'
|
|
94
|
+
}
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
id: 'upload-refused-by-entry-count',
|
|
98
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
99
|
+
description: 'applies the deploy cap to the expanded tree, not the bytes',
|
|
100
|
+
request: {
|
|
101
|
+
subject: SUBJECT,
|
|
102
|
+
body: {
|
|
103
|
+
appLoc: '/Public/apps/many',
|
|
104
|
+
fileTree: { members: manyMembers(10001) }
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
expect: {
|
|
108
|
+
status: 413,
|
|
109
|
+
body: {
|
|
110
|
+
status: 'failure',
|
|
111
|
+
message: 'The file tree exceeds the deploy limit: 10001 entries (maximum 10000).'
|
|
112
|
+
},
|
|
113
|
+
error: 'The file tree exceeds the deploy limit: 10001 entries (maximum 10000).'
|
|
114
|
+
}
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
id: 'upload-refused-by-store',
|
|
118
|
+
route: 'POST /SASjsApi/drive/deploy/upload',
|
|
119
|
+
description: 'answers the routes 500 when the drive refuses the write',
|
|
120
|
+
unwritable: true,
|
|
121
|
+
request: {
|
|
122
|
+
subject: SUBJECT,
|
|
123
|
+
body: {
|
|
124
|
+
appLoc: '/Public/apps/demo',
|
|
125
|
+
fileTree: {
|
|
126
|
+
members: [{ name: 'run', type: 'service', code: '%put hi;' }]
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
expect: {
|
|
131
|
+
status: 500,
|
|
132
|
+
body: { status: 'failure', message: 'Deployment failed!' },
|
|
133
|
+
error: 'Deployment failed!'
|
|
134
|
+
}
|
|
46
135
|
}
|
|
47
136
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/host/dispatch.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAOnD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,oFAAoF;IACpF,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;IACtD;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,mBAAmB;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,YAAY,CAAA;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B,yFAAyF;IACzF,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAC7B;AA2CD,eAAO,MAAM,QAAQ,GACnB,UAAU,QAAQ,EAClB,SAAS,MAAM,EACf,UAAS,UAAe,KACvB,OAAO,CAAC,WAAW,
|
|
1
|
+
{"version":3,"file":"dispatch.d.ts","sourceRoot":"","sources":["../../../src/host/dispatch.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAA;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAA;AAE7D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAA;AAOnD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAA;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC9B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,oFAAoF;IACpF,IAAI,CAAC,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;KAAE,CAAA;IACtD;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAA;IACd,mBAAmB;IACnB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,GAAG,UAAU,CAAA;CAC/B;AAED,MAAM,WAAW,QAAQ;IACvB,2DAA2D;IAC3D,IAAI,CAAC,EAAE,WAAW,CAAA;IAClB,KAAK,EAAE,YAAY,CAAA;IACnB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,eAAe,CAAA;IAC1B,yFAAyF;IACzF,OAAO,CAAC,EAAE,aAAa,CAAA;IACvB;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB;;;OAGG;IACH,QAAQ,CAAC,EAAE,iBAAiB,CAAA;CAC7B;AA2CD,eAAO,MAAM,QAAQ,GACnB,UAAU,QAAQ,EAClB,SAAS,MAAM,EACf,UAAS,UAAe,KACvB,OAAO,CAAC,WAAW,CA8crB,CAAA;AAED,0DAA0D;AAC1D,eAAO,MAAM,cAAc,EAAE,MAAM,EAkDlC,CAAA"}
|
|
@@ -167,6 +167,11 @@ export const dispatch = async (services, routeId, request = {}) => {
|
|
|
167
167
|
status: 200,
|
|
168
168
|
body: await drive.rename(String(request.body?.oldPath || ''), String(request.body?.newPath || ''))
|
|
169
169
|
};
|
|
170
|
+
// The archive is the host's transport - multer and a zip library on a
|
|
171
|
+
// server, `DecompressionStream` in a worker - and it hands this the same tree
|
|
172
|
+
// `POST /deploy` takes. The deploy cap is measured on that tree, after
|
|
173
|
+
// expansion, which is why the two share this path rather than reading bytes.
|
|
174
|
+
case 'POST /SASjsApi/drive/deploy/upload':
|
|
170
175
|
case 'POST /SASjsApi/drive/deploy': {
|
|
171
176
|
// `streamWebFolder` is the host's: publishing an app stream is not a drive
|
|
172
177
|
// operation, and a host that has no app stream ignores it.
|
|
@@ -392,6 +397,7 @@ export const dispatch = async (services, routeId, request = {}) => {
|
|
|
392
397
|
};
|
|
393
398
|
/** Whether a route is one `dispatch` can answer today. */
|
|
394
399
|
export const HANDLED_ROUTES = [
|
|
400
|
+
'POST /SASjsApi/drive/deploy/upload',
|
|
395
401
|
'DELETE /SASjsApi/drive/deploy',
|
|
396
402
|
'GET /SASjsApi/session/{sessionId}',
|
|
397
403
|
'GET /SASjsApi/session/{sessionId}/log',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../src/routes/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGzD,yDAAyD;AACzD,UAAU,aAAa;IACrB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;IAC3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GACtC,CAAC;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,WAAW,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAElE,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAczD,CAAA;
|
|
1
|
+
{"version":3,"file":"overlay.d.ts","sourceRoot":"","sources":["../../../src/routes/overlay.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AAGzD,yDAAyD;AACzD,UAAU,aAAa;IACrB,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;IAC3B;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;IACxB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CACpC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,YAAY,GAAG,aAAa,GACtC,CAAC;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,WAAW,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAC,CAAA;AAElE,kFAAkF;AAClF,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,EAAE,CAczD,CAAA;AAkCD,eAAO,MAAM,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CA0MhD,CAAA;AAED,wEAAwE;AACxE,eAAO,MAAM,OAAO,EAAE,UAAU,EAA8C,CAAA"}
|
|
@@ -27,7 +27,6 @@ const RUNTIME = 'Starting a program needs a runtime port, which this package doe
|
|
|
27
27
|
const HOST_CONFIG = "The body is the host's own configuration - ports, run times and providers - which a mock states for itself and this package cannot know.";
|
|
28
28
|
const HOST_OWNED = "The host owns this report: it describes the host's own process and files, which a browser build has no equivalent of.";
|
|
29
29
|
const WEB_BUNDLE = 'The host serves its own web bundle; there is no API decision here for this package to answer.';
|
|
30
|
-
const ARCHIVE = "Expanding the uploaded archive is the host's transport work - multer and a zip library on the server, `DecompressionStream` in a worker - and the host hands this package the tree it produces, which is the same tree `POST /SASjsApi/drive/deploy` takes.";
|
|
31
30
|
const success = { status: 'success' };
|
|
32
31
|
const user = {
|
|
33
32
|
uid: '',
|
|
@@ -155,10 +154,7 @@ export const OVERLAY = {
|
|
|
155
154
|
500: { status: 'failure', message: 'Deployment failed!' }
|
|
156
155
|
}
|
|
157
156
|
},
|
|
158
|
-
'POST /SASjsApi/drive/deploy/upload': {
|
|
159
|
-
implemented: false,
|
|
160
|
-
reason: ARCHIVE
|
|
161
|
-
},
|
|
157
|
+
'POST /SASjsApi/drive/deploy/upload': { implemented: true },
|
|
162
158
|
// `404` is a pair - the registry name and the appLoc it was published from -
|
|
163
159
|
// that matches no entry, and the drive's content is deliberately left alone.
|
|
164
160
|
'DELETE /SASjsApi/drive/deploy': { implemented: true },
|
package/package.json
CHANGED