@andie/openlist 0.0.1

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.
@@ -0,0 +1,173 @@
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.resolveConfigPath = resolveConfigPath;
40
+ exports.readUserConfig = readUserConfig;
41
+ exports.writeUserConfig = writeUserConfig;
42
+ exports.resolveEffectiveConfig = resolveEffectiveConfig;
43
+ const node_crypto_1 = require("node:crypto");
44
+ const nodeFs = __importStar(require("node:fs/promises"));
45
+ const node_os_1 = __importDefault(require("node:os"));
46
+ const node_path_1 = __importDefault(require("node:path"));
47
+ const result_1 = require("../model/result");
48
+ const redact_1 = require("./redact");
49
+ const CONFIG_DIR_NAME = "openlist";
50
+ const CONFIG_FILE_NAME = "config.json";
51
+ function resolveConfigPath(env) {
52
+ const configHome = env.XDG_CONFIG_HOME ??
53
+ node_path_1.default.join(env.HOME ?? env.USERPROFILE ?? node_os_1.default.homedir(), ".config");
54
+ return node_path_1.default.join(configHome, CONFIG_DIR_NAME, CONFIG_FILE_NAME);
55
+ }
56
+ async function readUserConfig(env, deps = {}) {
57
+ const fs = deps.fs ?? nodeFs;
58
+ const configPath = resolveConfigPath(env);
59
+ let raw;
60
+ try {
61
+ raw = await fs.readFile(configPath, "utf8");
62
+ }
63
+ catch (error) {
64
+ if (isNodeError(error) && error.code === "ENOENT") {
65
+ return {};
66
+ }
67
+ throw new result_1.OpenListError("CONFIG_READ_FAILED", "Failed to read OpenList config", 2, {
68
+ path: configPath
69
+ });
70
+ }
71
+ let parsed;
72
+ try {
73
+ parsed = JSON.parse(raw);
74
+ }
75
+ catch {
76
+ throw new result_1.OpenListError("CONFIG_INVALID", "OpenList config is not valid JSON", 2, {
77
+ path: configPath
78
+ });
79
+ }
80
+ if (!isRecord(parsed)) {
81
+ throw new result_1.OpenListError("CONFIG_INVALID", "OpenList config must be a JSON object", 2, {
82
+ path: configPath
83
+ });
84
+ }
85
+ const config = {};
86
+ if (typeof parsed.endpoint === "string") {
87
+ config.endpoint = parsed.endpoint;
88
+ }
89
+ if (typeof parsed.adminToken === "string") {
90
+ config.adminToken = parsed.adminToken;
91
+ }
92
+ return config;
93
+ }
94
+ async function writeUserConfig(env, config, deps = {}) {
95
+ const fs = deps.fs ?? nodeFs;
96
+ const configPath = resolveConfigPath(env);
97
+ const dir = node_path_1.default.dirname(configPath);
98
+ const tmpPath = node_path_1.default.join(dir, `.${CONFIG_FILE_NAME}.${process.pid}.${(0, node_crypto_1.randomUUID)()}.tmp`);
99
+ const data = `${JSON.stringify(config, null, 2)}\n`;
100
+ await fs.mkdir(dir, {
101
+ recursive: true,
102
+ mode: 0o700
103
+ });
104
+ await ignorePermissionError(() => fs.chmod(dir, 0o700));
105
+ await fs.writeFile(tmpPath, data, {
106
+ encoding: "utf8",
107
+ mode: 0o600
108
+ });
109
+ await ignorePermissionError(() => fs.chmod(tmpPath, 0o600));
110
+ await fs.rename(tmpPath, configPath);
111
+ await ignorePermissionError(() => fs.chmod(configPath, 0o600));
112
+ }
113
+ function resolveEffectiveConfig(env, flags, stored) {
114
+ const endpoint = firstValue([
115
+ ["flag", flags.endpoint],
116
+ ["env", env.OPENLIST_ENDPOINT],
117
+ ["config", stored.endpoint]
118
+ ]);
119
+ const adminToken = firstValue([
120
+ ["flag", flags.adminToken],
121
+ ["env", env.OPENLIST_ADMIN_TOKEN],
122
+ ["config", stored.adminToken]
123
+ ]);
124
+ return {
125
+ path: resolveConfigPath(env),
126
+ stored: {
127
+ endpoint: stored.endpoint ?? null,
128
+ adminToken: (0, redact_1.redactSecret)(stored.adminToken)
129
+ },
130
+ effective: {
131
+ endpoint: {
132
+ value: endpoint.value,
133
+ source: endpoint.source
134
+ },
135
+ adminToken: {
136
+ ...(0, redact_1.redactSecret)(adminToken.value ?? undefined),
137
+ source: adminToken.source
138
+ }
139
+ }
140
+ };
141
+ }
142
+ function firstValue(candidates) {
143
+ for (const [source, value] of candidates) {
144
+ if (value) {
145
+ return {
146
+ value,
147
+ source
148
+ };
149
+ }
150
+ }
151
+ return {
152
+ value: null,
153
+ source: "unset"
154
+ };
155
+ }
156
+ function isNodeError(error) {
157
+ return error instanceof Error && "code" in error;
158
+ }
159
+ function isRecord(value) {
160
+ return typeof value === "object" && value !== null && !Array.isArray(value);
161
+ }
162
+ async function ignorePermissionError(fn) {
163
+ try {
164
+ await fn();
165
+ }
166
+ catch (error) {
167
+ if (isNodeError(error) && (error.code === "EPERM" || error.code === "ENOSYS")) {
168
+ return;
169
+ }
170
+ throw error;
171
+ }
172
+ }
173
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/config/store.ts"],"names":[],"mappings":"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"}
package/dist/help.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export declare function topLevelHelp(): string;
2
+ export declare function configHelp(): string;
3
+ export declare function commandHelp(command: string | undefined, subcommand?: string): string | null;
package/dist/help.js ADDED
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.topLevelHelp = topLevelHelp;
4
+ exports.configHelp = configHelp;
5
+ exports.commandHelp = commandHelp;
6
+ function topLevelHelp() {
7
+ return [
8
+ "openlist - OpenList CLI",
9
+ "",
10
+ "Usage:",
11
+ " openlist [--endpoint <url>] [--admin-token <token>] <command> [args]",
12
+ "",
13
+ "Commands:",
14
+ " config set endpoint <url> Save the OpenList endpoint",
15
+ " config set admin-token <token> Save the OpenList admin token",
16
+ " config get Show stored and effective config",
17
+ " config unset admin-token Remove the stored admin token",
18
+ " config path Show the user config path",
19
+ " share create <path...> Create one OpenList share link",
20
+ "",
21
+ "Output:",
22
+ " Commands write stable JSON Agent Results to stdout.",
23
+ " Progress and diagnostics are written to stderr.",
24
+ "",
25
+ "Share defaults:",
26
+ " share create generates a share code unless --no-code is set.",
27
+ " share create expires in 3 days unless --expires or --no-expire is set.",
28
+ " Multiple paths create one share bundle.",
29
+ "",
30
+ "Environment:",
31
+ " OPENLIST_ENDPOINT OpenList endpoint",
32
+ " OPENLIST_ADMIN_TOKEN OpenList admin token",
33
+ "",
34
+ "Run openlist <command> --help for command-specific help."
35
+ ].join("\n");
36
+ }
37
+ function configHelp() {
38
+ return [
39
+ "openlist config - manage user config",
40
+ "",
41
+ "Usage:",
42
+ " openlist config set endpoint <url>",
43
+ " openlist config set admin-token <token>",
44
+ " openlist config get",
45
+ " openlist config unset admin-token",
46
+ " openlist config path",
47
+ "",
48
+ "Config:",
49
+ " Stored at ~/.config/openlist/config.json unless XDG_CONFIG_HOME is set.",
50
+ " The config directory is created with 0700 permissions.",
51
+ " The config file is written with 0600 permissions.",
52
+ "",
53
+ "Precedence:",
54
+ " CLI flags > environment variables > user config",
55
+ "",
56
+ "Output:",
57
+ " config commands write stable JSON Agent Results to stdout.",
58
+ " admin token values are redacted in command output."
59
+ ].join("\n");
60
+ }
61
+ function commandHelp(command, subcommand) {
62
+ if (command === "share" && subcommand === "create") {
63
+ return shareCreateHelp();
64
+ }
65
+ if (command === "share") {
66
+ return [
67
+ "openlist share - share operations",
68
+ "",
69
+ "Usage:",
70
+ " openlist share create <openlist-path> [more-openlist-paths...] [flags]",
71
+ "",
72
+ "Run openlist share create --help for flags."
73
+ ].join("\n");
74
+ }
75
+ return null;
76
+ }
77
+ function shareCreateHelp() {
78
+ return [
79
+ "openlist share create",
80
+ "",
81
+ "Usage:",
82
+ " openlist share create <openlist-path> [more-openlist-paths...] [flags]",
83
+ "",
84
+ "Creates one OpenList share. Multiple paths become one share bundle.",
85
+ "",
86
+ "Flags:",
87
+ " --code <code> Use an explicit share code",
88
+ " --no-code Create a share without a code",
89
+ " --expires <time> Expiration as ISO datetime or duration like 3d, 12h, 30m",
90
+ " --no-expire Create a share without expiration",
91
+ " --id <id> Use a custom share ID",
92
+ " --max-accessed <count> Limit access count, 0 means unlimited",
93
+ " --remark <text> Store a remark",
94
+ " --readme <markdown> Store share readme content",
95
+ " --header <markdown> Store share header content",
96
+ "",
97
+ "Defaults:",
98
+ " Generates an eight-character share code.",
99
+ " Expires in 3 days.",
100
+ "",
101
+ "Output:",
102
+ " Stable JSON Agent Result with accessUrl, url, code, id, expires, and paths."
103
+ ].join("\n");
104
+ }
105
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../src/help.ts"],"names":[],"mappings":";;AAAA,oCA8BC;AAED,gCAuBC;AAED,kCAiBC;AA1ED,SAAgB,YAAY;IAC1B,OAAO;QACL,yBAAyB;QACzB,EAAE;QACF,QAAQ;QACR,wEAAwE;QACxE,EAAE;QACF,WAAW;QACX,iEAAiE;QACjE,oEAAoE;QACpE,uEAAuE;QACvE,oEAAoE;QACpE,gEAAgE;QAChE,qEAAqE;QACrE,EAAE;QACF,SAAS;QACT,uDAAuD;QACvD,mDAAmD;QACnD,EAAE;QACF,iBAAiB;QACjB,gEAAgE;QAChE,0EAA0E;QAC1E,2CAA2C;QAC3C,EAAE;QACF,cAAc;QACd,6CAA6C;QAC7C,+CAA+C;QAC/C,EAAE;QACF,0DAA0D;KAC3D,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO;QACL,sCAAsC;QACtC,EAAE;QACF,QAAQ;QACR,sCAAsC;QACtC,2CAA2C;QAC3C,uBAAuB;QACvB,qCAAqC;QACrC,wBAAwB;QACxB,EAAE;QACF,SAAS;QACT,2EAA2E;QAC3E,0DAA0D;QAC1D,qDAAqD;QACrD,EAAE;QACF,aAAa;QACb,mDAAmD;QACnD,EAAE;QACF,SAAS;QACT,8DAA8D;QAC9D,sDAAsD;KACvD,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAgB,WAAW,CAAC,OAA2B,EAAE,UAAmB;IAC1E,IAAI,OAAO,KAAK,OAAO,IAAI,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnD,OAAO,eAAe,EAAE,CAAC;IAC3B,CAAC;IAED,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;QACxB,OAAO;YACL,mCAAmC;YACnC,EAAE;YACF,QAAQ;YACR,0EAA0E;YAC1E,EAAE;YACF,6CAA6C;SAC9C,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,eAAe;IACtB,OAAO;QACL,uBAAuB;QACvB,EAAE;QACF,QAAQ;QACR,0EAA0E;QAC1E,EAAE;QACF,qEAAqE;QACrE,EAAE;QACF,QAAQ;QACR,wDAAwD;QACxD,2DAA2D;QAC3D,sFAAsF;QACtF,+DAA+D;QAC/D,mDAAmD;QACnD,mEAAmE;QACnE,4CAA4C;QAC5C,wDAAwD;QACxD,wDAAwD;QACxD,EAAE;QACF,WAAW;QACX,4CAA4C;QAC5C,sBAAsB;QACtB,EAAE;QACF,SAAS;QACT,+EAA+E;KAChF,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC"}
@@ -0,0 +1,24 @@
1
+ export type ExitCode = 0 | 1 | 2 | 3 | 4;
2
+ export type AgentSuccess<TData> = {
3
+ ok: true;
4
+ command: string;
5
+ data: TData;
6
+ };
7
+ export type AgentFailure = {
8
+ ok: false;
9
+ command: string;
10
+ error: {
11
+ code: string;
12
+ message: string;
13
+ details: Record<string, unknown>;
14
+ };
15
+ };
16
+ export type AgentResult<TData = unknown> = AgentSuccess<TData> | AgentFailure;
17
+ export declare class OpenListError extends Error {
18
+ readonly code: string;
19
+ readonly exitCode: ExitCode;
20
+ readonly details: Record<string, unknown>;
21
+ constructor(code: string, message: string, exitCode: ExitCode, details?: Record<string, unknown>);
22
+ }
23
+ export declare function success<TData>(command: string, data: TData): AgentSuccess<TData>;
24
+ export declare function failure(command: string, error: OpenListError | Error): AgentFailure;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OpenListError = void 0;
4
+ exports.success = success;
5
+ exports.failure = failure;
6
+ class OpenListError extends Error {
7
+ code;
8
+ exitCode;
9
+ details;
10
+ constructor(code, message, exitCode, details = {}) {
11
+ super(message);
12
+ this.name = "OpenListError";
13
+ this.code = code;
14
+ this.exitCode = exitCode;
15
+ this.details = details;
16
+ }
17
+ }
18
+ exports.OpenListError = OpenListError;
19
+ function success(command, data) {
20
+ return {
21
+ ok: true,
22
+ command,
23
+ data
24
+ };
25
+ }
26
+ function failure(command, error) {
27
+ if (error instanceof OpenListError) {
28
+ return {
29
+ ok: false,
30
+ command,
31
+ error: {
32
+ code: error.code,
33
+ message: error.message,
34
+ details: error.details
35
+ }
36
+ };
37
+ }
38
+ return {
39
+ ok: false,
40
+ command,
41
+ error: {
42
+ code: "INTERNAL_ERROR",
43
+ message: error.message || "Unexpected internal error",
44
+ details: {}
45
+ }
46
+ };
47
+ }
48
+ //# sourceMappingURL=result.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/model/result.ts"],"names":[],"mappings":";;;AAuCA,0BASC;AAED,0BAyBC;AAvDD,MAAa,aAAc,SAAQ,KAAK;IAC7B,IAAI,CAAS;IACb,QAAQ,CAAW;IACnB,OAAO,CAA0B;IAE1C,YACE,IAAY,EACZ,OAAe,EACf,QAAkB,EAClB,UAAmC,EAAE;QAErC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;CACF;AAjBD,sCAiBC;AAED,SAAgB,OAAO,CACrB,OAAe,EACf,IAAW;IAEX,OAAO;QACL,EAAE,EAAE,IAAI;QACR,OAAO;QACP,IAAI;KACL,CAAC;AACJ,CAAC;AAED,SAAgB,OAAO,CACrB,OAAe,EACf,KAA4B;IAE5B,IAAI,KAAK,YAAY,aAAa,EAAE,CAAC;QACnC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,OAAO;YACP,KAAK,EAAE;gBACL,IAAI,EAAE,KAAK,CAAC,IAAI;gBAChB,OAAO,EAAE,KAAK,CAAC,OAAO;gBACtB,OAAO,EAAE,KAAK,CAAC,OAAO;aACvB;SACF,CAAC;IACJ,CAAC;IAED,OAAO;QACL,EAAE,EAAE,KAAK;QACT,OAAO;QACP,KAAK,EAAE;YACL,IAAI,EAAE,gBAAgB;YACtB,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,2BAA2B;YACrD,OAAO,EAAE,EAAE;SACZ;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,47 @@
1
+ export type OpenListConnection = {
2
+ endpoint: string;
3
+ adminToken: string;
4
+ };
5
+ export type OpenListFsEntry = {
6
+ name?: string;
7
+ size?: number;
8
+ is_dir?: boolean;
9
+ modified?: string;
10
+ created?: string;
11
+ type?: number;
12
+ raw_url?: string;
13
+ provider?: string;
14
+ };
15
+ export type OpenListCreateShareRequest = {
16
+ files: string[];
17
+ expires?: string | null;
18
+ pwd?: string;
19
+ max_accessed?: number;
20
+ id?: string;
21
+ remark?: string;
22
+ readme?: string;
23
+ header?: string;
24
+ };
25
+ export type OpenListShare = {
26
+ id: string;
27
+ files: string[];
28
+ expires?: string | null;
29
+ pwd?: string;
30
+ accessed?: number;
31
+ max_accessed?: number;
32
+ disabled?: boolean;
33
+ remark?: string;
34
+ readme?: string;
35
+ header?: string;
36
+ creator?: string;
37
+ creator_role?: number;
38
+ };
39
+ export type OpenListClient = {
40
+ getPath(path: string): Promise<OpenListFsEntry>;
41
+ createShare(request: OpenListCreateShareRequest): Promise<OpenListShare>;
42
+ };
43
+ export type OpenListClientDeps = {
44
+ fetch?: typeof fetch;
45
+ };
46
+ export declare function createOpenListClient(connection: OpenListConnection, deps?: OpenListClientDeps): OpenListClient;
47
+ export declare function normalizeEndpoint(endpoint: string): string;
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createOpenListClient = createOpenListClient;
4
+ exports.normalizeEndpoint = normalizeEndpoint;
5
+ const result_1 = require("../model/result");
6
+ function createOpenListClient(connection, deps = {}) {
7
+ const endpoint = normalizeEndpoint(connection.endpoint);
8
+ const fetchImpl = deps.fetch ?? fetch;
9
+ return {
10
+ async getPath(path) {
11
+ return postJson(fetchImpl, connection.adminToken, endpoint, "/api/fs/get", {
12
+ path
13
+ });
14
+ },
15
+ async createShare(request) {
16
+ return postJson(fetchImpl, connection.adminToken, endpoint, "/api/share/create", request);
17
+ }
18
+ };
19
+ }
20
+ function normalizeEndpoint(endpoint) {
21
+ const trimmed = endpoint.trim().replace(/\/+$/, "");
22
+ let parsed;
23
+ try {
24
+ parsed = new URL(trimmed);
25
+ }
26
+ catch {
27
+ throw new result_1.OpenListError("CONFIG_ENDPOINT_INVALID", "OpenList endpoint must be an absolute http(s) URL", 2, {
28
+ endpoint: trimmed
29
+ });
30
+ }
31
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
32
+ throw new result_1.OpenListError("CONFIG_ENDPOINT_INVALID", "OpenList endpoint must use http or https", 2, {
33
+ endpoint: trimmed,
34
+ protocol: parsed.protocol
35
+ });
36
+ }
37
+ return trimmed;
38
+ }
39
+ async function postJson(fetchImpl, adminToken, endpoint, apiPath, body) {
40
+ let response;
41
+ try {
42
+ response = await fetchImpl(`${endpoint}${apiPath}`, {
43
+ method: "POST",
44
+ headers: {
45
+ "content-type": "application/json",
46
+ authorization: adminToken
47
+ },
48
+ body: JSON.stringify(body)
49
+ });
50
+ }
51
+ catch (error) {
52
+ throw new result_1.OpenListError("OPENLIST_NETWORK_ERROR", error instanceof Error ? error.message : "OpenList request failed", 3, {
53
+ apiPath
54
+ });
55
+ }
56
+ const text = await response.text();
57
+ let envelope;
58
+ try {
59
+ envelope = JSON.parse(text);
60
+ }
61
+ catch {
62
+ throw new result_1.OpenListError("OPENLIST_BAD_RESPONSE", "OpenList returned a non-JSON response", 3, {
63
+ apiPath,
64
+ status: response.status
65
+ });
66
+ }
67
+ if (!response.ok || envelope.code !== 200) {
68
+ throw new result_1.OpenListError("OPENLIST_API_ERROR", envelope.message || `OpenList API request failed: ${apiPath}`, 3, {
69
+ apiPath,
70
+ status: response.status,
71
+ apiCode: envelope.code,
72
+ apiMessage: envelope.message
73
+ });
74
+ }
75
+ return envelope.data;
76
+ }
77
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/openlist/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type ExitCode } from "./model/result";
2
+ import { type Env } from "./config/store";
3
+ import type { CommandDeps } from "./commands/shared";
4
+ export type Writable = {
5
+ write(chunk: string): unknown;
6
+ };
7
+ export type RunOpenListIo = {
8
+ stdout: Writable;
9
+ stderr: Writable;
10
+ };
11
+ export type RunOpenListDeps = CommandDeps;
12
+ export type RunOpenListOptions = {
13
+ env?: Env;
14
+ io?: RunOpenListIo;
15
+ deps?: RunOpenListDeps;
16
+ };
17
+ export declare function runOpenList(argv: string[], options?: RunOpenListOptions): Promise<ExitCode>;
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.runOpenList = runOpenList;
4
+ const help_1 = require("./help");
5
+ const result_1 = require("./model/result");
6
+ const config_1 = require("./commands/config");
7
+ const share_create_1 = require("./commands/share-create");
8
+ async function runOpenList(argv, options = {}) {
9
+ const normalizedArgv = normalizeArgv(argv);
10
+ const env = options.env ?? process.env;
11
+ const io = options.io ?? {
12
+ stdout: process.stdout,
13
+ stderr: process.stderr
14
+ };
15
+ const deps = options.deps ?? {};
16
+ let command = commandNameFromArgv(normalizedArgv);
17
+ try {
18
+ const parsed = parseGlobalFlags(normalizedArgv);
19
+ command = commandNameFromArgv(parsed.args);
20
+ if (shouldShowTopLevelHelp(parsed.args)) {
21
+ writeLine(io.stdout, (0, help_1.topLevelHelp)());
22
+ return 0;
23
+ }
24
+ if (parsed.args[0] === "config") {
25
+ if (parsed.args.includes("--help") || parsed.args.includes("-h")) {
26
+ writeLine(io.stdout, (0, help_1.configHelp)());
27
+ return 0;
28
+ }
29
+ const result = await (0, config_1.runConfigCommand)(parsed.args.slice(1), env, parsed.flags, deps);
30
+ writeJson(io.stdout, result);
31
+ return 0;
32
+ }
33
+ if (parsed.args[0] === "share") {
34
+ if (parsed.args[1] === "create") {
35
+ if (parsed.args.includes("--help") || parsed.args.includes("-h")) {
36
+ writeLine(io.stdout, (0, help_1.commandHelp)("share", "create") ?? "");
37
+ return 0;
38
+ }
39
+ const result = await (0, share_create_1.runShareCreateCommand)(parsed.args.slice(2), env, parsed.flags, deps);
40
+ writeJson(io.stdout, result);
41
+ return 0;
42
+ }
43
+ if (parsed.args.includes("--help") || parsed.args.includes("-h")) {
44
+ writeLine(io.stdout, (0, help_1.commandHelp)("share") ?? "");
45
+ return 0;
46
+ }
47
+ throw new result_1.OpenListError("USAGE_UNKNOWN_SHARE_COMMAND", `Unknown share command: ${parsed.args[1] ?? ""}`, 2, {
48
+ command: parsed.args[1] ?? null
49
+ });
50
+ }
51
+ throw new result_1.OpenListError("USAGE_UNKNOWN_COMMAND", `Unknown command: ${parsed.args[0]}`, 2, {
52
+ command: parsed.args[0]
53
+ });
54
+ }
55
+ catch (error) {
56
+ const normalized = normalizeError(error);
57
+ writeJson(io.stdout, (0, result_1.failure)(command, normalized));
58
+ writeLine(io.stderr, normalized.message);
59
+ return normalized.exitCode;
60
+ }
61
+ }
62
+ function normalizeArgv(argv) {
63
+ return argv[0] === "--" ? argv.slice(1) : argv;
64
+ }
65
+ function parseGlobalFlags(argv) {
66
+ const args = [];
67
+ const flags = {};
68
+ let positionalOnly = false;
69
+ for (let index = 0; index < argv.length; index += 1) {
70
+ const arg = argv[index];
71
+ if (positionalOnly) {
72
+ args.push(arg);
73
+ continue;
74
+ }
75
+ if (arg === "--") {
76
+ positionalOnly = true;
77
+ continue;
78
+ }
79
+ if (arg === "--endpoint") {
80
+ flags.endpoint = requiredFlagValue(argv, index, "--endpoint");
81
+ index += 1;
82
+ continue;
83
+ }
84
+ if (arg.startsWith("--endpoint=")) {
85
+ flags.endpoint = valueFromEqualsFlag(arg, "--endpoint");
86
+ continue;
87
+ }
88
+ if (arg === "--admin-token") {
89
+ flags.adminToken = requiredFlagValue(argv, index, "--admin-token");
90
+ index += 1;
91
+ continue;
92
+ }
93
+ if (arg.startsWith("--admin-token=")) {
94
+ flags.adminToken = valueFromEqualsFlag(arg, "--admin-token");
95
+ continue;
96
+ }
97
+ args.push(arg);
98
+ }
99
+ return {
100
+ args,
101
+ flags
102
+ };
103
+ }
104
+ function shouldShowTopLevelHelp(args) {
105
+ return (args.length === 0 ||
106
+ args[0] === "help" ||
107
+ args[0] === "--help" ||
108
+ args[0] === "-h");
109
+ }
110
+ function commandNameFromArgv(argv) {
111
+ const args = normalizeArgv(argv);
112
+ if (args[0] === "share" && args[1]) {
113
+ return `share ${args[1]}`;
114
+ }
115
+ if (args[0] === "config" && args[1]) {
116
+ return `config ${args[1]}`;
117
+ }
118
+ return args[0] ?? "help";
119
+ }
120
+ function normalizeError(error) {
121
+ if (error instanceof result_1.OpenListError) {
122
+ return error;
123
+ }
124
+ if (error instanceof Error) {
125
+ return new result_1.OpenListError("INTERNAL_ERROR", error.message, 1);
126
+ }
127
+ return new result_1.OpenListError("INTERNAL_ERROR", "Unexpected internal error", 1);
128
+ }
129
+ function writeJson(stdout, value) {
130
+ stdout.write(`${JSON.stringify(value, null, 2)}\n`);
131
+ }
132
+ function writeLine(stdout, value) {
133
+ stdout.write(`${value}\n`);
134
+ }
135
+ function requiredFlagValue(args, index, flag) {
136
+ const value = args[index + 1];
137
+ if (!value || value.startsWith("--")) {
138
+ throw new result_1.OpenListError("USAGE_FLAG_VALUE_REQUIRED", `${flag} requires a value`, 2, {
139
+ flag
140
+ });
141
+ }
142
+ return value;
143
+ }
144
+ function valueFromEqualsFlag(arg, flag) {
145
+ const value = arg.slice(`${flag}=`.length);
146
+ if (!value) {
147
+ throw new result_1.OpenListError("USAGE_FLAG_VALUE_REQUIRED", `${flag} requires a value`, 2, {
148
+ flag
149
+ });
150
+ }
151
+ return value;
152
+ }
153
+ //# sourceMappingURL=run-openlist.js.map