Skip to content

Commit 2c30919

Browse files
refactor(site): Remove untar dep and support nested folders on template version page (#6244)
1 parent 8360357 commit 2c30919

File tree

11 files changed

+95
-132
lines changed

11 files changed

+95
-132
lines changed

site/js-untar.d.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.

site/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@
5959
"history": "5.3.0",
6060
"i18next": "21.9.1",
6161
"jest-location-mock": "1.0.9",
62-
"js-untar": "2.0.0",
6362
"just-debounce-it": "3.1.1",
6463
"lodash": "4.17.21",
6564
"playwright": "^1.29.2",
@@ -103,7 +102,6 @@
103102
"@types/react-helmet": "6.1.5",
104103
"@types/react-syntax-highlighter": "15.5.5",
105104
"@types/semver": "7.3.12",
106-
"@types/tar-js": "^0.3.2",
107105
"@types/ua-parser-js": "0.7.36",
108106
"@types/uuid": "8.3.4",
109107
"@typescript-eslint/eslint-plugin": "5.50.0",

site/site.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,6 @@ func cspHeaders(next http.Handler) http.Handler {
326326
// Report all violations back to the server to log
327327
CSPDirectiveReportURI: {"/api/v2/csp/reports"},
328328
CSPFrameAncestors: {"'none'"},
329-
// worker for loading the .tar files on FE using js-untar
330-
CSPDirectiveWorkerSrc: {"'self' blob:"},
331329

332330
// Only scripts can manipulate the dom. This prevents someone from
333331
// naming themselves something like '<svg onload="alert(/cross-site-scripting/)" />'.

site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/TemplateVersionEditorPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const TemplateVersionEditorPage: FC = () => {
2727
},
2828
{
2929
onSuccess(data) {
30-
sendEvent({ type: "INITIALIZE", untarFiles: data.untarFiles })
30+
sendEvent({ type: "INITIALIZE", tarReader: data.tarReader })
3131
},
3232
},
3333
)

site/src/pages/TemplateVersionPage/TemplateVersionEditorPage/data.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { useQuery, UseQueryOptions } from "@tanstack/react-query"
22
import { getFile, getTemplateByName, getTemplateVersionByName } from "api/api"
3+
import { TarReader } from "util/tar"
34
import { createTemplateVersionFileTree } from "util/templateVersion"
4-
import untar, { File as UntarFile } from "js-untar"
55

66
const getTemplateVersionData = async (
77
orgId: string,
@@ -13,17 +13,15 @@ const getTemplateVersionData = async (
1313
getTemplateVersionByName(orgId, templateName, versionName),
1414
])
1515
const tarFile = await getFile(version.job.file_id)
16-
let untarFiles: UntarFile[] = []
17-
await untar(tarFile).then((files) => {
18-
untarFiles = files
19-
})
20-
const fileTree = await createTemplateVersionFileTree(untarFiles)
16+
const tarReader = new TarReader()
17+
await tarReader.readFile(tarFile)
18+
const fileTree = await createTemplateVersionFileTree(tarReader)
2119

2220
return {
2321
template,
2422
version,
2523
fileTree,
26-
untarFiles,
24+
tarReader,
2725
}
2826
}
2927

site/src/util/tar.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ test("tar", async () => {
99
writer.addFile("b.txt", new Blob(["world"]), { mtime })
1010
writer.addFile("c.txt", "", { mtime })
1111
writer.addFolder("etc", { mtime })
12-
writer.addFile("etc/d.txt", "", { mtime })
12+
writer.addFile("etc/d.txt", "Some text content", {
13+
mtime,
14+
user: "coder",
15+
group: "codergroup",
16+
mode: parseInt("777", 8),
17+
})
1318
const blob = await writer.write()
1419

1520
// Read
@@ -32,8 +37,11 @@ test("tar", async () => {
3237
})
3338
verifyFile(fileInfos[4], reader.getTextFile(fileInfos[4].name) as string, {
3439
name: "etc/d.txt",
35-
content: "",
40+
content: "Some text content",
3641
})
42+
expect(fileInfos[4].group).toEqual("codergroup")
43+
expect(fileInfos[4].user).toEqual("coder")
44+
expect(fileInfos[4].mode).toEqual(parseInt("777", 8))
3745
})
3846

3947
function verifyFile(

site/src/util/tar.ts

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ export interface ITarFileInfo {
1313
name: string
1414
type: TarFileType
1515
size: number
16+
mode: number
17+
mtime: number
18+
user: string
19+
group: string
1620
headerOffset: number
1721
}
1822

@@ -34,7 +38,7 @@ export interface ITarWriteOptions {
3438
}
3539

3640
export class TarReader {
37-
private fileInfo: ITarFileInfo[] = []
41+
public fileInfo: ITarFileInfo[] = []
3842
private _buffer: ArrayBuffer | null = null
3943

4044
constructor() {
@@ -64,22 +68,28 @@ export class TarReader {
6468
private readFileInfo() {
6569
this.fileInfo = []
6670
let offset = 0
67-
let fileSize = 0
68-
let fileName = ""
69-
let fileType: TarFileType
71+
7072
while (offset < this.buffer.byteLength - 512) {
71-
fileName = this.readFileName(offset)
73+
const fileName = this.readFileName(offset)
7274
if (!fileName) {
7375
break
7476
}
75-
fileType = this.readFileType(offset)
76-
fileSize = this.readFileSize(offset)
77+
const fileType = this.readFileType(offset)
78+
const fileSize = this.readFileSize(offset)
79+
const fileMode = this.readFileMode(offset)
80+
const fileMtime = this.readFileMtime(offset)
81+
const fileUser = this.readFileUser(offset)
82+
const fileGroup = this.readFileGroup(offset)
7783

7884
this.fileInfo.push({
7985
name: fileName,
8086
type: fileType,
8187
size: fileSize,
8288
headerOffset: offset,
89+
mode: fileMode,
90+
mtime: fileMtime,
91+
user: fileUser,
92+
group: fileGroup,
8393
})
8494

8595
offset += 512 + 512 * Math.floor((fileSize + 511) / 512)
@@ -100,6 +110,24 @@ export class TarReader {
100110
return this.readString(offset, 100)
101111
}
102112

113+
private readFileMode(offset: number) {
114+
const mode = this.readString(offset + 100, 8)
115+
return parseInt(mode, 8)
116+
}
117+
118+
private readFileMtime(offset: number) {
119+
const mtime = this.readString(offset + 136, 12)
120+
return parseInt(mtime, 8)
121+
}
122+
123+
private readFileUser(offset: number) {
124+
return this.readString(offset + 265, 32)
125+
}
126+
127+
private readFileGroup(offset: number) {
128+
return this.readString(offset + 297, 32)
129+
}
130+
103131
private readFileType(offset: number) {
104132
const typeView = new Uint8Array(this.buffer, offset + 156, 1)
105133
const typeStr = String.fromCharCode(typeView[0])

site/src/util/templateVersion.ts

Lines changed: 15 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as API from "api/api"
22
import { TemplateVersion } from "api/typesGenerated"
3-
import untar, { File as UntarFile } from "js-untar"
43
import { FileTree, setFile } from "./filetree"
4+
import { TarReader } from "./tar"
55

66
/**
77
* Content by filename
@@ -10,32 +10,16 @@ export type TemplateVersionFiles = Record<string, string>
1010

1111
export const getTemplateVersionFiles = async (
1212
version: TemplateVersion,
13-
allowedExtensions: string[],
14-
allowedFiles: string[],
1513
): Promise<TemplateVersionFiles> => {
1614
const files: TemplateVersionFiles = {}
1715
const tarFile = await API.getFile(version.job.file_id)
18-
const blobs: Record<string, Blob> = {}
19-
20-
await untar(tarFile).then(undefined, undefined, async (file) => {
21-
const paths = file.name.split("/")
22-
const filename = paths[paths.length - 1]
23-
const [_, extension] = filename.split(".")
24-
25-
if (
26-
allowedExtensions.includes(extension) ||
27-
allowedFiles.includes(filename)
28-
) {
29-
blobs[filename] = file.blob
16+
const tarReader = new TarReader()
17+
await tarReader.readFile(tarFile)
18+
for (const file of tarReader.fileInfo) {
19+
if (isAllowedFile(file.name)) {
20+
files[file.name] = tarReader.getTextFile(file.name) as string
3021
}
31-
})
32-
33-
await Promise.all(
34-
Object.entries(blobs).map(async ([filename, blob]) => {
35-
files[filename] = await blob.text()
36-
}),
37-
)
38-
22+
}
3923
return files
4024
}
4125

@@ -46,23 +30,17 @@ export const isAllowedFile = (name: string) => {
4630
}
4731

4832
export const createTemplateVersionFileTree = async (
49-
untarFiles: UntarFile[],
33+
tarReader: TarReader,
5034
): Promise<FileTree> => {
5135
let fileTree: FileTree = {}
52-
const blobs: Record<string, Blob> = {}
53-
54-
for (const untarFile of untarFiles) {
55-
if (isAllowedFile(untarFile.name)) {
56-
blobs[untarFile.name] = untarFile.blob
36+
for (const file of tarReader.fileInfo) {
37+
if (isAllowedFile(file.name)) {
38+
fileTree = setFile(
39+
file.name,
40+
tarReader.getTextFile(file.name) as string,
41+
fileTree,
42+
)
5743
}
5844
}
59-
60-
await Promise.all(
61-
Object.entries(blobs).map(async ([fullPath, blob]) => {
62-
const content = await blob.text()
63-
fileTree = setFile(fullPath, content, fileTree)
64-
}),
65-
)
66-
6745
return fileTree
6846
}

site/src/xServices/templateVersion/templateVersionXService.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -162,23 +162,9 @@ export const templateVersionMachine = createMachine(
162162
}
163163
const loadFilesPromises: ReturnType<typeof getTemplateVersionFiles>[] =
164164
[]
165-
const allowedExtensions = ["tf", "md"]
166-
const allowedFiles = ["Dockerfile"]
167-
loadFilesPromises.push(
168-
getTemplateVersionFiles(
169-
currentVersion,
170-
allowedExtensions,
171-
allowedFiles,
172-
),
173-
)
165+
loadFilesPromises.push(getTemplateVersionFiles(currentVersion))
174166
if (previousVersion) {
175-
loadFilesPromises.push(
176-
getTemplateVersionFiles(
177-
previousVersion,
178-
allowedExtensions,
179-
allowedFiles,
180-
),
181-
)
167+
loadFilesPromises.push(getTemplateVersionFiles(previousVersion))
182168
}
183169
const [currentFiles, previousFiles] = await Promise.all(
184170
loadFilesPromises,

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy