Switch TS build config to use webpack. Switch Uploader to use axios

This commit is contained in:
Pat Hartl 2023-08-27 18:17:52 -05:00
parent c3d281a1e4
commit f52ffc5426
16 changed files with 6007 additions and 213 deletions

View file

@ -5,6 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>aspnet-LANCommander-C1F79CFA-9767-4AD7-BD5A-2549F8328A2D</UserSecretsId>
<ApplicationIcon>wwwroot\favicon.ico</ApplicationIcon>
<TypeScriptModuleKind>none</TypeScriptModuleKind>
</PropertyGroup>
<ItemGroup>
<Content Remove="wwwroot\js\Upload.ts" />
@ -43,7 +44,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.1.5">
<PackageReference Include="Microsoft.TypeScript.MSBuild" Version="5.2.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>

View file

@ -32,8 +32,7 @@
<script src="~/_content/BlazorMonaco/jsInterop.js"></script>
<script src="~/_content/BlazorMonaco/lib/monaco-editor/min/vs/loader.js"></script>
<script src="~/_content/BlazorMonaco/lib/monaco-editor/min/vs/editor/editor.main.js"></script>
<script src="~/js/site.js"></script>
<script src="~/js/Upload.js"></script>
<script>window.Uploader = new Uploader();</script>
<script src="~/scripts/dist/bundle.js"></script>
</body>
</html>

View file

@ -2,29 +2,6 @@
"version": "1.0",
"defaultProvider": "cdnjs",
"libraries": [
{
"provider": "cdnjs",
"library": "selectize.js@0.15.2",
"destination": "wwwroot/lib/selectize.js/",
"files": [
"js/selectize.min.js",
"css/selectize.bootstrap5.min.css",
"css/selectize.min.css",
"css/selectize.default.min.css"
]
},
{
"provider": "jsdelivr",
"library": "@tabler/core@1.0.0-beta16",
"destination": "wwwroot/lib/tabler/core/",
"files": [
"dist/js/tabler.min.js",
"dist/css/tabler-vendors.min.css",
"dist/css/tabler.min.css",
"dist/css/tabler-payments.min.css",
"dist/css/tabler-flags.min.css"
]
},
{
"provider": "cdnjs",
"library": "monaco-editor@0.34.1",
@ -38,18 +15,6 @@
"min/vs/base/browser/ui/codicons/codicon/codicon.ttf"
]
},
{
"provider": "cdnjs",
"library": "tabler-icons@1.35.0",
"destination": "wwwroot/lib/tabler-icons/",
"files": [
"iconfont/tabler-icons.min.css",
"iconfont/fonts/tabler-icons.eot",
"iconfont/fonts/tabler-icons.ttf",
"iconfont/fonts/tabler-icons.woff",
"iconfont/fonts/tabler-icons.woff2"
]
},
{
"provider": "unpkg",
"library": "@antv/g2plot@1.1.28",
@ -67,6 +32,13 @@
"lib/xterm-addon-fit.min.js",
"lib/xterm-addon-fit.js.map"
]
},
{
"library": "axios@1.4.0",
"destination": "wwwroot/lib/axios/",
"files": [
"axios.min.js"
]
}
]
}

View file

@ -1,12 +1,10 @@
{
"compilerOptions": {
"noImplicitAny": false,
"noEmitOnError": true,
"removeComments": false,
"sourceMap": true,
"target": "es6"
"target": "ES6",
"module": "ESNext",
"outDir": "./dist",
"moduleResolution": "node"
},
"exclude": [
"node_modules"
]
}
"include": [ "wwwroot/scripts/**/*.ts" ],
"exclude": [ "node_modules" ]
}

View file

@ -1,117 +0,0 @@
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
class Chunk {
constructor(start, end, index) {
this.Start = start;
this.End = end;
this.Index = index;
}
}
class Uploader {
constructor() {
this.InitRoute = "/Upload/Init";
this.ChunkRoute = "/Upload/Chunk";
this.MaxChunkSize = 1024 * 1024 * 50;
}
Init(fileInputId, uploadButtonId, objectKeyInputId) {
this.FileInput = document.getElementById(fileInputId);
this.UploadButton = document.getElementById(uploadButtonId);
this.ObjectKeyInput = document.getElementById(objectKeyInputId);
this.Chunks = [];
this.UploadButton.onclick = (e) => __awaiter(this, void 0, void 0, function* () {
yield this.OnUploadButtonClicked(e);
});
}
Upload(fileInputId) {
return __awaiter(this, void 0, void 0, function* () {
this.FileInput = document.getElementById(fileInputId);
this.Chunks = [];
this.File = this.FileInput.files.item(0);
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
var response = yield fetch(this.InitRoute, {
method: "POST"
});
const data = yield response.json();
if (response.ok) {
this.Key = data.key;
this.GetChunks();
try {
for (let chunk of this.Chunks) {
yield this.UploadChunk(chunk);
}
}
catch (ex) {
this.OnError();
}
return this.Key;
}
return null;
});
}
OnUploadButtonClicked(e) {
return __awaiter(this, void 0, void 0, function* () {
e.preventDefault();
this.OnStart();
this.File = this.FileInput.files.item(0);
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
var response = yield fetch(this.InitRoute, {
method: "POST"
});
const data = yield response.json();
if (response.ok) {
this.Key = data.key;
this.GetChunks();
try {
for (let chunk of this.Chunks) {
yield this.UploadChunk(chunk);
}
this.ObjectKeyInput.value = this.Key;
var event = document.createEvent('HTMLEvents');
event.initEvent('change', false, true);
this.ObjectKeyInput.dispatchEvent(event);
this.OnComplete(this.Id, this.Key);
}
catch (ex) {
this.OnError();
}
}
});
}
UploadChunk(chunk) {
return __awaiter(this, void 0, void 0, function* () {
let formData = new FormData();
formData.append('file', this.File.slice(chunk.Start, chunk.End + 1));
formData.append('start', chunk.Start.toString());
formData.append('end', chunk.End.toString());
formData.append('key', this.Key);
formData.append('total', this.File.size.toString());
console.info(`Uploading chunk ${chunk.Index}/${this.TotalChunks}...`);
let chunkResponse = yield fetch(this.ChunkRoute, {
method: "POST",
body: formData
});
if (!chunkResponse)
throw `Error uploading chunk ${chunk.Index}/${this.TotalChunks}`;
var percent = Math.ceil((chunk.Index / this.TotalChunks) * 100);
let progress = document.querySelector('.ant-progress-bg');
progress.style.width = percent + '%';
});
}
GetChunks() {
for (let currentChunk = 1; currentChunk <= this.TotalChunks; currentChunk++) {
let start = (currentChunk - 1) * this.MaxChunkSize;
let end = (currentChunk * this.MaxChunkSize) - 1;
if (currentChunk == this.TotalChunks)
end = this.File.size;
this.Chunks.push(new Chunk(start, end, currentChunk));
}
}
}
//# sourceMappingURL=Upload.js.map

View file

@ -1 +0,0 @@
{"version":3,"file":"Upload.js","sourceRoot":"","sources":["Upload.ts"],"names":[],"mappings":"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"}

View file

@ -0,0 +1,11 @@
export default class Chunk {
Index: number;
Start: number;
End: number;
constructor(start: number, end: number, index: number) {
this.Start = start;
this.End = end;
this.Index = index;
}
}

View file

@ -0,0 +1,3 @@
export default class UploadInitResponse {
key: string = "";
}

View file

@ -1,32 +1,24 @@
class Chunk {
Index: number;
Start: number;
End: number;
import Chunk from './Chunk';
import UploadInitResponse from './UploadInitResponse';
import axios from 'axios';
constructor(start: number, end: number, index: number) {
this.Start = start;
this.End = end;
this.Index = index;
}
}
export default class Uploader {
FileInput: HTMLInputElement | undefined;
UploadButton: HTMLButtonElement | undefined;
ObjectKeyInput: HTMLInputElement | undefined;
class Uploader {
FileInput: HTMLInputElement;
UploadButton: HTMLButtonElement;
ObjectKeyInput: HTMLInputElement;
File: File;
File: File | undefined;
InitRoute: string = "/Upload/Init";
ChunkRoute: string = "/Upload/Chunk";
MaxChunkSize: number = 1024 * 1024 * 50;
TotalChunks: number;
CurrentChunk: number;
Chunks: Chunk[];
TotalChunks: number = 0;
CurrentChunk: number = 0;
Chunks: Chunk[] = [];
Key: string;
Id: string;
Key: string = "";
Id: string = "";
Init(fileInputId: string, uploadButtonId: string, objectKeyInputId: string) {
this.FileInput = document.getElementById(fileInputId) as HTMLInputElement;
@ -47,14 +39,10 @@ class Uploader {
this.File = this.FileInput.files.item(0);
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
var response = await fetch(this.InitRoute, {
method: "POST"
});
try {
var resp = await axios.post<UploadInitResponse>(this.InitRoute);
const data = await response.json();
if (response.ok) {
this.Key = data.key;
this.Key = resp.data.key;
this.GetChunks();
@ -68,9 +56,11 @@ class Uploader {
}
return this.Key;
}
} catch (ex) {
console.error(`Could not init upload: ${ex}`);
return null;
return null;
}
}
async OnUploadButtonClicked(e: MouseEvent) {
@ -81,14 +71,10 @@ class Uploader {
this.File = this.FileInput.files.item(0);
this.TotalChunks = Math.ceil(this.File.size / this.MaxChunkSize);
var response = await fetch(this.InitRoute, {
method: "POST"
});
try {
var resp = await axios.post<UploadInitResponse>(this.InitRoute);
const data = await response.json();
if (response.ok) {
this.Key = data.key;
this.Key = resp.data.key;
this.GetChunks();
@ -107,6 +93,8 @@ class Uploader {
catch (ex) {
this.OnError();
}
} catch (ex) {
console.error(`Could not init upload: ${ex}`);
}
}
@ -121,19 +109,22 @@ class Uploader {
console.info(`Uploading chunk ${chunk.Index}/${this.TotalChunks}...`);
let chunkResponse = await fetch(this.ChunkRoute, {
method: "POST",
body: formData
});
if (!chunkResponse)
try {
let chunkResponse = await axios({
method: "post",
url: this.ChunkRoute,
data: formData,
headers: { "Content-Type": "multipart/form-data" }
});
} catch (ex) {
throw `Error uploading chunk ${chunk.Index}/${this.TotalChunks}`;
} finally {
var percent = Math.ceil((chunk.Index / this.TotalChunks) * 100);
var percent = Math.ceil((chunk.Index / this.TotalChunks) * 100);
let progress: HTMLElement = document.querySelector('.ant-progress-bg');
let progress: HTMLElement = document.querySelector('.ant-progress-bg');
progress.style.width = percent + '%';
progress.style.width = percent + '%';
}
}
GetChunks() {

View file

@ -0,0 +1,3 @@
import Uploader from './Uploader';
(<any>window).Uploader = new Uploader();

File diff suppressed because it is too large Load diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,9 @@
{
"devDependencies": {
"axios": "^1.5.0",
"ts-loader": "^9.4.4",
"typescript": "^5.2.2",
"webpack": "^5.88.2",
"webpack-cli": "^5.1.4"
}
}

View file

@ -0,0 +1,11 @@
{
"compilerOptions": {
"target": "ES6",
"module": "ESNext",
"outDir": "./dist",
"moduleResolution": "node",
"sourceMap": true
},
"include": [ "**/*.ts" ],
"exclude": [ "node_modules" ]
}

View file

@ -0,0 +1,23 @@
const path = require('path');
module.exports = {
entry: './app.ts',
mode: 'development',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
},
resolve: {
extensions: ['.ts', '.js'],
},
module: {
rules: [
{
test: /\.ts$/,
use: 'ts-loader',
exclude: /node_modules/,
}
]
},
devtool: 'source-map'
}