dropley 0.1.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.
Potentially problematic release.
This version of dropley might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/README.md +110 -0
- package/dist/api.d.ts +55 -0
- package/dist/api.js +126 -0
- package/dist/api.js.map +1 -0
- package/dist/args.d.ts +21 -0
- package/dist/args.js +83 -0
- package/dist/args.js.map +1 -0
- package/dist/bin/dropley.d.ts +2 -0
- package/dist/bin/dropley.js +4 -0
- package/dist/bin/dropley.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -0
- package/dist/collect.d.ts +15 -0
- package/dist/collect.js +59 -0
- package/dist/collect.js.map +1 -0
- package/dist/commands/context.d.ts +14 -0
- package/dist/commands/context.js +28 -0
- package/dist/commands/context.js.map +1 -0
- package/dist/commands/delete.d.ts +3 -0
- package/dist/commands/delete.js +14 -0
- package/dist/commands/delete.js.map +1 -0
- package/dist/commands/pack.d.ts +10 -0
- package/dist/commands/pack.js +45 -0
- package/dist/commands/pack.js.map +1 -0
- package/dist/commands/publish.d.ts +4 -0
- package/dist/commands/publish.js +94 -0
- package/dist/commands/publish.js.map +1 -0
- package/dist/commands/status.d.ts +3 -0
- package/dist/commands/status.js +27 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/update.d.ts +3 -0
- package/dist/commands/update.js +23 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +68 -0
- package/dist/config.js.map +1 -0
- package/dist/errors.d.ts +12 -0
- package/dist/errors.js +19 -0
- package/dist/errors.js.map +1 -0
- package/dist/mime.d.ts +1 -0
- package/dist/mime.js +47 -0
- package/dist/mime.js.map +1 -0
- package/dist/output.d.ts +9 -0
- package/dist/output.js +24 -0
- package/dist/output.js.map +1 -0
- package/dist/target.d.ts +5 -0
- package/dist/target.js +29 -0
- package/dist/target.js.map +1 -0
- package/dist/zip.d.ts +14 -0
- package/dist/zip.js +136 -0
- package/dist/zip.js.map +1 -0
- package/package.json +54 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../src/collect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ParsedArgs } from '../args.js';
|
|
2
|
+
export interface CommandContext {
|
|
3
|
+
shortId: string;
|
|
4
|
+
token?: string;
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
}
|
|
7
|
+
/** Variant where a token is guaranteed (update, delete). */
|
|
8
|
+
export interface AuthenticatedContext extends CommandContext {
|
|
9
|
+
token: string;
|
|
10
|
+
}
|
|
11
|
+
/** Context for tokenless commands (status shows public metadata without one). */
|
|
12
|
+
export declare function commandContext(parsed: ParsedArgs): CommandContext;
|
|
13
|
+
/** Context for commands that must authenticate (update, delete). */
|
|
14
|
+
export declare function commandContextWithToken(parsed: ParsedArgs): AuthenticatedContext;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { resolveBaseUrl, requireToken, resolveToken } from '../config.js';
|
|
2
|
+
import { UsageError } from '../errors.js';
|
|
3
|
+
import { parseTarget } from '../target.js';
|
|
4
|
+
function targetOf(parsed) {
|
|
5
|
+
const raw = parsed.positionals[0];
|
|
6
|
+
if (raw === undefined)
|
|
7
|
+
throw new UsageError('Missing <url-or-shortId> argument.');
|
|
8
|
+
return parseTarget(raw);
|
|
9
|
+
}
|
|
10
|
+
/** Context for tokenless commands (status shows public metadata without one). */
|
|
11
|
+
export function commandContext(parsed) {
|
|
12
|
+
const shortId = targetOf(parsed);
|
|
13
|
+
return {
|
|
14
|
+
shortId,
|
|
15
|
+
token: resolveToken(parsed.values.token, shortId),
|
|
16
|
+
baseUrl: resolveBaseUrl(parsed.values.api),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/** Context for commands that must authenticate (update, delete). */
|
|
20
|
+
export function commandContextWithToken(parsed) {
|
|
21
|
+
const shortId = targetOf(parsed);
|
|
22
|
+
return {
|
|
23
|
+
shortId,
|
|
24
|
+
token: requireToken(parsed.values.token, shortId),
|
|
25
|
+
baseUrl: resolveBaseUrl(parsed.values.api),
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/commands/context.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAC1E,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAa3C,SAAS,QAAQ,CAAC,MAAkB;IAClC,MAAM,GAAG,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAClC,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,oCAAoC,CAAC,CAAC;IAClF,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,MAAkB;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO;QACL,OAAO;QACP,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;QACjD,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;KAC3C,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,uBAAuB,CAAC,MAAkB;IACxD,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;IACjC,OAAO;QACL,OAAO;QACP,KAAK,EAAE,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC;QACjD,OAAO,EAAE,cAAc,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;KAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { deleteArtifact } from '../api.js';
|
|
2
|
+
import { commandContextWithToken } from './context.js';
|
|
3
|
+
export async function del(parsed, io) {
|
|
4
|
+
const { shortId, token, baseUrl } = commandContextWithToken(parsed);
|
|
5
|
+
const result = await deleteArtifact(baseUrl, shortId, token);
|
|
6
|
+
if (io.json) {
|
|
7
|
+
io.printJson(result);
|
|
8
|
+
}
|
|
9
|
+
else {
|
|
10
|
+
io.stdout(`deleted: ${shortId}`);
|
|
11
|
+
}
|
|
12
|
+
return 0;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=delete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"delete.js","sourceRoot":"","sources":["../../src/commands/delete.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAGvD,MAAM,CAAC,KAAK,UAAU,GAAG,CAAC,MAAkB,EAAE,EAAM;IAClD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAE7D,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACZ,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,MAAM,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ParsedArgs } from '../args.js';
|
|
2
|
+
import type { Io } from '../output.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a byte-for-byte reproducible zip archive of a directory
|
|
5
|
+
* (stable ordering, fixed timestamps, OS junk files excluded).
|
|
6
|
+
*
|
|
7
|
+
* Note: Dropley serves uploads as-is and does not expand archives — publish a
|
|
8
|
+
* directory directly for hosting; `pack` is for archiving and reproducible builds.
|
|
9
|
+
*/
|
|
10
|
+
export declare function pack(parsed: ParsedArgs, io: Io): Promise<number>;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { createHash } from 'node:crypto';
|
|
2
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
3
|
+
import { basename, dirname, join, resolve } from 'node:path';
|
|
4
|
+
import { collectFiles } from '../collect.js';
|
|
5
|
+
import { createZip } from '../zip.js';
|
|
6
|
+
import { UsageError } from '../errors.js';
|
|
7
|
+
/**
|
|
8
|
+
* Creates a byte-for-byte reproducible zip archive of a directory
|
|
9
|
+
* (stable ordering, fixed timestamps, OS junk files excluded).
|
|
10
|
+
*
|
|
11
|
+
* Note: Dropley serves uploads as-is and does not expand archives — publish a
|
|
12
|
+
* directory directly for hosting; `pack` is for archiving and reproducible builds.
|
|
13
|
+
*/
|
|
14
|
+
export async function pack(parsed, io) {
|
|
15
|
+
const inputPath = parsed.positionals[0];
|
|
16
|
+
if (!inputPath)
|
|
17
|
+
throw new UsageError('Missing <dir> argument.');
|
|
18
|
+
const outFlag = parsed.values.out;
|
|
19
|
+
if (outFlag !== undefined && !outFlag.endsWith('.zip')) {
|
|
20
|
+
throw new UsageError(`Output must end with .zip: ${outFlag}`);
|
|
21
|
+
}
|
|
22
|
+
const abs = resolve(inputPath);
|
|
23
|
+
const files = await collectFiles(abs);
|
|
24
|
+
const entries = files.map((f) => ({
|
|
25
|
+
name: f.path,
|
|
26
|
+
data: readFileSync(f.absPath),
|
|
27
|
+
}));
|
|
28
|
+
const archive = createZip(entries);
|
|
29
|
+
// Default output sits BESIDE the source directory so repeated packs never
|
|
30
|
+
// include a previous archive as input.
|
|
31
|
+
const outPath = resolve(outFlag ?? join(dirname(abs), `${basename(abs)}.zip`));
|
|
32
|
+
writeFileSync(outPath, archive);
|
|
33
|
+
const sha256 = createHash('sha256').update(archive).digest('hex');
|
|
34
|
+
if (io.json) {
|
|
35
|
+
io.printJson({ out: outPath, sha256, bytes: archive.length, files: entries.length });
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
io.stdout(`out: ${outPath}`);
|
|
39
|
+
io.stdout(`sha256: ${sha256}`);
|
|
40
|
+
io.stdout(`bytes: ${archive.length}`);
|
|
41
|
+
io.stdout(`files: ${entries.length}`);
|
|
42
|
+
}
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=pack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.js","sourceRoot":"","sources":["../../src/commands/pack.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtD,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAiB,MAAM,WAAW,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAI1C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,MAAkB,EAAE,EAAM;IACnD,MAAM,SAAS,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IACxC,IAAI,CAAC,SAAS;QAAE,MAAM,IAAI,UAAU,CAAC,yBAAyB,CAAC,CAAC;IAChE,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;IAClC,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACvD,MAAM,IAAI,UAAU,CAAC,8BAA8B,OAAO,EAAE,CAAC,CAAC;IAChE,CAAC;IAED,MAAM,GAAG,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,MAAM,YAAY,CAAC,GAAG,CAAC,CAAC;IAEtC,MAAM,OAAO,GAAe,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QAC5C,IAAI,EAAE,CAAC,CAAC,IAAI;QACZ,IAAI,EAAE,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC;KAC9B,CAAC,CAAC,CAAC;IACJ,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IAEnC,0EAA0E;IAC1E,uCAAuC;IACvC,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/E,aAAa,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAElE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACZ,EAAE,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACvF,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,MAAM,CAAC,QAAQ,OAAO,EAAE,CAAC,CAAC;QAC7B,EAAE,CAAC,MAAM,CAAC,WAAW,MAAM,EAAE,CAAC,CAAC;QAC/B,EAAE,CAAC,MAAM,CAAC,UAAU,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;QACtC,EAAE,CAAC,MAAM,CAAC,UAAU,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { statSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { basename, resolve } from 'node:path';
|
|
3
|
+
import { contentTypeForPath } from '../mime.js';
|
|
4
|
+
import { collectFiles, MAX_TOTAL_BYTES } from '../collect.js';
|
|
5
|
+
import { createArtifact } from '../api.js';
|
|
6
|
+
import { resolveBaseUrl, saveToken } from '../config.js';
|
|
7
|
+
import { UsageError } from '../errors.js';
|
|
8
|
+
function formatBytes(n) {
|
|
9
|
+
return n >= 1024 * 1024 ? `${(n / 1024 / 1024).toFixed(1)}MB` : `${Math.max(1, Math.round(n / 1024))}KB`;
|
|
10
|
+
}
|
|
11
|
+
function loadParts(files) {
|
|
12
|
+
return files.map((f) => ({
|
|
13
|
+
path: f.path,
|
|
14
|
+
contentType: contentTypeForPath(f.absPath),
|
|
15
|
+
data: readFileSync(f.absPath),
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
export function validateExpiry(value) {
|
|
19
|
+
if (!/^\d+[hd]$/.test(value)) {
|
|
20
|
+
throw new UsageError(`Invalid expiry "${value}". Use a value like 1d, 3d, 7d, 15d, 30d or 12h.`);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
export async function publish(parsed, io) {
|
|
24
|
+
const inputPath = parsed.positionals[0];
|
|
25
|
+
if (!inputPath)
|
|
26
|
+
throw new UsageError('Missing <path> argument.');
|
|
27
|
+
const expiry = parsed.values.expiry;
|
|
28
|
+
if (expiry !== undefined)
|
|
29
|
+
validateExpiry(expiry);
|
|
30
|
+
const abs = resolve(inputPath);
|
|
31
|
+
let st;
|
|
32
|
+
try {
|
|
33
|
+
st = statSync(abs);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
throw new UsageError(`No such file or directory: ${inputPath}`);
|
|
37
|
+
}
|
|
38
|
+
let files;
|
|
39
|
+
let renamedFrom;
|
|
40
|
+
if (st.isDirectory()) {
|
|
41
|
+
files = await collectFiles(abs);
|
|
42
|
+
if (!files.some((f) => f.path === 'index.html')) {
|
|
43
|
+
throw new UsageError(`No index.html found at the root of ${inputPath}. Dropley requires an entry file named index.html.`);
|
|
44
|
+
}
|
|
45
|
+
io.stderr(`Packing ${files.length} file${files.length === 1 ? '' : 's'} (${formatBytes(files.reduce((n, f) => n + f.size, 0))})…`);
|
|
46
|
+
}
|
|
47
|
+
else if (st.isFile()) {
|
|
48
|
+
const size = st.size;
|
|
49
|
+
if (size > MAX_TOTAL_BYTES) {
|
|
50
|
+
throw new UsageError(`File is ${formatBytes(size)}; the limit is ${MAX_TOTAL_BYTES / 1024 / 1024}MB.`);
|
|
51
|
+
}
|
|
52
|
+
const name = basename(abs);
|
|
53
|
+
if (name !== 'index.html')
|
|
54
|
+
renamedFrom = name;
|
|
55
|
+
files = [{ absPath: abs, path: name, size }];
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
throw new UsageError(`Not a regular file or directory: ${inputPath}`);
|
|
59
|
+
}
|
|
60
|
+
// Single-file publishes are always served as the site entry (index.html).
|
|
61
|
+
const parts = st.isFile() && !files.some((f) => f.path === 'index.html')
|
|
62
|
+
? [
|
|
63
|
+
{
|
|
64
|
+
path: 'index.html',
|
|
65
|
+
contentType: contentTypeForPath(abs),
|
|
66
|
+
data: readFileSync(abs),
|
|
67
|
+
},
|
|
68
|
+
]
|
|
69
|
+
: loadParts(files);
|
|
70
|
+
io.stderr('Uploading…');
|
|
71
|
+
const baseUrl = resolveBaseUrl(parsed.values.api);
|
|
72
|
+
const result = await createArtifact(baseUrl, parts, { expiry });
|
|
73
|
+
try {
|
|
74
|
+
saveToken(result.shortId, result.artifactToken);
|
|
75
|
+
io.stderr(`Token saved for ${result.shortId} (used automatically by status/update/delete).`);
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
io.stderr('Warning: could not save token locally — keep it to update or delete this artifact.');
|
|
79
|
+
}
|
|
80
|
+
if (renamedFrom) {
|
|
81
|
+
io.stderr(`Entry uploaded as index.html (from ${renamedFrom}).`);
|
|
82
|
+
}
|
|
83
|
+
if (io.json) {
|
|
84
|
+
io.printJson(result);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
io.stdout(`url: ${result.url}`);
|
|
88
|
+
io.stdout(`token: ${result.artifactToken}`);
|
|
89
|
+
if (result.expiresAt)
|
|
90
|
+
io.stdout(`expires: ${result.expiresAt}`);
|
|
91
|
+
}
|
|
92
|
+
return 0;
|
|
93
|
+
}
|
|
94
|
+
//# sourceMappingURL=publish.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { getArtifact } from '../api.js';
|
|
2
|
+
import { commandContext } from './context.js';
|
|
3
|
+
function humanValue(v) {
|
|
4
|
+
if (v === null || v === undefined)
|
|
5
|
+
return '-';
|
|
6
|
+
if (Array.isArray(v))
|
|
7
|
+
return v.length > 0 ? v.map(String).join(', ') : '-';
|
|
8
|
+
if (typeof v === 'object')
|
|
9
|
+
return JSON.stringify(v);
|
|
10
|
+
const s = String(v);
|
|
11
|
+
return s.length > 0 ? s : '-';
|
|
12
|
+
}
|
|
13
|
+
export async function status(parsed, io) {
|
|
14
|
+
const { shortId, token, baseUrl } = commandContext(parsed);
|
|
15
|
+
if (!token)
|
|
16
|
+
io.stderr('No artifact token found — showing public metadata only.');
|
|
17
|
+
const info = await getArtifact(baseUrl, shortId, token);
|
|
18
|
+
if (io.json) {
|
|
19
|
+
io.printJson(info);
|
|
20
|
+
return 0;
|
|
21
|
+
}
|
|
22
|
+
for (const [key, value] of Object.entries(info)) {
|
|
23
|
+
io.stdout(`${key}: ${humanValue(value)}`);
|
|
24
|
+
}
|
|
25
|
+
return 0;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAC;AAExC,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAG9C,SAAS,UAAU,CAAC,CAAU;IAC5B,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC;IAC9C,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;IAC3E,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IACpD,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACpB,OAAO,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAkB,EAAE,EAAM;IACrD,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IAC3D,IAAI,CAAC,KAAK;QAAE,EAAE,CAAC,MAAM,CAAC,yDAAyD,CAAC,CAAC;IAEjF,MAAM,IAAI,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,CAAC;IAExD,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACZ,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACnB,OAAO,CAAC,CAAC;IACX,CAAC;IACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,EAAE,CAAC,MAAM,CAAC,GAAG,GAAG,KAAK,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { updateArtifact } from '../api.js';
|
|
2
|
+
import { commandContextWithToken } from './context.js';
|
|
3
|
+
import { UsageError } from '../errors.js';
|
|
4
|
+
import { validateExpiry } from './publish.js';
|
|
5
|
+
export async function update(parsed, io) {
|
|
6
|
+
const expiry = parsed.values.expiry;
|
|
7
|
+
if (expiry === undefined) {
|
|
8
|
+
throw new UsageError('Nothing to update. Pass --expiry <value> (e.g. --expiry 7d).');
|
|
9
|
+
}
|
|
10
|
+
validateExpiry(expiry);
|
|
11
|
+
const { shortId, token, baseUrl } = commandContextWithToken(parsed);
|
|
12
|
+
const result = await updateArtifact(baseUrl, shortId, token, { expiry });
|
|
13
|
+
if (io.json) {
|
|
14
|
+
io.printJson(result);
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
io.stdout(`updated: ${shortId}`);
|
|
18
|
+
if (result.expiresAt)
|
|
19
|
+
io.stdout(`expires: ${result.expiresAt}`);
|
|
20
|
+
}
|
|
21
|
+
return 0;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,MAAkB,EAAE,EAAM;IACrD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC;IACpC,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;QACzB,MAAM,IAAI,UAAU,CAAC,8DAA8D,CAAC,CAAC;IACvF,CAAC;IACD,cAAc,CAAC,MAAM,CAAC,CAAC;IAEvB,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,GAAG,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACpE,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAEzE,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC;QACZ,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;SAAM,CAAC;QACN,EAAE,CAAC,MAAM,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;QACjC,IAAI,MAAM,CAAC,SAAS;YAAE,EAAE,CAAC,MAAM,CAAC,YAAY,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;IAClE,CAAC;IACD,OAAO,CAAC,CAAC;AACX,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function resolveBaseUrl(flagValue?: string): string;
|
|
2
|
+
export declare function readSavedToken(shortId: string): string | undefined;
|
|
3
|
+
export declare function saveToken(shortId: string, token: string): void;
|
|
4
|
+
/**
|
|
5
|
+
* Token precedence: --token flag > DROPLEY_TOKEN env > saved publish token.
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveToken(flagValue: string | undefined, shortId: string): string | undefined;
|
|
8
|
+
export declare function requireToken(flagValue: string | undefined, shortId: string): string;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { dirname, join } from 'node:path';
|
|
4
|
+
import { DEFAULT_BASE_URL } from './api.js';
|
|
5
|
+
import { AuthError, UsageError } from './errors.js';
|
|
6
|
+
export function resolveBaseUrl(flagValue) {
|
|
7
|
+
const raw = flagValue ?? process.env.DROPLEY_API ?? DEFAULT_BASE_URL;
|
|
8
|
+
if (!/^https?:\/\//i.test(raw)) {
|
|
9
|
+
throw new UsageError(`Invalid API base URL: ${raw} (must start with http:// or https://)`);
|
|
10
|
+
}
|
|
11
|
+
return raw.replace(/\/+$/, '');
|
|
12
|
+
}
|
|
13
|
+
function tokenStorePath() {
|
|
14
|
+
const configHome = process.env.DROPLEY_CONFIG_DIR ?? (process.env.XDG_CONFIG_HOME || join(homedir(), '.config'));
|
|
15
|
+
return join(configHome, 'dropley', 'tokens.json');
|
|
16
|
+
}
|
|
17
|
+
export function readSavedToken(shortId) {
|
|
18
|
+
try {
|
|
19
|
+
const path = tokenStorePath();
|
|
20
|
+
if (!existsSync(path))
|
|
21
|
+
return undefined;
|
|
22
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
23
|
+
if (parsed && typeof parsed === 'object' && 'tokens' in parsed) {
|
|
24
|
+
const tokens = parsed.tokens;
|
|
25
|
+
const value = tokens?.[shortId];
|
|
26
|
+
return typeof value === 'string' && value.length > 0 ? value : undefined;
|
|
27
|
+
}
|
|
28
|
+
return undefined;
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function saveToken(shortId, token) {
|
|
35
|
+
const path = tokenStorePath();
|
|
36
|
+
let tokens = {};
|
|
37
|
+
try {
|
|
38
|
+
const parsed = JSON.parse(readFileSync(path, 'utf8'));
|
|
39
|
+
if (parsed && typeof parsed === 'object' && 'tokens' in parsed) {
|
|
40
|
+
tokens = parsed.tokens ?? {};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
// missing/corrupt store → start fresh
|
|
45
|
+
}
|
|
46
|
+
tokens[shortId] = token;
|
|
47
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
48
|
+
writeFileSync(path, `${JSON.stringify({ version: 1, tokens }, null, 2)}\n`, { mode: 0o600 });
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Token precedence: --token flag > DROPLEY_TOKEN env > saved publish token.
|
|
52
|
+
*/
|
|
53
|
+
export function resolveToken(flagValue, shortId) {
|
|
54
|
+
if (flagValue)
|
|
55
|
+
return flagValue;
|
|
56
|
+
const env = process.env.DROPLEY_TOKEN;
|
|
57
|
+
if (env)
|
|
58
|
+
return env;
|
|
59
|
+
return readSavedToken(shortId);
|
|
60
|
+
}
|
|
61
|
+
export function requireToken(flagValue, shortId) {
|
|
62
|
+
const token = resolveToken(flagValue, shortId);
|
|
63
|
+
if (!token) {
|
|
64
|
+
throw new AuthError('No artifact token found. Pass --token <token>, set DROPLEY_TOKEN, or publish this artifact from this machine first.');
|
|
65
|
+
}
|
|
66
|
+
return token;
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare class UsageError extends Error {
|
|
2
|
+
constructor(message: string);
|
|
3
|
+
}
|
|
4
|
+
/** Environmental failure (e.g. a required credential is missing). Exit 1. */
|
|
5
|
+
export declare class AuthError extends Error {
|
|
6
|
+
constructor(message: string);
|
|
7
|
+
}
|
|
8
|
+
export declare const EXIT: {
|
|
9
|
+
readonly ok: 0;
|
|
10
|
+
readonly failure: 1;
|
|
11
|
+
readonly usage: 2;
|
|
12
|
+
};
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export class UsageError extends Error {
|
|
2
|
+
constructor(message) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'UsageError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** Environmental failure (e.g. a required credential is missing). Exit 1. */
|
|
8
|
+
export class AuthError extends Error {
|
|
9
|
+
constructor(message) {
|
|
10
|
+
super(message);
|
|
11
|
+
this.name = 'AuthError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
export const EXIT = {
|
|
15
|
+
ok: 0,
|
|
16
|
+
failure: 1,
|
|
17
|
+
usage: 2,
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,UAAW,SAAQ,KAAK;IACnC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,YAAY,CAAC;IAC3B,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,EAAE,EAAE,CAAC;IACL,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,CAAC;CACA,CAAC"}
|
package/dist/mime.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function contentTypeForPath(filePath: string): string;
|
package/dist/mime.js
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const EXT_TYPES = {
|
|
2
|
+
html: 'text/html',
|
|
3
|
+
htm: 'text/html',
|
|
4
|
+
css: 'text/css',
|
|
5
|
+
js: 'text/javascript',
|
|
6
|
+
mjs: 'text/javascript',
|
|
7
|
+
cjs: 'text/javascript',
|
|
8
|
+
json: 'application/json',
|
|
9
|
+
map: 'application/json',
|
|
10
|
+
txt: 'text/plain; charset=utf-8',
|
|
11
|
+
md: 'text/markdown; charset=utf-8',
|
|
12
|
+
csv: 'text/csv',
|
|
13
|
+
xml: 'application/xml',
|
|
14
|
+
yaml: 'text/yaml',
|
|
15
|
+
yml: 'text/yaml',
|
|
16
|
+
svg: 'image/svg+xml',
|
|
17
|
+
png: 'image/png',
|
|
18
|
+
jpg: 'image/jpeg',
|
|
19
|
+
jpeg: 'image/jpeg',
|
|
20
|
+
gif: 'image/gif',
|
|
21
|
+
webp: 'image/webp',
|
|
22
|
+
avif: 'image/avif',
|
|
23
|
+
bmp: 'image/bmp',
|
|
24
|
+
ico: 'image/x-icon',
|
|
25
|
+
woff: 'font/woff',
|
|
26
|
+
woff2: 'font/woff2',
|
|
27
|
+
ttf: 'font/ttf',
|
|
28
|
+
otf: 'font/otf',
|
|
29
|
+
eot: 'application/vnd.ms-fontobject',
|
|
30
|
+
mp3: 'audio/mpeg',
|
|
31
|
+
wav: 'audio/wav',
|
|
32
|
+
ogg: 'audio/ogg',
|
|
33
|
+
mp4: 'video/mp4',
|
|
34
|
+
webm: 'video/webm',
|
|
35
|
+
pdf: 'application/pdf',
|
|
36
|
+
wasm: 'application/wasm',
|
|
37
|
+
zip: 'application/zip',
|
|
38
|
+
};
|
|
39
|
+
const DEFAULT_TYPE = 'application/octet-stream';
|
|
40
|
+
export function contentTypeForPath(filePath) {
|
|
41
|
+
const base = filePath.slice(Math.max(filePath.lastIndexOf('/'), filePath.lastIndexOf('\\')) + 1);
|
|
42
|
+
const dot = base.lastIndexOf('.');
|
|
43
|
+
if (dot <= 0)
|
|
44
|
+
return DEFAULT_TYPE;
|
|
45
|
+
return EXT_TYPES[base.slice(dot + 1).toLowerCase()] ?? DEFAULT_TYPE;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=mime.js.map
|
package/dist/mime.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mime.js","sourceRoot":"","sources":["../src/mime.ts"],"names":[],"mappings":"AAAA,MAAM,SAAS,GAA2B;IACxC,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,UAAU;IACf,EAAE,EAAE,iBAAiB;IACrB,GAAG,EAAE,iBAAiB;IACtB,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,kBAAkB;IACvB,GAAG,EAAE,2BAA2B;IAChC,EAAE,EAAE,8BAA8B;IAClC,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,WAAW;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,YAAY;IACjB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,cAAc;IACnB,IAAI,EAAE,WAAW;IACjB,KAAK,EAAE,YAAY;IACnB,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,UAAU;IACf,GAAG,EAAE,+BAA+B;IACpC,GAAG,EAAE,YAAY;IACjB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,GAAG,EAAE,WAAW;IAChB,IAAI,EAAE,YAAY;IAClB,GAAG,EAAE,iBAAiB;IACtB,IAAI,EAAE,kBAAkB;IACxB,GAAG,EAAE,iBAAiB;CACvB,CAAC;AAEF,MAAM,YAAY,GAAG,0BAA0B,CAAC;AAEhD,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,WAAW,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjG,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,YAAY,CAAC;IAClC,OAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,IAAI,YAAY,CAAC;AACtE,CAAC"}
|
package/dist/output.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ApiError } from './api.js';
|
|
2
|
+
export interface Io {
|
|
3
|
+
stdout(message: string): void;
|
|
4
|
+
stderr(message: string): void;
|
|
5
|
+
printJson(value: unknown): void;
|
|
6
|
+
readonly json: boolean;
|
|
7
|
+
}
|
|
8
|
+
export declare function createIo(jsonMode: boolean): Io;
|
|
9
|
+
export declare function formatApiError(err: ApiError): string;
|
package/dist/output.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { ApiError } from './api.js';
|
|
2
|
+
export function createIo(jsonMode) {
|
|
3
|
+
return {
|
|
4
|
+
stdout: (m) => process.stdout.write(m.endsWith('\n') ? m : `${m}\n`),
|
|
5
|
+
stderr: (m) => process.stderr.write(m.endsWith('\n') ? m : `${m}\n`),
|
|
6
|
+
printJson: (v) => process.stdout.write(`${JSON.stringify(v, null, 2)}\n`),
|
|
7
|
+
json: jsonMode,
|
|
8
|
+
};
|
|
9
|
+
}
|
|
10
|
+
export function formatApiError(err) {
|
|
11
|
+
const lines = [`error: ${err.message}`];
|
|
12
|
+
if (err.code)
|
|
13
|
+
lines.push(`code: ${err.code}`);
|
|
14
|
+
if (err.status > 0)
|
|
15
|
+
lines.push(`http: ${err.status}`);
|
|
16
|
+
if (err.retryAfter !== undefined)
|
|
17
|
+
lines.push(`retry-after: ${err.retryAfter}s`);
|
|
18
|
+
if (err.hint)
|
|
19
|
+
lines.push(`hint: ${err.hint}`);
|
|
20
|
+
if (err.requestId)
|
|
21
|
+
lines.push(`request-id: ${err.requestId}`);
|
|
22
|
+
return lines.join('\n');
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"output.js","sourceRoot":"","sources":["../src/output.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AASpC,MAAM,UAAU,QAAQ,CAAC,QAAiB;IACxC,OAAO;QACL,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACpE,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;QACpE,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC;QACzE,IAAI,EAAE,QAAQ;KACf,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAa;IAC1C,MAAM,KAAK,GAAG,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;IACxC,IAAI,GAAG,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;IACtD,IAAI,GAAG,CAAC,UAAU,KAAK,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,GAAG,CAAC,UAAU,GAAG,CAAC,CAAC;IAChF,IAAI,GAAG,CAAC,IAAI;QAAE,KAAK,CAAC,IAAI,CAAC,SAAS,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC;IAC9C,IAAI,GAAG,CAAC,SAAS;QAAE,KAAK,CAAC,IAAI,CAAC,eAAe,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/target.d.ts
ADDED
package/dist/target.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { UsageError } from './errors.js';
|
|
2
|
+
const ID_PATTERN = /^[A-Za-z0-9_-]{4,64}$/;
|
|
3
|
+
/**
|
|
4
|
+
* Accepts a bare short ID or a full artifact URL
|
|
5
|
+
* (e.g. https://preview.dropley.app/p/aB3cD5eF) and returns the short ID.
|
|
6
|
+
*/
|
|
7
|
+
export function parseTarget(raw) {
|
|
8
|
+
const input = raw.trim();
|
|
9
|
+
if (/^https?:\/\//i.test(input)) {
|
|
10
|
+
let url;
|
|
11
|
+
try {
|
|
12
|
+
url = new URL(input);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
throw new UsageError(`Invalid URL: ${input}`);
|
|
16
|
+
}
|
|
17
|
+
const segments = url.pathname.split('/').filter((s) => s.length > 0);
|
|
18
|
+
const last = segments.at(-1);
|
|
19
|
+
if (!last || !ID_PATTERN.test(last)) {
|
|
20
|
+
throw new UsageError(`Could not find a short ID in ${input}`);
|
|
21
|
+
}
|
|
22
|
+
return last;
|
|
23
|
+
}
|
|
24
|
+
if (!ID_PATTERN.test(input)) {
|
|
25
|
+
throw new UsageError(`Invalid short ID: ${input}. Pass a short ID or an artifact URL like https://preview.dropley.app/p/<shortId>.`);
|
|
26
|
+
}
|
|
27
|
+
return input;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=target.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAE3C;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACrC,MAAM,KAAK,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IACzB,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAChC,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,IAAI,UAAU,CAAC,gBAAgB,KAAK,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACrE,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;QAC7B,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,UAAU,CAAC,gCAAgC,KAAK,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,UAAU,CAClB,qBAAqB,KAAK,oFAAoF,CAC/G,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
package/dist/zip.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal deterministic ZIP writer.
|
|
3
|
+
*
|
|
4
|
+
* Byte-for-byte reproducible output for identical inputs:
|
|
5
|
+
* - entries sorted by name (code-unit order), duplicates rejected
|
|
6
|
+
* - names normalized to POSIX, no leading slashes
|
|
7
|
+
* - fixed DOS timestamp (1980-01-01 00:00:00), no extra fields, no real mtimes
|
|
8
|
+
* - UTF-8 flag set; per-entry DEFLATE when smaller than STORE
|
|
9
|
+
*/
|
|
10
|
+
export interface ZipEntry {
|
|
11
|
+
name: string;
|
|
12
|
+
data: Uint8Array;
|
|
13
|
+
}
|
|
14
|
+
export declare function createZip(inputEntries: readonly ZipEntry[]): Buffer;
|