@spotsccc/cli 0.6.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.
- package/dist/chunk-UK5FHYML.js +259 -0
- package/dist/index.js +148 -0
- package/dist/operations-WR7WHN3O.js +14088 -0
- package/package.json +24 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __export = (target, all) => {
|
|
4
|
+
for (var name in all)
|
|
5
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// ../../node_modules/.pnpm/errore@0.14.1/node_modules/errore/dist/serialize-cause.js
|
|
9
|
+
var serializeCause = (cause) => {
|
|
10
|
+
if (cause instanceof Error) {
|
|
11
|
+
return { name: cause.name, message: cause.message, stack: cause.stack };
|
|
12
|
+
}
|
|
13
|
+
return cause;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// ../../node_modules/.pnpm/errore@0.14.1/node_modules/errore/dist/error.js
|
|
17
|
+
function findCause(error, ErrorClass) {
|
|
18
|
+
const seen = /* @__PURE__ */ new Set();
|
|
19
|
+
let current = error;
|
|
20
|
+
while (current instanceof Error) {
|
|
21
|
+
if (seen.has(current))
|
|
22
|
+
break;
|
|
23
|
+
seen.add(current);
|
|
24
|
+
if (current instanceof ErrorClass)
|
|
25
|
+
return current;
|
|
26
|
+
current = current.cause;
|
|
27
|
+
}
|
|
28
|
+
return void 0;
|
|
29
|
+
}
|
|
30
|
+
var isAnyTaggedError = (value) => {
|
|
31
|
+
return value instanceof Error && "_tag" in value && typeof value._tag === "string";
|
|
32
|
+
};
|
|
33
|
+
var TaggedError = Object.assign((tag, BaseClass) => () => {
|
|
34
|
+
const ActualBase = BaseClass ?? Error;
|
|
35
|
+
const RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
36
|
+
"_tag",
|
|
37
|
+
"fingerprint",
|
|
38
|
+
"name",
|
|
39
|
+
"stack",
|
|
40
|
+
"message",
|
|
41
|
+
"cause"
|
|
42
|
+
]);
|
|
43
|
+
class Tagged extends ActualBase {
|
|
44
|
+
_tag = tag;
|
|
45
|
+
get fingerprint() {
|
|
46
|
+
return [this._tag];
|
|
47
|
+
}
|
|
48
|
+
/** Type guard for this error class */
|
|
49
|
+
static is(value) {
|
|
50
|
+
return value instanceof Tagged;
|
|
51
|
+
}
|
|
52
|
+
constructor(args) {
|
|
53
|
+
const message = args && "message" in args && typeof args.message === "string" ? args.message : void 0;
|
|
54
|
+
const cause = args && "cause" in args ? args.cause : void 0;
|
|
55
|
+
super(message, cause !== void 0 ? { cause } : void 0);
|
|
56
|
+
if (args) {
|
|
57
|
+
for (const key of Object.keys(args)) {
|
|
58
|
+
if (!RESERVED_KEYS.has(key)) {
|
|
59
|
+
;
|
|
60
|
+
this[key] = args[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
65
|
+
this.name = tag;
|
|
66
|
+
if (cause instanceof Error && cause.stack) {
|
|
67
|
+
const indented = cause.stack.replace(/\n/g, "\n ");
|
|
68
|
+
this.stack = `${this.stack}
|
|
69
|
+
Caused by: ${indented}`;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
findCause(ErrorClass) {
|
|
73
|
+
return findCause(this, ErrorClass);
|
|
74
|
+
}
|
|
75
|
+
toJSON() {
|
|
76
|
+
return {
|
|
77
|
+
...this,
|
|
78
|
+
_tag: this._tag,
|
|
79
|
+
name: this.name,
|
|
80
|
+
message: this.message,
|
|
81
|
+
fingerprint: this.fingerprint,
|
|
82
|
+
cause: serializeCause(this.cause),
|
|
83
|
+
stack: this.stack
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return Tagged;
|
|
88
|
+
}, { is: isAnyTaggedError });
|
|
89
|
+
var UnhandledError = class extends TaggedError("UnhandledError")() {
|
|
90
|
+
constructor(args) {
|
|
91
|
+
const message = args.cause instanceof Error ? `Unhandled exception: ${args.cause.message}` : `Unhandled exception: ${String(args.cause)}`;
|
|
92
|
+
super({ message, cause: args.cause });
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
// ../../node_modules/.pnpm/errore@0.14.1/node_modules/errore/dist/core.js
|
|
97
|
+
function tryFn(fnOrOpts) {
|
|
98
|
+
if (typeof fnOrOpts === "function") {
|
|
99
|
+
try {
|
|
100
|
+
return fnOrOpts();
|
|
101
|
+
} catch (cause) {
|
|
102
|
+
if (!(cause instanceof Error)) {
|
|
103
|
+
throw cause;
|
|
104
|
+
}
|
|
105
|
+
return new UnhandledError({ cause });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
try {
|
|
109
|
+
return fnOrOpts.try();
|
|
110
|
+
} catch (cause) {
|
|
111
|
+
if (!(cause instanceof Error)) {
|
|
112
|
+
throw cause;
|
|
113
|
+
}
|
|
114
|
+
return fnOrOpts.catch(cause);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// ../../node_modules/.pnpm/errore@0.14.1/node_modules/errore/dist/factory.js
|
|
119
|
+
var compileMessageInterpolator = (template) => {
|
|
120
|
+
const variableNames = [];
|
|
121
|
+
const seenVariables = /* @__PURE__ */ new Set();
|
|
122
|
+
const staticParts = [];
|
|
123
|
+
const placeholders = [];
|
|
124
|
+
const regex = /\$([a-zA-Z_][a-zA-Z0-9_]*)/g;
|
|
125
|
+
let lastIndex = 0;
|
|
126
|
+
let match2;
|
|
127
|
+
while ((match2 = regex.exec(template)) !== null) {
|
|
128
|
+
staticParts.push(template.slice(lastIndex, match2.index));
|
|
129
|
+
const varName = match2[1];
|
|
130
|
+
placeholders.push(varName);
|
|
131
|
+
if (!seenVariables.has(varName)) {
|
|
132
|
+
seenVariables.add(varName);
|
|
133
|
+
variableNames.push(varName);
|
|
134
|
+
}
|
|
135
|
+
lastIndex = regex.lastIndex;
|
|
136
|
+
}
|
|
137
|
+
staticParts.push(template.slice(lastIndex));
|
|
138
|
+
if (placeholders.length === 0) {
|
|
139
|
+
return {
|
|
140
|
+
variableNames,
|
|
141
|
+
interpolate: () => template
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
if (placeholders.length === 1) {
|
|
145
|
+
const head = staticParts[0] ?? "";
|
|
146
|
+
const tail = staticParts[1] ?? "";
|
|
147
|
+
const varName = placeholders[0];
|
|
148
|
+
const varLiteral = `$${varName}`;
|
|
149
|
+
return {
|
|
150
|
+
variableNames,
|
|
151
|
+
interpolate: (values) => {
|
|
152
|
+
if (!values)
|
|
153
|
+
return template;
|
|
154
|
+
const value = values[varName];
|
|
155
|
+
return `${head}${value !== void 0 ? String(value) : varLiteral}${tail}`;
|
|
156
|
+
}
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
const placeholderLiterals = placeholders.map((varName) => `$${varName}`);
|
|
160
|
+
const interpolate = (values) => {
|
|
161
|
+
if (!values) {
|
|
162
|
+
return template;
|
|
163
|
+
}
|
|
164
|
+
let result = staticParts[0] ?? "";
|
|
165
|
+
for (let i = 0; i < placeholders.length; i++) {
|
|
166
|
+
const varName = placeholders[i];
|
|
167
|
+
const value = values[varName];
|
|
168
|
+
result += value !== void 0 ? String(value) : placeholderLiterals[i];
|
|
169
|
+
result += staticParts[i + 1] ?? "";
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
};
|
|
173
|
+
return { variableNames, interpolate };
|
|
174
|
+
};
|
|
175
|
+
function createTaggedError(opts) {
|
|
176
|
+
const { name: tag } = opts;
|
|
177
|
+
const messageTemplate = opts.message ?? "$message";
|
|
178
|
+
const BaseError = opts.extends ?? Error;
|
|
179
|
+
const { variableNames: varNames, interpolate } = compileMessageInterpolator(messageTemplate);
|
|
180
|
+
const FORBIDDEN_VARS = ["_tag", "name", "stack", "cause"];
|
|
181
|
+
for (const forbidden of FORBIDDEN_VARS) {
|
|
182
|
+
if (varNames.includes(forbidden)) {
|
|
183
|
+
throw new Error(`createTaggedError(${tag}): template variable $${forbidden} is reserved and not allowed. Use a different variable name.`);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
const TypedBase = BaseError;
|
|
187
|
+
const RESERVED_KEYS = /* @__PURE__ */ new Set([
|
|
188
|
+
"_tag",
|
|
189
|
+
"messageTemplate",
|
|
190
|
+
"fingerprint",
|
|
191
|
+
"name",
|
|
192
|
+
"stack",
|
|
193
|
+
"message",
|
|
194
|
+
"cause"
|
|
195
|
+
]);
|
|
196
|
+
const serializableVarNames = varNames.filter((varName) => !RESERVED_KEYS.has(varName));
|
|
197
|
+
class Tagged extends TypedBase {
|
|
198
|
+
_tag = tag;
|
|
199
|
+
messageTemplate = messageTemplate;
|
|
200
|
+
get fingerprint() {
|
|
201
|
+
return [this._tag, this.messageTemplate];
|
|
202
|
+
}
|
|
203
|
+
static tag = tag;
|
|
204
|
+
static is(value) {
|
|
205
|
+
return value instanceof Tagged;
|
|
206
|
+
}
|
|
207
|
+
constructor(args) {
|
|
208
|
+
const interpolatedMessage = interpolate(args);
|
|
209
|
+
const cause = args && "cause" in args ? args.cause : void 0;
|
|
210
|
+
super(interpolatedMessage, cause !== void 0 ? { cause } : void 0);
|
|
211
|
+
if (args) {
|
|
212
|
+
for (const varName of serializableVarNames) {
|
|
213
|
+
if (varName in args) {
|
|
214
|
+
;
|
|
215
|
+
this[varName] = args[varName];
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
220
|
+
this.name = tag;
|
|
221
|
+
if (cause instanceof Error && cause.stack) {
|
|
222
|
+
const indented = cause.stack.replace(/\n/g, "\n ");
|
|
223
|
+
this.stack = `${this.stack}
|
|
224
|
+
Caused by: ${indented}`;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
findCause(ErrorClass) {
|
|
228
|
+
return findCause(this, ErrorClass);
|
|
229
|
+
}
|
|
230
|
+
toJSON() {
|
|
231
|
+
const json = {
|
|
232
|
+
_tag: this._tag,
|
|
233
|
+
name: this.name,
|
|
234
|
+
message: this.message,
|
|
235
|
+
messageTemplate: this.messageTemplate,
|
|
236
|
+
fingerprint: this.fingerprint,
|
|
237
|
+
cause: serializeCause(this.cause),
|
|
238
|
+
stack: this.stack
|
|
239
|
+
};
|
|
240
|
+
for (const varName of serializableVarNames) {
|
|
241
|
+
if (varName in this) {
|
|
242
|
+
json[varName] = this[varName];
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return json;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return Tagged;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// ../../node_modules/.pnpm/errore@0.14.1/node_modules/errore/dist/disposable.js
|
|
252
|
+
Symbol.dispose ??= /* @__PURE__ */ Symbol("Symbol.dispose");
|
|
253
|
+
Symbol.asyncDispose ??= /* @__PURE__ */ Symbol("Symbol.asyncDispose");
|
|
254
|
+
|
|
255
|
+
export {
|
|
256
|
+
__export,
|
|
257
|
+
tryFn,
|
|
258
|
+
createTaggedError
|
|
259
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
tryFn
|
|
4
|
+
} from "./chunk-UK5FHYML.js";
|
|
5
|
+
|
|
6
|
+
// src/index.ts
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
import os from "os";
|
|
10
|
+
var CONFIG_DIR = path.join(os.homedir(), ".assistant");
|
|
11
|
+
var CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
12
|
+
function readConfig() {
|
|
13
|
+
const raw = tryFn({
|
|
14
|
+
try: () => fs.readFileSync(CONFIG_FILE, "utf-8"),
|
|
15
|
+
catch: () => new Error("Config not found")
|
|
16
|
+
});
|
|
17
|
+
if (raw instanceof Error) return {};
|
|
18
|
+
const parsed = tryFn({
|
|
19
|
+
try: () => JSON.parse(raw),
|
|
20
|
+
catch: () => new Error("Invalid config")
|
|
21
|
+
});
|
|
22
|
+
if (parsed instanceof Error) return {};
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|
|
25
|
+
function writeConfig(config) {
|
|
26
|
+
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
27
|
+
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
28
|
+
}
|
|
29
|
+
var command = process.argv[2];
|
|
30
|
+
var jsonArg = process.argv[3];
|
|
31
|
+
if (!command) {
|
|
32
|
+
console.error("Usage: assistant <command> [json-args]");
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
if (command === "auth") {
|
|
36
|
+
if (!jsonArg) {
|
|
37
|
+
console.error("Usage: assistant auth <database-url>");
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
writeConfig({ databaseUrl: jsonArg });
|
|
41
|
+
console.log("Database URL saved.");
|
|
42
|
+
process.exit(0);
|
|
43
|
+
}
|
|
44
|
+
if (!process.env.DATABASE_URL) {
|
|
45
|
+
const config = readConfig();
|
|
46
|
+
if (config.databaseUrl) {
|
|
47
|
+
process.env.DATABASE_URL = config.databaseUrl;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
var {
|
|
51
|
+
createTransaction,
|
|
52
|
+
listTransactions,
|
|
53
|
+
deleteTransaction,
|
|
54
|
+
incomeSchema,
|
|
55
|
+
expenseSchema,
|
|
56
|
+
transferSchema,
|
|
57
|
+
listTransactionsSchema,
|
|
58
|
+
deleteTransactionSchema,
|
|
59
|
+
getWallets,
|
|
60
|
+
getWalletBalance,
|
|
61
|
+
createWallet,
|
|
62
|
+
createWalletSchema,
|
|
63
|
+
getWalletBalanceSchema,
|
|
64
|
+
getCategories,
|
|
65
|
+
createCategory,
|
|
66
|
+
deleteCategory,
|
|
67
|
+
createCategorySchema,
|
|
68
|
+
deleteCategorySchema,
|
|
69
|
+
spendingReport,
|
|
70
|
+
spendingReportSchema
|
|
71
|
+
} = await import("./operations-WR7WHN3O.js");
|
|
72
|
+
var commands = {
|
|
73
|
+
"create-income": async (input) => {
|
|
74
|
+
const parsed = incomeSchema.omit({ type: true }).parse(input);
|
|
75
|
+
const result = await createTransaction({ ...parsed, type: "income" });
|
|
76
|
+
if (result instanceof Error) throw result;
|
|
77
|
+
return result;
|
|
78
|
+
},
|
|
79
|
+
"create-expense": async (input) => {
|
|
80
|
+
const parsed = expenseSchema.omit({ type: true }).parse(input);
|
|
81
|
+
const result = await createTransaction({ ...parsed, type: "expense" });
|
|
82
|
+
if (result instanceof Error) throw result;
|
|
83
|
+
return result;
|
|
84
|
+
},
|
|
85
|
+
"create-transfer": async (input) => {
|
|
86
|
+
const parsed = transferSchema.omit({ type: true }).parse(input);
|
|
87
|
+
const result = await createTransaction({ ...parsed, type: "transfer" });
|
|
88
|
+
if (result instanceof Error) throw result;
|
|
89
|
+
return result;
|
|
90
|
+
},
|
|
91
|
+
"list-transactions": async (input) => {
|
|
92
|
+
const parsed = listTransactionsSchema.parse(input);
|
|
93
|
+
return listTransactions(parsed);
|
|
94
|
+
},
|
|
95
|
+
"delete-transaction": async (input) => {
|
|
96
|
+
const parsed = deleteTransactionSchema.parse(input);
|
|
97
|
+
const result = await deleteTransaction(parsed.id);
|
|
98
|
+
if (result instanceof Error) throw result;
|
|
99
|
+
return result;
|
|
100
|
+
},
|
|
101
|
+
"get-wallets": async () => {
|
|
102
|
+
return getWallets();
|
|
103
|
+
},
|
|
104
|
+
"get-wallet-balance": async (input) => {
|
|
105
|
+
const parsed = getWalletBalanceSchema.parse(input);
|
|
106
|
+
const result = await getWalletBalance(parsed.walletId);
|
|
107
|
+
if (result instanceof Error) throw result;
|
|
108
|
+
return result;
|
|
109
|
+
},
|
|
110
|
+
"create-wallet": async (input) => {
|
|
111
|
+
const parsed = createWalletSchema.parse(input);
|
|
112
|
+
return createWallet(parsed);
|
|
113
|
+
},
|
|
114
|
+
"get-categories": async () => {
|
|
115
|
+
return getCategories();
|
|
116
|
+
},
|
|
117
|
+
"create-category": async (input) => {
|
|
118
|
+
const parsed = createCategorySchema.parse(input);
|
|
119
|
+
return createCategory(parsed);
|
|
120
|
+
},
|
|
121
|
+
"delete-category": async (input) => {
|
|
122
|
+
const parsed = deleteCategorySchema.parse(input);
|
|
123
|
+
const result = await deleteCategory(parsed.id);
|
|
124
|
+
if (result instanceof Error) throw result;
|
|
125
|
+
return result;
|
|
126
|
+
},
|
|
127
|
+
"spending-report": async (input) => {
|
|
128
|
+
const parsed = spendingReportSchema.parse(input);
|
|
129
|
+
return spendingReport(parsed);
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
var handler = commands[command];
|
|
133
|
+
if (!handler) {
|
|
134
|
+
console.error(
|
|
135
|
+
`Unknown command: ${command}
|
|
136
|
+
Available: auth, ${Object.keys(commands).join(", ")}`
|
|
137
|
+
);
|
|
138
|
+
process.exit(1);
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const input = jsonArg ? JSON.parse(jsonArg) : {};
|
|
142
|
+
const result = await handler(input);
|
|
143
|
+
console.log(JSON.stringify(result, null, 2));
|
|
144
|
+
process.exit(0);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
147
|
+
process.exit(1);
|
|
148
|
+
}
|