@osaas/client-web 0.6.4 → 0.6.6
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/README.md +14 -6
- package/lib/index.d.ts +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -3
- package/lib/index.js.map +1 -1
- package/lib/mypage.d.ts +96 -0
- package/lib/mypage.d.ts.map +1 -0
- package/lib/mypage.js +261 -0
- package/lib/mypage.js.map +1 -0
- package/package.json +5 -4
- package/lib/bucket.d.ts +0 -11
- package/lib/bucket.d.ts.map +0 -1
- package/lib/bucket.js +0 -133
- package/lib/bucket.js.map +0 -1
- package/lib/publish.d.ts +0 -33
- package/lib/publish.d.ts.map +0 -1
- package/lib/publish.js +0 -48
- package/lib/publish.js.map +0 -1
package/README.md
CHANGED
|
@@ -16,18 +16,26 @@ npm install --save @osaas/client-web
|
|
|
16
16
|
|
|
17
17
|
Example code
|
|
18
18
|
|
|
19
|
+
Publishing uses `osaas-deploy-manager`'s `/mypages` API (a shared per-tenant
|
|
20
|
+
storage instance with a `*.pages.osaas.io` URL and directory-index support).
|
|
21
|
+
It does not provision a dedicated storage bucket per site, so `web cdn-create`
|
|
22
|
+
/ custom domains cannot be pointed at a published site yet (see
|
|
23
|
+
`Eyevinn/osaas-deploy-manager#1409`):
|
|
24
|
+
|
|
19
25
|
```javascript
|
|
20
26
|
import { Context, Log } from '@osaas/client-core';
|
|
21
|
-
import {
|
|
27
|
+
import { publishToMyPages } from '@osaas/client-web';
|
|
22
28
|
|
|
23
29
|
async function main() {
|
|
24
|
-
const ctx = new Context();
|
|
30
|
+
const ctx = new Context({ environment });
|
|
25
31
|
|
|
26
32
|
try {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
33
|
+
const page = await publishToMyPages(
|
|
34
|
+
'www',
|
|
35
|
+
'/Users/birme/Code/eyevinn/www/dist',
|
|
36
|
+
ctx
|
|
37
|
+
);
|
|
38
|
+
console.log(page.url);
|
|
31
39
|
} catch (err) {
|
|
32
40
|
Log().error(err);
|
|
33
41
|
}
|
package/lib/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** @module @osaas/client-web */
|
|
2
|
-
export { publish } from './publish';
|
|
3
2
|
export { createCloudfrontDistribution } from './cdn';
|
|
4
3
|
export { generateCommonAccessToken, validateCommonAccessToken } from './cat';
|
|
4
|
+
export { publishToMyPages, MyPage, MyPageUploadFile, MyPageUploadTarget, MyPageUploadUrlsResponse, MyPagePublishResult, MyPagesPublishResult, MyPageNotReadyError, validateMyPageName, MAX_PAGE_FILE_SIZE_BYTES, MAX_UPLOAD_FILES_PER_REQUEST } from './mypage';
|
|
5
5
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAEhC,OAAO,EAAE,4BAA4B,EAAE,MAAM,OAAO,CAAC;AACrD,OAAO,EAAE,yBAAyB,EAAE,yBAAyB,EAAE,MAAM,OAAO,CAAC;AAC7E,OAAO,EACL,gBAAgB,EAChB,MAAM,EACN,gBAAgB,EAChB,kBAAkB,EAClB,wBAAwB,EACxB,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,kBAAkB,EAClB,wBAAwB,EACxB,4BAA4B,EAC7B,MAAM,UAAU,CAAC"}
|
package/lib/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/** @module @osaas/client-web */
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
-
exports.
|
|
5
|
-
var publish_1 = require("./publish");
|
|
6
|
-
Object.defineProperty(exports, "publish", { enumerable: true, get: function () { return publish_1.publish; } });
|
|
4
|
+
exports.MAX_UPLOAD_FILES_PER_REQUEST = exports.MAX_PAGE_FILE_SIZE_BYTES = exports.validateMyPageName = exports.MyPageNotReadyError = exports.publishToMyPages = exports.validateCommonAccessToken = exports.generateCommonAccessToken = exports.createCloudfrontDistribution = void 0;
|
|
7
5
|
var cdn_1 = require("./cdn");
|
|
8
6
|
Object.defineProperty(exports, "createCloudfrontDistribution", { enumerable: true, get: function () { return cdn_1.createCloudfrontDistribution; } });
|
|
9
7
|
var cat_1 = require("./cat");
|
|
10
8
|
Object.defineProperty(exports, "generateCommonAccessToken", { enumerable: true, get: function () { return cat_1.generateCommonAccessToken; } });
|
|
11
9
|
Object.defineProperty(exports, "validateCommonAccessToken", { enumerable: true, get: function () { return cat_1.validateCommonAccessToken; } });
|
|
10
|
+
var mypage_1 = require("./mypage");
|
|
11
|
+
Object.defineProperty(exports, "publishToMyPages", { enumerable: true, get: function () { return mypage_1.publishToMyPages; } });
|
|
12
|
+
Object.defineProperty(exports, "MyPageNotReadyError", { enumerable: true, get: function () { return mypage_1.MyPageNotReadyError; } });
|
|
13
|
+
Object.defineProperty(exports, "validateMyPageName", { enumerable: true, get: function () { return mypage_1.validateMyPageName; } });
|
|
14
|
+
Object.defineProperty(exports, "MAX_PAGE_FILE_SIZE_BYTES", { enumerable: true, get: function () { return mypage_1.MAX_PAGE_FILE_SIZE_BYTES; } });
|
|
15
|
+
Object.defineProperty(exports, "MAX_UPLOAD_FILES_PER_REQUEST", { enumerable: true, get: function () { return mypage_1.MAX_UPLOAD_FILES_PER_REQUEST; } });
|
|
12
16
|
//# sourceMappingURL=index.js.map
|
package/lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gCAAgC;;;AAEhC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA,gCAAgC;;;AAEhC,6BAAqD;AAA5C,mHAAA,4BAA4B,OAAA;AACrC,6BAA6E;AAApE,gHAAA,yBAAyB,OAAA;AAAE,gHAAA,yBAAyB,OAAA;AAC7D,mCAYkB;AAXhB,0GAAA,gBAAgB,OAAA;AAOhB,6GAAA,mBAAmB,OAAA;AACnB,4GAAA,kBAAkB,OAAA;AAClB,kHAAA,wBAAwB,OAAA;AACxB,sHAAA,4BAA4B,OAAA"}
|
package/lib/mypage.d.ts
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Context, FetchError } from '@osaas/client-core';
|
|
2
|
+
/**
|
|
3
|
+
* Per-file size cap and per-request file count cap for `osaas-deploy-manager`'s
|
|
4
|
+
* `/mypages` API, mirrored from `MAX_PAGE_FILE_SIZE_BYTES` /
|
|
5
|
+
* `MAX_UPLOAD_FILES_PER_REQUEST` in `Eyevinn/osaas-deploy-manager`'s
|
|
6
|
+
* `src/apps/mypage.ts` (verified against `main`). These are not re-exported by
|
|
7
|
+
* that service, so the values are duplicated here — if the upstream service
|
|
8
|
+
* ever changes them, requests will simply get a 400/413 from the server, which
|
|
9
|
+
* is a safe failure mode.
|
|
10
|
+
*/
|
|
11
|
+
export declare const MAX_PAGE_FILE_SIZE_BYTES = 26214400;
|
|
12
|
+
export declare const MAX_UPLOAD_FILES_PER_REQUEST = 500;
|
|
13
|
+
/** Server-side cap on the `files` manifest passed to `/mypages/:id/publish`. */
|
|
14
|
+
export declare const MAX_PAGE_MANIFEST_FILES = 5000;
|
|
15
|
+
export interface MyPage {
|
|
16
|
+
id: string;
|
|
17
|
+
name: string;
|
|
18
|
+
url: string;
|
|
19
|
+
status: 'draft' | 'live';
|
|
20
|
+
}
|
|
21
|
+
export interface MyPageUploadFile {
|
|
22
|
+
path: string;
|
|
23
|
+
size: number;
|
|
24
|
+
}
|
|
25
|
+
export interface MyPageUploadTarget {
|
|
26
|
+
path: string;
|
|
27
|
+
url: string;
|
|
28
|
+
method: 'POST';
|
|
29
|
+
contentType: string;
|
|
30
|
+
fields: Record<string, string>;
|
|
31
|
+
}
|
|
32
|
+
export interface MyPageUploadUrlsResponse {
|
|
33
|
+
uploads: MyPageUploadTarget[];
|
|
34
|
+
expiresAt: string;
|
|
35
|
+
maxFileSizeBytes: number;
|
|
36
|
+
}
|
|
37
|
+
export interface MyPagePublishResult extends MyPage {
|
|
38
|
+
prunedCount?: number;
|
|
39
|
+
}
|
|
40
|
+
/** Thrown when the server responds 503 because the tenant's `mypages` MinIO
|
|
41
|
+
* instance is still starting up. Carries the `Retry-After` value (seconds)
|
|
42
|
+
* so callers can back off accordingly. */
|
|
43
|
+
export declare class MyPageNotReadyError extends FetchError {
|
|
44
|
+
retryAfterSeconds: number;
|
|
45
|
+
constructor(message: string, retryAfterSeconds: number);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Lightweight client-side pre-check mirroring
|
|
49
|
+
* `validatePageName`/`PAGE_NAME_CHARSET_RE` in
|
|
50
|
+
* `Eyevinn/osaas-deploy-manager`'s `src/apps/mypage.ts`. This exists to fail
|
|
51
|
+
* fast with a clear message before any network call — the server remains the
|
|
52
|
+
* authoritative validator and will still reject an invalid name with a 400.
|
|
53
|
+
*/
|
|
54
|
+
export declare function validateMyPageName(name: string): string | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Create a new My Page site.
|
|
57
|
+
*
|
|
58
|
+
* Retries on 503 (the tenant's dedicated `mypages` MinIO instance is still
|
|
59
|
+
* starting up) using the server's `Retry-After` header, up to a total wait
|
|
60
|
+
* of ~60s. Throws immediately (no retry) on 409 name-collision.
|
|
61
|
+
*/
|
|
62
|
+
export declare function createMyPage(name: string, ctx: Context): Promise<MyPage>;
|
|
63
|
+
/**
|
|
64
|
+
* Mint presigned S3 POST upload targets for a batch of files. `files` must
|
|
65
|
+
* contain at most `MAX_UPLOAD_FILES_PER_REQUEST` entries — chunk larger
|
|
66
|
+
* manifests before calling this.
|
|
67
|
+
*/
|
|
68
|
+
export declare function getPageUploadUrls(id: string, files: MyPageUploadFile[], ctx: Context): Promise<MyPageUploadUrlsResponse>;
|
|
69
|
+
/**
|
|
70
|
+
* Finalize a publish: server-side copies each `dir/index.html` to `dir/` so
|
|
71
|
+
* directory URLs resolve, marks the site `live`, and (since `prune: true` is
|
|
72
|
+
* always sent here with the complete file manifest) deletes any bucket
|
|
73
|
+
* object that is not part of the current publish.
|
|
74
|
+
*/
|
|
75
|
+
export declare function finalizeMyPagePublish(id: string, files: string[], ctx: Context): Promise<MyPagePublishResult>;
|
|
76
|
+
/**
|
|
77
|
+
* Upload a single file to a presigned S3 POST target. Builds a multipart
|
|
78
|
+
* form from `target.fields` (appended in order, untouched) with the file
|
|
79
|
+
* appended last under the field name `file`, read as a stream — never
|
|
80
|
+
* base64-encoded or buffered into memory.
|
|
81
|
+
*/
|
|
82
|
+
export declare function uploadFileToPresignedTarget(filePath: string, target: MyPageUploadTarget): Promise<void>;
|
|
83
|
+
export interface MyPagesPublishResult {
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
url: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Publish a directory of static files as a My Page site via
|
|
90
|
+
* `osaas-deploy-manager`'s `/mypages` API: create the site, mint presigned
|
|
91
|
+
* upload targets in batches of at most `MAX_UPLOAD_FILES_PER_REQUEST`, POST
|
|
92
|
+
* every file directly to its presigned target, then finalize the publish
|
|
93
|
+
* with the complete file manifest and `prune: true`.
|
|
94
|
+
*/
|
|
95
|
+
export declare function publishToMyPages(name: string, dir: string, ctx: Context): Promise<MyPagesPublishResult>;
|
|
96
|
+
//# sourceMappingURL=mypage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mypage.d.ts","sourceRoot":"","sources":["../src/mypage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAe,MAAM,oBAAoB,CAAC;AAKtE;;;;;;;;GAQG;AACH,eAAO,MAAM,wBAAwB,WAAW,CAAC;AACjD,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAChD,gFAAgF;AAChF,eAAO,MAAM,uBAAuB,OAAO,CAAC;AAS5C,MAAM,WAAW,MAAM;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,kBAAkB,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAoB,SAAQ,MAAM;IACjD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;0CAE0C;AAC1C,qBAAa,mBAAoB,SAAQ,UAAU;IACjD,iBAAiB,EAAE,MAAM,CAAC;gBAEd,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM;CAIvD;AAgDD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQnE;AAED;;;;;;GAMG;AACH,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAED;;;;GAIG;AACH,wBAAsB,iBAAiB,CACrC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,gBAAgB,EAAE,EACzB,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,wBAAwB,CAAC,CAWnC;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EAAE,EACf,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,mBAAmB,CAAC,CAW9B;AAED;;;;;GAKG;AACH,wBAAsB,2BAA2B,CAC/C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,IAAI,CAAC,CAkDf;AAqBD,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,oBAAoB,CAAC,CAuD/B"}
|
package/lib/mypage.js
ADDED
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.publishToMyPages = exports.uploadFileToPresignedTarget = exports.finalizeMyPagePublish = exports.getPageUploadUrls = exports.createMyPage = exports.validateMyPageName = exports.MyPageNotReadyError = exports.MAX_PAGE_MANIFEST_FILES = exports.MAX_UPLOAD_FILES_PER_REQUEST = exports.MAX_PAGE_FILE_SIZE_BYTES = void 0;
|
|
7
|
+
const client_core_1 = require("@osaas/client-core");
|
|
8
|
+
const fs_1 = require("fs");
|
|
9
|
+
const path_1 = require("path");
|
|
10
|
+
const form_data_1 = __importDefault(require("form-data"));
|
|
11
|
+
/**
|
|
12
|
+
* Per-file size cap and per-request file count cap for `osaas-deploy-manager`'s
|
|
13
|
+
* `/mypages` API, mirrored from `MAX_PAGE_FILE_SIZE_BYTES` /
|
|
14
|
+
* `MAX_UPLOAD_FILES_PER_REQUEST` in `Eyevinn/osaas-deploy-manager`'s
|
|
15
|
+
* `src/apps/mypage.ts` (verified against `main`). These are not re-exported by
|
|
16
|
+
* that service, so the values are duplicated here — if the upstream service
|
|
17
|
+
* ever changes them, requests will simply get a 400/413 from the server, which
|
|
18
|
+
* is a safe failure mode.
|
|
19
|
+
*/
|
|
20
|
+
exports.MAX_PAGE_FILE_SIZE_BYTES = 26214400; // 25 MiB
|
|
21
|
+
exports.MAX_UPLOAD_FILES_PER_REQUEST = 500;
|
|
22
|
+
/** Server-side cap on the `files` manifest passed to `/mypages/:id/publish`. */
|
|
23
|
+
exports.MAX_PAGE_MANIFEST_FILES = 5000;
|
|
24
|
+
/** Total time budget for retrying a 503 "storage still starting up" response. */
|
|
25
|
+
const NOT_READY_RETRY_BUDGET_MS = 60000;
|
|
26
|
+
/** Fallback backoff when the server does not send a usable `Retry-After`. */
|
|
27
|
+
const DEFAULT_RETRY_AFTER_SECONDS = 10;
|
|
28
|
+
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
29
|
+
/** Thrown when the server responds 503 because the tenant's `mypages` MinIO
|
|
30
|
+
* instance is still starting up. Carries the `Retry-After` value (seconds)
|
|
31
|
+
* so callers can back off accordingly. */
|
|
32
|
+
class MyPageNotReadyError extends client_core_1.FetchError {
|
|
33
|
+
retryAfterSeconds;
|
|
34
|
+
constructor(message, retryAfterSeconds) {
|
|
35
|
+
super({ message, httpCode: 503 });
|
|
36
|
+
this.retryAfterSeconds = retryAfterSeconds;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
exports.MyPageNotReadyError = MyPageNotReadyError;
|
|
40
|
+
/**
|
|
41
|
+
* Error factory for `/mypages*` endpoints. Behaves like the library default
|
|
42
|
+
* (parses `{ reason }` / `{ message }` JSON bodies, or falls back to raw
|
|
43
|
+
* text) but additionally turns a 503 into a `MyPageNotReadyError` carrying
|
|
44
|
+
* the parsed `Retry-After` header, since the shared `createFetch` error path
|
|
45
|
+
* does not expose response headers to callers.
|
|
46
|
+
*/
|
|
47
|
+
const mypageErrorFactory = async (response) => {
|
|
48
|
+
let message;
|
|
49
|
+
if (response.headers.get('content-type')?.includes('application/json')) {
|
|
50
|
+
const body = (await response.json());
|
|
51
|
+
message = body?.message ?? body?.reason ?? JSON.stringify(body);
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
message = await response.text();
|
|
55
|
+
}
|
|
56
|
+
if (response.status === 503) {
|
|
57
|
+
const retryAfterHeader = response.headers.get('retry-after');
|
|
58
|
+
const parsed = retryAfterHeader ? parseInt(retryAfterHeader, 10) : NaN;
|
|
59
|
+
return new MyPageNotReadyError(message, Number.isFinite(parsed) ? parsed : DEFAULT_RETRY_AFTER_SECONDS);
|
|
60
|
+
}
|
|
61
|
+
return new client_core_1.FetchError({ message, httpCode: response.status });
|
|
62
|
+
};
|
|
63
|
+
function myPagesBaseUrl(ctx) {
|
|
64
|
+
return `https://deploy.svc.${ctx.getEnvironment()}.osaas.io`;
|
|
65
|
+
}
|
|
66
|
+
function jsonHeaders(ctx) {
|
|
67
|
+
return {
|
|
68
|
+
'x-pat-jwt': `Bearer ${ctx.getPersonalAccessToken()}`,
|
|
69
|
+
'Content-Type': 'application/json'
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const PAGE_NAME_CHARSET_RE = /^[a-z0-9]([a-z0-9-]*[a-z0-9])?$/;
|
|
73
|
+
/**
|
|
74
|
+
* Lightweight client-side pre-check mirroring
|
|
75
|
+
* `validatePageName`/`PAGE_NAME_CHARSET_RE` in
|
|
76
|
+
* `Eyevinn/osaas-deploy-manager`'s `src/apps/mypage.ts`. This exists to fail
|
|
77
|
+
* fast with a clear message before any network call — the server remains the
|
|
78
|
+
* authoritative validator and will still reject an invalid name with a 400.
|
|
79
|
+
*/
|
|
80
|
+
function validateMyPageName(name) {
|
|
81
|
+
if (name.length < 3 || name.length > 52) {
|
|
82
|
+
return `Page name must be between 3 and 52 characters (got ${name.length})`;
|
|
83
|
+
}
|
|
84
|
+
if (!PAGE_NAME_CHARSET_RE.test(name)) {
|
|
85
|
+
return 'Page name must be lowercase letters, numbers, and hyphens only, and must start/end with a letter or number';
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
88
|
+
}
|
|
89
|
+
exports.validateMyPageName = validateMyPageName;
|
|
90
|
+
/**
|
|
91
|
+
* Create a new My Page site.
|
|
92
|
+
*
|
|
93
|
+
* Retries on 503 (the tenant's dedicated `mypages` MinIO instance is still
|
|
94
|
+
* starting up) using the server's `Retry-After` header, up to a total wait
|
|
95
|
+
* of ~60s. Throws immediately (no retry) on 409 name-collision.
|
|
96
|
+
*/
|
|
97
|
+
async function createMyPage(name, ctx) {
|
|
98
|
+
const url = new URL('/mypages', myPagesBaseUrl(ctx));
|
|
99
|
+
let waitedMs = 0;
|
|
100
|
+
for (;;) {
|
|
101
|
+
try {
|
|
102
|
+
return await (0, client_core_1.createFetch)(url, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: jsonHeaders(ctx),
|
|
105
|
+
body: JSON.stringify({ name })
|
|
106
|
+
}, mypageErrorFactory);
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (error instanceof client_core_1.FetchError && error.httpCode === 409) {
|
|
110
|
+
throw new Error(`Page name '${name}' is already in use. Choose a different name.`);
|
|
111
|
+
}
|
|
112
|
+
if (error instanceof MyPageNotReadyError) {
|
|
113
|
+
const backoffMs = error.retryAfterSeconds * 1000;
|
|
114
|
+
if (waitedMs + backoffMs > NOT_READY_RETRY_BUDGET_MS) {
|
|
115
|
+
throw new Error(`My Page storage for '${name}' is still starting up after ${Math.round(waitedMs / 1000)}s of retries. Try again in a moment. (${error.message})`);
|
|
116
|
+
}
|
|
117
|
+
await delay(backoffMs);
|
|
118
|
+
waitedMs += backoffMs;
|
|
119
|
+
continue;
|
|
120
|
+
}
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
exports.createMyPage = createMyPage;
|
|
126
|
+
/**
|
|
127
|
+
* Mint presigned S3 POST upload targets for a batch of files. `files` must
|
|
128
|
+
* contain at most `MAX_UPLOAD_FILES_PER_REQUEST` entries — chunk larger
|
|
129
|
+
* manifests before calling this.
|
|
130
|
+
*/
|
|
131
|
+
async function getPageUploadUrls(id, files, ctx) {
|
|
132
|
+
const url = new URL(`/mypages/${id}/upload-urls`, myPagesBaseUrl(ctx));
|
|
133
|
+
return await (0, client_core_1.createFetch)(url, {
|
|
134
|
+
method: 'POST',
|
|
135
|
+
headers: jsonHeaders(ctx),
|
|
136
|
+
body: JSON.stringify({ files })
|
|
137
|
+
}, mypageErrorFactory);
|
|
138
|
+
}
|
|
139
|
+
exports.getPageUploadUrls = getPageUploadUrls;
|
|
140
|
+
/**
|
|
141
|
+
* Finalize a publish: server-side copies each `dir/index.html` to `dir/` so
|
|
142
|
+
* directory URLs resolve, marks the site `live`, and (since `prune: true` is
|
|
143
|
+
* always sent here with the complete file manifest) deletes any bucket
|
|
144
|
+
* object that is not part of the current publish.
|
|
145
|
+
*/
|
|
146
|
+
async function finalizeMyPagePublish(id, files, ctx) {
|
|
147
|
+
const url = new URL(`/mypages/${id}/publish`, myPagesBaseUrl(ctx));
|
|
148
|
+
return await (0, client_core_1.createFetch)(url, {
|
|
149
|
+
method: 'POST',
|
|
150
|
+
headers: jsonHeaders(ctx),
|
|
151
|
+
body: JSON.stringify({ files, prune: true })
|
|
152
|
+
}, mypageErrorFactory);
|
|
153
|
+
}
|
|
154
|
+
exports.finalizeMyPagePublish = finalizeMyPagePublish;
|
|
155
|
+
/**
|
|
156
|
+
* Upload a single file to a presigned S3 POST target. Builds a multipart
|
|
157
|
+
* form from `target.fields` (appended in order, untouched) with the file
|
|
158
|
+
* appended last under the field name `file`, read as a stream — never
|
|
159
|
+
* base64-encoded or buffered into memory.
|
|
160
|
+
*/
|
|
161
|
+
async function uploadFileToPresignedTarget(filePath, target) {
|
|
162
|
+
const form = new form_data_1.default();
|
|
163
|
+
for (const [key, value] of Object.entries(target.fields)) {
|
|
164
|
+
form.append(key, value);
|
|
165
|
+
}
|
|
166
|
+
form.append('file', (0, fs_1.createReadStream)(filePath), {
|
|
167
|
+
filename: (0, path_1.basename)(filePath),
|
|
168
|
+
contentType: target.contentType
|
|
169
|
+
});
|
|
170
|
+
await new Promise((resolve, reject) => {
|
|
171
|
+
form.submit(target.url, (err, res) => {
|
|
172
|
+
if (err) {
|
|
173
|
+
reject(new Error(`Upload of '${target.path}' failed: ${err.message}`));
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
if (!res) {
|
|
177
|
+
reject(new Error(`Upload of '${target.path}' failed: no response`));
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const chunks = [];
|
|
181
|
+
res.on('data', (chunk) => chunks.push(chunk));
|
|
182
|
+
res.on('error', (streamErr) => reject(new Error(`Upload of '${target.path}' failed: ${streamErr.message}`)));
|
|
183
|
+
res.on('end', () => {
|
|
184
|
+
const statusCode = res.statusCode ?? 0;
|
|
185
|
+
if (statusCode >= 200 && statusCode < 300) {
|
|
186
|
+
resolve();
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
const body = Buffer.concat(chunks).toString('utf8');
|
|
190
|
+
reject(new Error(`Upload of '${target.path}' failed with HTTP ${statusCode}: ${body}`));
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
exports.uploadFileToPresignedTarget = uploadFileToPresignedTarget;
|
|
197
|
+
function chunk(items, size) {
|
|
198
|
+
const chunks = [];
|
|
199
|
+
for (let i = 0; i < items.length; i += size) {
|
|
200
|
+
chunks.push(items.slice(i, i + size));
|
|
201
|
+
}
|
|
202
|
+
return chunks;
|
|
203
|
+
}
|
|
204
|
+
/** Recursively list every regular file under `dir`, as site-relative paths
|
|
205
|
+
* using forward slashes (the `/mypages` API rejects backslashes), skipping
|
|
206
|
+
* `.git`. */
|
|
207
|
+
function listSiteFiles(dir) {
|
|
208
|
+
const entries = (0, fs_1.readdirSync)(dir, { recursive: true });
|
|
209
|
+
return entries
|
|
210
|
+
.filter((entry) => entry.split(path_1.sep)[0] !== '.git')
|
|
211
|
+
.filter((entry) => !(0, fs_1.statSync)((0, path_1.join)(dir, entry)).isDirectory())
|
|
212
|
+
.map((entry) => entry.split(path_1.sep).join('/'));
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Publish a directory of static files as a My Page site via
|
|
216
|
+
* `osaas-deploy-manager`'s `/mypages` API: create the site, mint presigned
|
|
217
|
+
* upload targets in batches of at most `MAX_UPLOAD_FILES_PER_REQUEST`, POST
|
|
218
|
+
* every file directly to its presigned target, then finalize the publish
|
|
219
|
+
* with the complete file manifest and `prune: true`.
|
|
220
|
+
*/
|
|
221
|
+
async function publishToMyPages(name, dir, ctx) {
|
|
222
|
+
const nameError = validateMyPageName(name);
|
|
223
|
+
if (nameError) {
|
|
224
|
+
throw new Error(nameError);
|
|
225
|
+
}
|
|
226
|
+
const relativePaths = listSiteFiles(dir);
|
|
227
|
+
if (relativePaths.length === 0) {
|
|
228
|
+
throw new Error(`No files found to publish in '${dir}'`);
|
|
229
|
+
}
|
|
230
|
+
if (relativePaths.length > exports.MAX_PAGE_MANIFEST_FILES) {
|
|
231
|
+
throw new Error(`'${dir}' contains ${relativePaths.length} files, which exceeds the ${exports.MAX_PAGE_MANIFEST_FILES}-file limit for a single My Page site`);
|
|
232
|
+
}
|
|
233
|
+
const oversized = relativePaths.filter((p) => (0, fs_1.statSync)((0, path_1.join)(dir, p)).size > exports.MAX_PAGE_FILE_SIZE_BYTES);
|
|
234
|
+
if (oversized.length > 0) {
|
|
235
|
+
throw new Error(`The following files exceed the ${exports.MAX_PAGE_FILE_SIZE_BYTES}-byte per-file limit: ${oversized.join(', ')}`);
|
|
236
|
+
}
|
|
237
|
+
const page = await createMyPage(name, ctx);
|
|
238
|
+
const fileBatches = chunk(relativePaths, exports.MAX_UPLOAD_FILES_PER_REQUEST);
|
|
239
|
+
const targetsByPath = new Map();
|
|
240
|
+
for (const batch of fileBatches) {
|
|
241
|
+
const files = batch.map((p) => ({
|
|
242
|
+
path: p,
|
|
243
|
+
size: (0, fs_1.statSync)((0, path_1.join)(dir, p)).size
|
|
244
|
+
}));
|
|
245
|
+
const { uploads } = await getPageUploadUrls(page.id, files, ctx);
|
|
246
|
+
for (const upload of uploads) {
|
|
247
|
+
targetsByPath.set(upload.path, upload);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
for (const relativePath of relativePaths) {
|
|
251
|
+
const target = targetsByPath.get(relativePath);
|
|
252
|
+
if (!target) {
|
|
253
|
+
throw new Error(`Server did not return an upload target for '${relativePath}'`);
|
|
254
|
+
}
|
|
255
|
+
await uploadFileToPresignedTarget((0, path_1.join)(dir, relativePath), target);
|
|
256
|
+
}
|
|
257
|
+
const published = await finalizeMyPagePublish(page.id, relativePaths, ctx);
|
|
258
|
+
return { id: published.id, name: published.name, url: published.url };
|
|
259
|
+
}
|
|
260
|
+
exports.publishToMyPages = publishToMyPages;
|
|
261
|
+
//# sourceMappingURL=mypage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mypage.js","sourceRoot":"","sources":["../src/mypage.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@osaas/client-web",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.6",
|
|
4
4
|
"description": "Open Source Cloud Client SDK web library",
|
|
5
5
|
"author": "Eyevinn Open Source Cloud <osc@eyevinn.se>",
|
|
6
6
|
"homepage": "https://www.osaas.io",
|
|
@@ -26,14 +26,15 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@aws-sdk/client-cloudfront": "^3.730.0",
|
|
29
|
-
"@osaas/client-core": "^0.
|
|
30
|
-
"@osaas/client-services": "^0.17.
|
|
29
|
+
"@osaas/client-core": "^0.26.0",
|
|
30
|
+
"@osaas/client-services": "^0.17.3",
|
|
31
31
|
"chalk": "4.1.2",
|
|
32
|
+
"form-data": "^4.0.0",
|
|
32
33
|
"mime": "^3.0.0",
|
|
33
34
|
"minio": "^8.0.2"
|
|
34
35
|
},
|
|
35
36
|
"publishConfig": {
|
|
36
37
|
"access": "public"
|
|
37
38
|
},
|
|
38
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "2991b52a67fbbc8c038222dfd0f7a060b0072b8d"
|
|
39
40
|
}
|
package/lib/bucket.d.ts
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { Context } from '@osaas/client-core';
|
|
2
|
-
export interface Bucket {
|
|
3
|
-
name: string;
|
|
4
|
-
endpoint: string;
|
|
5
|
-
accessKeyId: string;
|
|
6
|
-
secretAccessKey: string;
|
|
7
|
-
}
|
|
8
|
-
export declare function createStorageBucket(name: string, ctx: Context): Promise<Bucket>;
|
|
9
|
-
export declare function removeBucketContents(bucket: Bucket): Promise<void>;
|
|
10
|
-
export declare function uploadFile(source: string, dest: string, bucket: Bucket): Promise<void>;
|
|
11
|
-
//# sourceMappingURL=bucket.d.ts.map
|
package/lib/bucket.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bucket.d.ts","sourceRoot":"","sources":["../src/bucket.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,OAAO,EAIR,MAAM,oBAAoB,CAAC;AAa5B,MAAM,WAAW,MAAM;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;CACzB;AA0BD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,MAAM,CAAC,CAoCjB;AAED,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,MAAM,iBA6BxD;AAED,wBAAsB,UAAU,CAC9B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
package/lib/bucket.js
DELETED
|
@@ -1,133 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (mod) {
|
|
19
|
-
if (mod && mod.__esModule) return mod;
|
|
20
|
-
var result = {};
|
|
21
|
-
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
22
|
-
__setModuleDefault(result, mod);
|
|
23
|
-
return result;
|
|
24
|
-
};
|
|
25
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
26
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
|
-
};
|
|
28
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.uploadFile = exports.removeBucketContents = exports.createStorageBucket = void 0;
|
|
30
|
-
const client_core_1 = require("@osaas/client-core");
|
|
31
|
-
const client_services_1 = require("@osaas/client-services");
|
|
32
|
-
const crypto_1 = require("crypto");
|
|
33
|
-
const fs_1 = require("fs");
|
|
34
|
-
const Minio = __importStar(require("minio"));
|
|
35
|
-
const mime_1 = __importDefault(require("mime"));
|
|
36
|
-
const delay = (ms) => new Promise((res) => setTimeout(res, ms));
|
|
37
|
-
function createPublicBucketPolicy(name) {
|
|
38
|
-
return {
|
|
39
|
-
Statement: [
|
|
40
|
-
{
|
|
41
|
-
Action: ['s3:GetBucketLocation', 's3:ListBucket'],
|
|
42
|
-
Effect: 'Allow',
|
|
43
|
-
Principal: {
|
|
44
|
-
AWS: ['*']
|
|
45
|
-
},
|
|
46
|
-
Resource: [`arn:aws:s3:::${name}`]
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
Action: ['s3:GetObject'],
|
|
50
|
-
Effect: 'Allow',
|
|
51
|
-
Principal: {
|
|
52
|
-
AWS: ['*']
|
|
53
|
-
},
|
|
54
|
-
Resource: [`arn:aws:s3:::${name}/*`]
|
|
55
|
-
}
|
|
56
|
-
],
|
|
57
|
-
Version: '2012-10-17'
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
async function createStorageBucket(name, ctx) {
|
|
61
|
-
const sat = await ctx.getServiceAccessToken('minio-minio');
|
|
62
|
-
let instance = await (0, client_core_1.getInstance)(ctx, 'minio-minio', name, sat);
|
|
63
|
-
if (!instance) {
|
|
64
|
-
const rootPassword = (0, crypto_1.randomBytes)(16).toString('hex');
|
|
65
|
-
const config = {
|
|
66
|
-
name,
|
|
67
|
-
RootUser: 'root',
|
|
68
|
-
RootPassword: rootPassword
|
|
69
|
-
};
|
|
70
|
-
const newInstance = await (0, client_services_1.createMinioMinioInstance)(ctx, config);
|
|
71
|
-
if (!newInstance) {
|
|
72
|
-
throw new Error('Failed to create new Minio instance');
|
|
73
|
-
}
|
|
74
|
-
instance = newInstance;
|
|
75
|
-
await (0, client_core_1.waitForInstanceReady)('minio-minio', name, ctx);
|
|
76
|
-
await delay(2000);
|
|
77
|
-
const minioClient = new Minio.Client({
|
|
78
|
-
endPoint: new URL(instance.url).hostname,
|
|
79
|
-
accessKey: 'root',
|
|
80
|
-
secretKey: instance.RootPassword || ''
|
|
81
|
-
});
|
|
82
|
-
await minioClient.makeBucket(name);
|
|
83
|
-
await minioClient.setBucketPolicy(name, JSON.stringify(createPublicBucketPolicy(name)));
|
|
84
|
-
}
|
|
85
|
-
return {
|
|
86
|
-
name: instance.name,
|
|
87
|
-
endpoint: instance.url,
|
|
88
|
-
accessKeyId: 'root',
|
|
89
|
-
secretAccessKey: instance.RootPassword || ''
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
exports.createStorageBucket = createStorageBucket;
|
|
93
|
-
async function removeBucketContents(bucket) {
|
|
94
|
-
(0, client_core_1.Log)().debug(`Removing contents on bucket ${bucket.name}`);
|
|
95
|
-
const minioClient = new Minio.Client({
|
|
96
|
-
endPoint: new URL(bucket.endpoint).hostname,
|
|
97
|
-
accessKey: bucket.accessKeyId,
|
|
98
|
-
secretKey: bucket.secretAccessKey
|
|
99
|
-
});
|
|
100
|
-
const p = new Promise((resolve, reject) => {
|
|
101
|
-
const stream = minioClient.listObjects(bucket.name, '', true);
|
|
102
|
-
const objectsToDelete = [];
|
|
103
|
-
stream.on('data', (obj) => {
|
|
104
|
-
if (obj.name) {
|
|
105
|
-
objectsToDelete.push(obj.name);
|
|
106
|
-
}
|
|
107
|
-
});
|
|
108
|
-
stream.on('end', () => {
|
|
109
|
-
resolve(objectsToDelete);
|
|
110
|
-
});
|
|
111
|
-
stream.on('error', (err) => {
|
|
112
|
-
reject(err);
|
|
113
|
-
});
|
|
114
|
-
});
|
|
115
|
-
const objectsToDelete = await p;
|
|
116
|
-
(0, client_core_1.Log)().debug(`Deleting ${objectsToDelete.length} objects`);
|
|
117
|
-
await minioClient.removeObjects(bucket.name, objectsToDelete);
|
|
118
|
-
}
|
|
119
|
-
exports.removeBucketContents = removeBucketContents;
|
|
120
|
-
async function uploadFile(source, dest, bucket) {
|
|
121
|
-
(0, client_core_1.Log)().debug(`Uploading ${source} to ${bucket.name}/${dest}`);
|
|
122
|
-
const fileStream = (0, fs_1.createReadStream)(source);
|
|
123
|
-
const stats = await (0, fs_1.statSync)(source);
|
|
124
|
-
const metadata = { 'Content-Type': mime_1.default.getType(source) };
|
|
125
|
-
const minioClient = new Minio.Client({
|
|
126
|
-
endPoint: new URL(bucket.endpoint).hostname,
|
|
127
|
-
accessKey: bucket.accessKeyId,
|
|
128
|
-
secretKey: bucket.secretAccessKey
|
|
129
|
-
});
|
|
130
|
-
await minioClient.putObject(bucket.name, dest, fileStream, stats.size, metadata);
|
|
131
|
-
}
|
|
132
|
-
exports.uploadFile = uploadFile;
|
|
133
|
-
//# sourceMappingURL=bucket.js.map
|
package/lib/bucket.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bucket.js","sourceRoot":"","sources":["../src/bucket.ts"],"names":[],"mappings":"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"}
|
package/lib/publish.d.ts
DELETED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { Context } from '@osaas/client-core';
|
|
2
|
-
import { Bucket } from './bucket';
|
|
3
|
-
export interface PublishOpts {
|
|
4
|
-
sync?: boolean;
|
|
5
|
-
}
|
|
6
|
-
export interface Website {
|
|
7
|
-
name: string;
|
|
8
|
-
url: string;
|
|
9
|
-
bucket: Bucket;
|
|
10
|
-
}
|
|
11
|
-
/**
|
|
12
|
-
* Publish options
|
|
13
|
-
* @typedef PublishOpts
|
|
14
|
-
* @type object
|
|
15
|
-
* @property {boolean} [sync] - If true, clear bucket before uploading new files
|
|
16
|
-
*/
|
|
17
|
-
/**
|
|
18
|
-
* Publish a static website using Eyevinn Open Source Cloud Storage
|
|
19
|
-
*
|
|
20
|
-
* @memberof module:@osaas/client-web
|
|
21
|
-
* @async
|
|
22
|
-
* @param name - Name of the website
|
|
23
|
-
* @param dir - Directory to publish
|
|
24
|
-
* @param ctx - Open Source Cloud configuration context
|
|
25
|
-
* @param {PublishOpts} [opts] - Publish options
|
|
26
|
-
* @returns name and url of the published website
|
|
27
|
-
*/
|
|
28
|
-
export declare function publish(name: string, dir: string, ctx: Context, opts?: PublishOpts): Promise<{
|
|
29
|
-
name: string;
|
|
30
|
-
url: string;
|
|
31
|
-
bucket: Bucket;
|
|
32
|
-
}>;
|
|
33
|
-
//# sourceMappingURL=publish.d.ts.map
|
package/lib/publish.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAuB,MAAM,oBAAoB,CAAC;AAClE,OAAO,EACL,MAAM,EAIP,MAAM,UAAU,CAAC;AAKlB,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACH,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,OAAO,EACZ,IAAI,CAAC,EAAE,WAAW;;;;GAuBnB"}
|
package/lib/publish.js
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.publish = void 0;
|
|
4
|
-
const client_core_1 = require("@osaas/client-core");
|
|
5
|
-
const bucket_1 = require("./bucket");
|
|
6
|
-
const promises_1 = require("fs/promises");
|
|
7
|
-
const path_1 = require("path");
|
|
8
|
-
const fs_1 = require("fs");
|
|
9
|
-
/**
|
|
10
|
-
* Publish options
|
|
11
|
-
* @typedef PublishOpts
|
|
12
|
-
* @type object
|
|
13
|
-
* @property {boolean} [sync] - If true, clear bucket before uploading new files
|
|
14
|
-
*/
|
|
15
|
-
/**
|
|
16
|
-
* Publish a static website using Eyevinn Open Source Cloud Storage
|
|
17
|
-
*
|
|
18
|
-
* @memberof module:@osaas/client-web
|
|
19
|
-
* @async
|
|
20
|
-
* @param name - Name of the website
|
|
21
|
-
* @param dir - Directory to publish
|
|
22
|
-
* @param ctx - Open Source Cloud configuration context
|
|
23
|
-
* @param {PublishOpts} [opts] - Publish options
|
|
24
|
-
* @returns name and url of the published website
|
|
25
|
-
*/
|
|
26
|
-
async function publish(name, dir, ctx, opts) {
|
|
27
|
-
if (!(0, client_core_1.isValidInstanceName)(name)) {
|
|
28
|
-
throw new Error(`Invalid website identifier (lowercase letters and numbers allowed): ${name}`);
|
|
29
|
-
}
|
|
30
|
-
const sync = opts?.sync || false;
|
|
31
|
-
const bucket = await (0, bucket_1.createStorageBucket)(name, ctx);
|
|
32
|
-
if (sync) {
|
|
33
|
-
await (0, bucket_1.removeBucketContents)(bucket);
|
|
34
|
-
}
|
|
35
|
-
const files = await (0, promises_1.readdir)(dir, { recursive: true });
|
|
36
|
-
for (const file of files.filter((f) => f !== '.git')) {
|
|
37
|
-
if (!(0, fs_1.statSync)((0, path_1.join)(dir, file)).isDirectory()) {
|
|
38
|
-
await (0, bucket_1.uploadFile)((0, path_1.join)(dir, file), file, bucket);
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
return {
|
|
42
|
-
name,
|
|
43
|
-
url: bucket.endpoint + '/' + bucket.name + '/index.html',
|
|
44
|
-
bucket
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
exports.publish = publish;
|
|
48
|
-
//# sourceMappingURL=publish.js.map
|
package/lib/publish.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":";;;AAAA,oDAAkE;AAClE,qCAKkB;AAClB,0CAAsC;AACtC,+BAA4B;AAC5B,2BAA8B;AAY9B;;;;;GAKG;AAEH;;;;;;;;;;GAUG;AACI,KAAK,UAAU,OAAO,CAC3B,IAAY,EACZ,GAAW,EACX,GAAY,EACZ,IAAkB;IAElB,IAAI,CAAC,IAAA,iCAAmB,EAAC,IAAI,CAAC,EAAE;QAC9B,MAAM,IAAI,KAAK,CACb,uEAAuE,IAAI,EAAE,CAC9E,CAAC;KACH;IACD,MAAM,IAAI,GAAG,IAAI,EAAE,IAAI,IAAI,KAAK,CAAC;IACjC,MAAM,MAAM,GAAG,MAAM,IAAA,4BAAmB,EAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IACpD,IAAI,IAAI,EAAE;QACR,MAAM,IAAA,6BAAoB,EAAC,MAAM,CAAC,CAAC;KACpC;IACD,MAAM,KAAK,GAAG,MAAM,IAAA,kBAAO,EAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACtD,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,EAAE;QACpD,IAAI,CAAC,IAAA,aAAQ,EAAC,IAAA,WAAI,EAAC,GAAG,EAAE,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,EAAE;YAC5C,MAAM,IAAA,mBAAU,EAAC,IAAA,WAAI,EAAC,GAAG,EAAE,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;SACjD;KACF;IACD,OAAO;QACL,IAAI;QACJ,GAAG,EAAE,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,GAAG,aAAa;QACxD,MAAM;KACP,CAAC;AACJ,CAAC;AA3BD,0BA2BC"}
|