-
-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathindex.tsx
164 lines (152 loc) · 6.58 KB
/
index.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
import { h } from "../deps.ts";
import { Layout } from "../components/layout.tsx";
import { Block } from "../components/block.tsx";
import { LabelButton } from "../components/label_button.tsx";
import { InputButton } from "../components/input_button.tsx";
import { ResultButton } from "../components/result_button.tsx";
import { CodeInline } from "../components/code_inline.tsx";
import { EXTENSIONS } from "../util/constants.ts";
export function Index() {
return (
<Layout
description
>
<Block>
<div class="flex flex(col lg:row)">
<div class="inset-y-0 left-0 w(full lg:3/5)">
crux.land is a free registry service meant for hosting small (≤
20kB) single deno scripts. All uploaded scripts are immutable and
will not be changed nor deleted unless there is a legal reason or if
it is found to be malicious.
<br />
<br />
To use crux.land simply upload a file with one of the supported file
extensions ({EXTENSIONS.map((ext, idx) => (
<span>
<CodeInline>{ext}</CodeInline>
{EXTENSIONS.length - 1 === idx ? "" : ", "}
</span>
))}) and if successful you will recieve a permanent link to said
file. This link may be used in deno or browsers import and
automatically serve the correct{" "}
<CodeInline>Content-Type</CodeInline>{" "}
header. An optional extension may be added to the end of the url but
is not necessary as it is automatically redirected to.
<br />
<br />
A custom name may also be requested to be associated with your
uploaded scripts. These aliases are versioned and can be updated
with new tags unlike the raw links for a script which are permanent
and therefor not versioned. To request an alias a GitHub account
login is required to prevent abuse.
</div>
<div class="flex flex-col inset-y-0 right-0 w(full lg:2/5)">
<input
type="file"
name="file"
id="file"
accept={EXTENSIONS.map((ext) => "." + ext).join(",")}
// @ts-ignore TS2322
onchange="
const file = document.getElementById('file');
const label = document.getElementById('label');
if (file.files[0]) {
label.innerText = file.files[0].name;
} else {
label.innerText = 'Choose a script';
}
"
required
hidden
/>
<div class="mb-2 mt(4 lg:0)">
<LabelButton
// @ts-ignore TS2322
id="label"
htmlFor="file"
>
Choose a script
</LabelButton>
</div>
<div class="mb-2 mt(2 lg:0)">
<InputButton
// @ts-ignore TS2322
type="button"
name="submit"
id="submit"
value="Upload"
onclick="
const file = document.getElementById('file');
const submit = document.getElementById('submit');
const result = document.getElementById('result');
const label = document.getElementById('label');
function encode(data) {
const base64abc = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L',
'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a',
'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',
'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4',
'5', '6', '7', '8', '9', '+', '/'];
const uint8 = new Uint8Array(data);
let result = '',
i;
const l = uint8.length;
for (i = 2; i < l; i += 3) {
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[((uint8[i - 1] & 0x0f) << 2) | (uint8[i] >> 6)];
result += base64abc[uint8[i] & 0x3f];
}
if (i === l + 1) {
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[(uint8[i - 2] & 0x03) << 4];
result += '==';
}
if (i === l) {
result += base64abc[uint8[i - 2] >> 2];
result += base64abc[((uint8[i - 2] & 0x03) << 4) | (uint8[i - 1] >> 4)];
result += base64abc[(uint8[i - 1] & 0x0f) << 2];
result += '=';
}
return result;
}
result.style.display = 'none';
submit.disabled = true;
submit.value = 'Uploading...';
file.files[0].arrayBuffer().then((buf) => {
fetch('/api/add', {
method: 'POST',
body: JSON.stringify({
name: file.files[0].name,
content: encode(buf)
}),
}).then(async (res) => {
submit.disabled = false;
submit.value = 'Upload';
if (res.ok) {
res.json().then(({ id }) => {
result.style.color = 'rgba(55, 65, 81, var(--tw-text-opacity))';
result.innerText = window.location.href + id;
});
} else {
res.json().then(({ error }) => {
result.style.color = 'rgba(220, 38, 38, var(--tw-text-opacity))';
result.innerText = error;
});
}
result.style.display = 'flex';
label.innerText = 'Choose a script';
});
});
"
/>
</div>
<div class="select-all cursor-text">
<ResultButton // @ts-ignore TS2322
id="result" />
</div>
</div>
</div>
</Block>
</Layout>
);
}