@lumenkey/cli 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.
Files changed (52) hide show
  1. package/README.md +134 -0
  2. package/bin/lumenkey-mcp.js +7 -0
  3. package/bin/lumenkey.js +7 -0
  4. package/dist/cli/copied.d.ts +27 -0
  5. package/dist/cli/copied.d.ts.map +1 -0
  6. package/dist/cli/copied.js +489 -0
  7. package/dist/cli/copied.js.map +1 -0
  8. package/dist/cli/index.d.ts +2 -0
  9. package/dist/cli/index.d.ts.map +1 -0
  10. package/dist/cli/index.js +227 -0
  11. package/dist/cli/index.js.map +1 -0
  12. package/dist/core/client.d.ts +60 -0
  13. package/dist/core/client.d.ts.map +1 -0
  14. package/dist/core/client.js +227 -0
  15. package/dist/core/client.js.map +1 -0
  16. package/dist/core/config.d.ts +12 -0
  17. package/dist/core/config.d.ts.map +1 -0
  18. package/dist/core/config.js +97 -0
  19. package/dist/core/config.js.map +1 -0
  20. package/dist/core/explain.d.ts +23 -0
  21. package/dist/core/explain.d.ts.map +1 -0
  22. package/dist/core/explain.js +54 -0
  23. package/dist/core/explain.js.map +1 -0
  24. package/dist/core/poller.d.ts +19 -0
  25. package/dist/core/poller.d.ts.map +1 -0
  26. package/dist/core/poller.js +108 -0
  27. package/dist/core/poller.js.map +1 -0
  28. package/dist/core/profiles.d.ts +25 -0
  29. package/dist/core/profiles.d.ts.map +1 -0
  30. package/dist/core/profiles.js +96 -0
  31. package/dist/core/profiles.js.map +1 -0
  32. package/dist/core/set-values.d.ts +22 -0
  33. package/dist/core/set-values.d.ts.map +1 -0
  34. package/dist/core/set-values.js +141 -0
  35. package/dist/core/set-values.js.map +1 -0
  36. package/dist/core/types.d.ts +80 -0
  37. package/dist/core/types.d.ts.map +1 -0
  38. package/dist/core/types.js +6 -0
  39. package/dist/core/types.js.map +1 -0
  40. package/dist/core/wait.d.ts +7 -0
  41. package/dist/core/wait.d.ts.map +1 -0
  42. package/dist/core/wait.js +19 -0
  43. package/dist/core/wait.js.map +1 -0
  44. package/dist/index.d.ts +7 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +7 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/mcp/server.d.ts +4 -0
  49. package/dist/mcp/server.d.ts.map +1 -0
  50. package/dist/mcp/server.js +346 -0
  51. package/dist/mcp/server.js.map +1 -0
  52. package/package.json +49 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAiBjD,wBAAgB,UAAU,IAAI,cAAc,CA8C3C;AAED,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,cAAc,CAAC,GAAG,IAAI,CAejE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI;IAAE,aAAa,EAAE,OAAO,CAAC;IAAC,SAAS,EAAE,KAAK,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAAA;CAAE,CAW1G;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,cAAc,GAAG,MAAM,CAQ9D"}
@@ -0,0 +1,97 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ import crypto from 'node:crypto';
5
+ import { currentProfile } from './profiles.js';
6
+ // Official live gateway default: 华语站默认 https://123outlets.com
7
+ const DEFAULT_BASE_URL = 'https://123outlets.com';
8
+ // Must cover the gateway's 180s FunCloud first-token open. A shorter client
9
+ // abort is recorded as CANCELLED while the upstream call is still running.
10
+ const DEFAULT_TIMEOUT_MS = 180000;
11
+ function getConfigDir() {
12
+ return path.join(os.homedir(), '.lumenkey');
13
+ }
14
+ function getConfigPath() {
15
+ return path.join(getConfigDir(), 'config.json');
16
+ }
17
+ export function loadConfig() {
18
+ let fileConfig = {};
19
+ const configPath = getConfigPath();
20
+ if (fs.existsSync(configPath)) {
21
+ try {
22
+ const content = fs.readFileSync(configPath, 'utf-8');
23
+ fileConfig = JSON.parse(content);
24
+ }
25
+ catch {
26
+ // Ignore parse errors from file
27
+ }
28
+ }
29
+ const profile = currentProfile().record;
30
+ const apiKey = process.env.LUMENKEY_API_KEY ||
31
+ fileConfig.apiKey ||
32
+ profile?.key ||
33
+ undefined;
34
+ const rawBaseUrl = process.env.LUMENKEY_BASE_URL ||
35
+ fileConfig.baseUrl ||
36
+ profile?.host ||
37
+ DEFAULT_BASE_URL;
38
+ // Clean trailing slashes and /v1 suffix to avoid /v1/v1 duplication
39
+ const baseUrl = rawBaseUrl.replace(/\/+$/, '').replace(/\/v1$/, '');
40
+ const projectId = process.env.LUMENKEY_PROJECT_ID ||
41
+ fileConfig.projectId ||
42
+ profile?.projectId ||
43
+ undefined;
44
+ const envTimeout = Number(process.env.LUMENKEY_TIMEOUT_MS);
45
+ const timeoutMs = Number.isSafeInteger(envTimeout) && envTimeout > 0
46
+ ? envTimeout
47
+ : fileConfig.timeoutMs || DEFAULT_TIMEOUT_MS;
48
+ return {
49
+ apiKey,
50
+ baseUrl,
51
+ projectId,
52
+ timeoutMs,
53
+ };
54
+ }
55
+ export function saveConfig(updates) {
56
+ const configDir = getConfigDir();
57
+ if (!fs.existsSync(configDir)) {
58
+ fs.mkdirSync(configDir, { recursive: true });
59
+ }
60
+ const current = loadConfig();
61
+ const nextConfig = {
62
+ apiKey: updates.apiKey !== undefined ? updates.apiKey : current.apiKey,
63
+ baseUrl: updates.baseUrl !== undefined ? updates.baseUrl : current.baseUrl,
64
+ projectId: updates.projectId !== undefined ? updates.projectId : current.projectId,
65
+ timeoutMs: updates.timeoutMs !== undefined ? updates.timeoutMs : current.timeoutMs,
66
+ };
67
+ fs.writeFileSync(getConfigPath(), JSON.stringify(nextConfig, null, 2), { encoding: 'utf-8', mode: 0o600 });
68
+ }
69
+ /**
70
+ * Ensure a valid projectId UUID exists; if absent, generate and persist one.
71
+ */
72
+ export function describeKey() {
73
+ if (process.env.LUMENKEY_API_KEY)
74
+ return { keyConfigured: true, keySource: 'env' };
75
+ const filePath = getConfigPath();
76
+ if (fs.existsSync(filePath)) {
77
+ try {
78
+ const parsed = JSON.parse(fs.readFileSync(filePath, 'utf8'));
79
+ if (parsed.apiKey)
80
+ return { keyConfigured: true, keySource: 'config' };
81
+ }
82
+ catch { /* ignore unreadable config */ }
83
+ }
84
+ if (currentProfile().record?.key)
85
+ return { keyConfigured: true, keySource: 'profile' };
86
+ return { keyConfigured: false, keySource: 'none' };
87
+ }
88
+ export function ensureProjectId(config) {
89
+ if (config.projectId && /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(config.projectId)) {
90
+ return config.projectId;
91
+ }
92
+ const newId = crypto.randomUUID();
93
+ saveConfig({ projectId: newId });
94
+ config.projectId = newId;
95
+ return newId;
96
+ }
97
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/core/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ import type { ModelItem } from './types.js';
2
+ export interface ExplainedParam {
3
+ name: string;
4
+ type: unknown;
5
+ label: unknown;
6
+ required: boolean;
7
+ default: unknown;
8
+ length: unknown;
9
+ options: unknown[];
10
+ conditionalRules?: unknown[];
11
+ }
12
+ export interface ModelExplanation {
13
+ modelCode: string;
14
+ modelName: string | null;
15
+ nodeType: string | null;
16
+ restricted: boolean | null;
17
+ params: ExplainedParam[];
18
+ inputRules: unknown[];
19
+ }
20
+ /** Same keys as Pixmax `_model_explanation`, filled from this catalog's JSON Schema. */
21
+ export declare function explainModel(model: ModelItem): ModelExplanation;
22
+ export declare function findModels(models: ModelItem[], query: string, nodeType?: string): ModelItem[];
23
+ //# sourceMappingURL=explain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../src/core/explain.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,CAAC;IACd,KAAK,EAAE,OAAO,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,gBAAgB,CAAC,EAAE,OAAO,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,UAAU,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,UAAU,EAAE,OAAO,EAAE,CAAC;CACvB;AAUD,wFAAwF;AACxF,wBAAgB,YAAY,CAAC,KAAK,EAAE,SAAS,GAAG,gBAAgB,CA6B/D;AAED,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,EAAE,CAQ7F"}
@@ -0,0 +1,54 @@
1
+ import { LumenKeyError } from './client.js';
2
+ function schemaObject(model) {
3
+ const schema = model.inputSchema;
4
+ if (!schema || typeof schema !== 'object' || Array.isArray(schema))
5
+ throw new LumenKeyError('MODEL_INPUT_SCHEMA_INVALID');
6
+ const properties = schema.properties;
7
+ if (!properties || typeof properties !== 'object' || Array.isArray(properties))
8
+ throw new LumenKeyError('MODEL_INPUT_SCHEMA_INVALID');
9
+ return schema;
10
+ }
11
+ /** Same keys as Pixmax `_model_explanation`, filled from this catalog's JSON Schema. */
12
+ export function explainModel(model) {
13
+ const schema = schemaObject(model);
14
+ const properties = schema.properties;
15
+ const required = new Set(Array.isArray(schema.required) ? schema.required.filter((item) => typeof item === 'string') : []);
16
+ const params = [];
17
+ for (const [name, raw] of Object.entries(properties)) {
18
+ const item = raw && typeof raw === 'object' && !Array.isArray(raw) ? raw : {};
19
+ const options = Array.isArray(item.enum) ? item.enum : [];
20
+ const param = {
21
+ name,
22
+ type: item.type ?? null,
23
+ label: item.label ?? item.title ?? null,
24
+ required: required.has(name),
25
+ default: item.default ?? item.defaultValue ?? null,
26
+ length: item.maxLength ?? item.length ?? null,
27
+ options,
28
+ };
29
+ if (Array.isArray(item.conditionalRules) && item.conditionalRules.length > 0)
30
+ param.conditionalRules = item.conditionalRules;
31
+ params.push(param);
32
+ }
33
+ const record = model;
34
+ return {
35
+ modelCode: model.id,
36
+ modelName: model.displayName || model.name || record.modelName || null,
37
+ nodeType: model.type || record.nodeType || null,
38
+ restricted: typeof record.restricted === 'boolean' ? record.restricted : null,
39
+ params,
40
+ inputRules: Array.isArray(schema.inputRules) ? schema.inputRules : [],
41
+ };
42
+ }
43
+ export function findModels(models, query, nodeType) {
44
+ const needle = query.trim().toLowerCase();
45
+ return models.filter((model) => {
46
+ if (nodeType && model.type !== nodeType && !model.capabilities?.includes(nodeType))
47
+ return false;
48
+ if (!needle)
49
+ return true;
50
+ const names = [model.id, model.displayName, model.name].filter((item) => typeof item === 'string');
51
+ return names.some((name) => name.toLowerCase().includes(needle));
52
+ });
53
+ }
54
+ //# sourceMappingURL=explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"explain.js","sourceRoot":"","sources":["../../src/core/explain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { LumenKeyClient } from './client.js';
2
+ import { LumenKeyError } from './client.js';
3
+ import type { GenerationJobDetail } from './types.js';
4
+ export interface PollOptions {
5
+ initialIntervalMs?: number;
6
+ maxIntervalMs?: number;
7
+ timeoutMs?: number;
8
+ onProgress?: (detail: GenerationJobDetail) => void;
9
+ }
10
+ export declare class JobFailureError extends LumenKeyError {
11
+ constructor(code: string, message?: unknown);
12
+ }
13
+ export declare function assertJobResult(detail: GenerationJobDetail, requireOutput?: boolean): void;
14
+ export declare function pollJob(client: LumenKeyClient, jobId: string, options?: PollOptions): Promise<GenerationJobDetail>;
15
+ /**
16
+ * Downloads a remote URL to an explicit local file path
17
+ */
18
+ export declare function downloadFile(url: string, outputPath: string, overwrite?: boolean): Promise<string>;
19
+ //# sourceMappingURL=poller.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.d.ts","sourceRoot":"","sources":["../../src/core/poller.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtD,MAAM,WAAW,WAAW;IAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,mBAAmB,KAAK,IAAI,CAAC;CACpD;AAID,qBAAa,eAAgB,SAAQ,aAAa;gBACpC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO;CAe5C;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,mBAAmB,EAAE,aAAa,UAAQ,GAAG,IAAI,CAUxF;AAED,wBAAsB,OAAO,CAC3B,MAAM,EAAE,cAAc,EACtB,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,WAAgB,GACxB,OAAO,CAAC,mBAAmB,CAAC,CAwC9B;AAED;;GAEG;AACH,wBAAsB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CA4BtG"}
@@ -0,0 +1,108 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { pipeline } from 'node:stream/promises';
4
+ import { Readable } from 'node:stream';
5
+ import { Transform } from 'node:stream';
6
+ import crypto from 'node:crypto';
7
+ import { LumenKeyError } from './client.js';
8
+ const TERMINAL_STATES = new Set(['succeeded', 'rejected', 'failed', 'cancelled', 'expired']);
9
+ export class JobFailureError extends LumenKeyError {
10
+ constructor(code, message) {
11
+ super(code);
12
+ this.name = 'JobFailureError';
13
+ // Keep the public explanation short and single-line; never reflect credential
14
+ // assignments or URLs (which can contain signed access parameters).
15
+ const short = typeof message === 'string' ? message
16
+ .replace(/\u001b\[[0-?]*[ -/]*[@-~]/g, '')
17
+ .replace(/[\u0000-\u001f\u007f-\u009f]/g, ' ')
18
+ .replace(/\b(?:https?|postgres(?:ql)?|redis):\/\/\S+/gi, '[redacted]')
19
+ .replace(/\bBearer\s+\S+/gi, 'Bearer [redacted]')
20
+ .replace(/\b(?:api[_-]?key|token|secret|password|authorization|dsn)\s*[:=]\s*\S+/gi, '[redacted]')
21
+ .replace(/\b(?:sk-|lk_live_|lk_test_)[A-Za-z0-9_-]+/g, '[redacted]')
22
+ .replace(/\s+/g, ' ').trim().slice(0, 200) : '';
23
+ this.message = `${code}${short ? `: ${short}` : ''}`;
24
+ }
25
+ }
26
+ export function assertJobResult(detail, requireOutput = false) {
27
+ if (detail.error != null || ['failed', 'rejected', 'cancelled', 'expired'].includes(detail.status)) {
28
+ const error = typeof detail.error === 'object' && detail.error ? detail.error : {};
29
+ const code = typeof error.code === 'string' && (/^[a-z][a-z0-9_]{0,63}$/.test(error.code) || /^[A-Z][A-Z0-9_]{0,79}$/.test(error.code))
30
+ ? error.code : detail.status === 'cancelled' ? 'JOB_CANCELLED' : detail.status === 'expired' ? 'JOB_EXPIRED' : 'JOB_TERMINAL_FAILURE';
31
+ throw new JobFailureError(code, error.message);
32
+ }
33
+ if (requireOutput && (typeof detail.outputs?.[0]?.url !== 'string' || !detail.outputs[0].url.trim())) {
34
+ throw new JobFailureError('JOB_OUTPUT_MISSING');
35
+ }
36
+ }
37
+ export async function pollJob(client, jobId, options = {}) {
38
+ const { initialIntervalMs = 2000, maxIntervalMs = 10000, timeoutMs = 600000, // 10 minutes max for video
39
+ onProgress, } = options;
40
+ let interval = initialIntervalMs;
41
+ const startTime = Date.now();
42
+ while (true) {
43
+ if (Date.now() - startTime > timeoutMs) {
44
+ throw new Error(`Polling timed out after ${timeoutMs}ms for job ${jobId}. The job is still running on the server; you can resume querying with: lumenkey status ${jobId}`);
45
+ }
46
+ let detail;
47
+ try {
48
+ detail = await client.getJob(jobId);
49
+ }
50
+ catch (error) {
51
+ if (!(error instanceof LumenKeyError) || !(error.status === 429 || error.status === 502 || error.status === 503 || error.status === 504))
52
+ throw error;
53
+ const remaining = timeoutMs - (Date.now() - startTime);
54
+ if (remaining <= 0)
55
+ continue;
56
+ await new Promise(resolve => setTimeout(resolve, Math.min(remaining, Math.max(interval, error.retryAfterMs ?? 0))));
57
+ interval = Math.min(interval * 1.5, maxIntervalMs);
58
+ continue;
59
+ }
60
+ if (onProgress) {
61
+ onProgress(detail);
62
+ }
63
+ assertJobResult(detail);
64
+ if (TERMINAL_STATES.has(detail.status)) {
65
+ return detail; // succeeded
66
+ }
67
+ // Wait with exponential backoff
68
+ await new Promise((resolve) => setTimeout(resolve, interval));
69
+ interval = Math.min(interval * 1.5, maxIntervalMs);
70
+ }
71
+ }
72
+ /**
73
+ * Downloads a remote URL to an explicit local file path
74
+ */
75
+ export async function downloadFile(url, outputPath, overwrite = false) {
76
+ const resolvedPath = path.resolve(outputPath);
77
+ if (fs.existsSync(resolvedPath) && !overwrite) {
78
+ throw new Error(`Output file already exists at ${resolvedPath}. Pass overwrite: true or specify a different filename.`);
79
+ }
80
+ const parentDir = path.dirname(resolvedPath);
81
+ if (!fs.existsSync(parentDir)) {
82
+ fs.mkdirSync(parentDir, { recursive: true });
83
+ }
84
+ const target = new URL(url);
85
+ if (target.username || target.password || !['https:', 'http:'].includes(target.protocol))
86
+ throw new Error('DOWNLOAD_URL_INVALID');
87
+ const response = await fetch(url, { redirect: 'error', signal: AbortSignal.timeout(120000) });
88
+ if (!response.ok || !response.body) {
89
+ throw new Error(`DOWNLOAD_HTTP_ERROR_${response.status}`);
90
+ }
91
+ const temporary = `${resolvedPath}.${crypto.randomUUID()}.part`;
92
+ const limit = 128 * 1024 * 1024;
93
+ let bytes = 0;
94
+ try {
95
+ await pipeline(Readable.fromWeb(response.body), new Transform({ transform(chunk, _encoding, callback) { bytes += chunk.length; callback(bytes > limit ? new Error('DOWNLOAD_TOO_LARGE') : null, chunk); } }), fs.createWriteStream(temporary, { flags: 'wx', mode: 0o600 }));
96
+ if (overwrite)
97
+ await fs.promises.rename(temporary, resolvedPath);
98
+ else {
99
+ await fs.promises.link(temporary, resolvedPath);
100
+ await fs.promises.unlink(temporary);
101
+ }
102
+ }
103
+ finally {
104
+ await fs.promises.rm(temporary, { force: true });
105
+ }
106
+ return resolvedPath;
107
+ }
108
+ //# sourceMappingURL=poller.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"poller.js","sourceRoot":"","sources":["../../src/core/poller.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ export interface ProfileRecord {
2
+ key?: string;
3
+ host?: string;
4
+ projectId?: string;
5
+ }
6
+ export declare function currentProfile(home?: string): {
7
+ name?: string;
8
+ record?: ProfileRecord;
9
+ };
10
+ export declare function listProfiles(home?: string): {
11
+ current?: string;
12
+ profiles: Array<{
13
+ profile: string;
14
+ isSet: boolean;
15
+ settings: string[];
16
+ }>;
17
+ };
18
+ export declare function publicProfile(record: ProfileRecord | undefined): Record<string, unknown>;
19
+ export declare function createProfile(name: string, home?: string, activate?: boolean): 'created' | 'exists';
20
+ export declare function setProfile(name: string, home?: string): void;
21
+ export declare function unsetProfile(home?: string): void;
22
+ export declare function deleteProfile(name: string, home?: string): boolean;
23
+ export declare function setNamedProfileFields(name: string, fields: ProfileRecord, home?: string): void;
24
+ export declare function setProfileFields(fields: ProfileRecord, home?: string): string;
25
+ //# sourceMappingURL=profiles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.d.ts","sourceRoot":"","sources":["../../src/core/profiles.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AA4BD,wBAAgB,cAAc,CAAC,IAAI,SAAe,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,aAAa,CAAA;CAAE,CAI7F;AAED,wBAAgB,YAAY,CAAC,IAAI,SAAe,GAAG;IAAE,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAA;CAAE,CAUhJ;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKxF;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAe,EAAE,QAAQ,UAAO,GAAG,SAAS,GAAG,QAAQ,CAOtG;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAe,GAAG,IAAI,CAKlE;AAED,wBAAgB,YAAY,CAAC,IAAI,SAAe,GAAG,IAAI,CAItD;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,SAAe,GAAG,OAAO,CAOxE;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,SAAe,GAAG,IAAI,CAKpG;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,aAAa,EAAE,IAAI,SAAe,GAAG,MAAM,CAOnF"}
@@ -0,0 +1,96 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import os from 'node:os';
4
+ function filePath(home = os.homedir()) {
5
+ return path.join(home, '.lumenkey', 'profiles.json');
6
+ }
7
+ function read(home = os.homedir()) {
8
+ const target = filePath(home);
9
+ if (!fs.existsSync(target))
10
+ return { profiles: {} };
11
+ try {
12
+ const parsed = JSON.parse(fs.readFileSync(target, 'utf8'));
13
+ return { current: parsed.current, profiles: parsed.profiles && typeof parsed.profiles === 'object' ? parsed.profiles : {} };
14
+ }
15
+ catch {
16
+ return { profiles: {} };
17
+ }
18
+ }
19
+ function write(data, home = os.homedir()) {
20
+ const target = filePath(home);
21
+ fs.mkdirSync(path.dirname(target), { recursive: true });
22
+ fs.writeFileSync(target, JSON.stringify(data, null, 2), { mode: 0o600 });
23
+ }
24
+ export function currentProfile(home = os.homedir()) {
25
+ const data = read(home);
26
+ if (!data.current)
27
+ return {};
28
+ return { name: data.current, record: data.profiles[data.current] };
29
+ }
30
+ export function listProfiles(home = os.homedir()) {
31
+ const data = read(home);
32
+ return {
33
+ current: data.current,
34
+ profiles: Object.entries(data.profiles).map(([profile, record]) => ({
35
+ profile,
36
+ isSet: profile === data.current,
37
+ settings: Object.keys(record),
38
+ })),
39
+ };
40
+ }
41
+ export function publicProfile(record) {
42
+ if (!record)
43
+ return {};
44
+ const copy = { ...record, hasStoredToken: Boolean(record.key) };
45
+ delete copy.key;
46
+ return copy;
47
+ }
48
+ export function createProfile(name, home = os.homedir(), activate = true) {
49
+ const data = read(home);
50
+ if (data.profiles[name])
51
+ return 'exists';
52
+ data.profiles[name] = {};
53
+ if (activate)
54
+ data.current = name;
55
+ write(data, home);
56
+ return 'created';
57
+ }
58
+ export function setProfile(name, home = os.homedir()) {
59
+ const data = read(home);
60
+ if (!data.profiles[name])
61
+ throw new Error(`Profile ${name} does not exist.`);
62
+ data.current = name;
63
+ write(data, home);
64
+ }
65
+ export function unsetProfile(home = os.homedir()) {
66
+ const data = read(home);
67
+ delete data.current;
68
+ write(data, home);
69
+ }
70
+ export function deleteProfile(name, home = os.homedir()) {
71
+ const data = read(home);
72
+ if (!data.profiles[name])
73
+ return false;
74
+ delete data.profiles[name];
75
+ if (data.current === name)
76
+ delete data.current;
77
+ write(data, home);
78
+ return true;
79
+ }
80
+ export function setNamedProfileFields(name, fields, home = os.homedir()) {
81
+ const data = read(home);
82
+ if (!data.profiles[name])
83
+ throw new Error(`Profile ${name} does not exist.`);
84
+ data.profiles[name] = { ...data.profiles[name], ...fields };
85
+ write(data, home);
86
+ }
87
+ export function setProfileFields(fields, home = os.homedir()) {
88
+ const data = read(home);
89
+ const name = data.current;
90
+ if (!name || !data.profiles[name])
91
+ throw new Error('No key set for profile. Use profile create first.');
92
+ data.profiles[name] = { ...data.profiles[name], ...fields };
93
+ write(data, home);
94
+ return name;
95
+ }
96
+ //# sourceMappingURL=profiles.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profiles.js","sourceRoot":"","sources":["../../src/core/profiles.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /** Pixmax `_parse_value` plus fal's first `=` / `:=` split and `[index]` / `[]` paths. */
2
+ export declare function parseValue(value: string): unknown;
3
+ type PathStep = {
4
+ kind: 'key';
5
+ name: string;
6
+ } | {
7
+ kind: 'index';
8
+ index: number;
9
+ } | {
10
+ kind: 'append';
11
+ };
12
+ export declare function splitPair(pair: string): {
13
+ key: string;
14
+ raw: string;
15
+ };
16
+ export declare function parsePath(key: string): PathStep[];
17
+ export declare function setNested(payload: Record<string, unknown>, key: string, value: unknown): void;
18
+ export declare function applyKeyValues(payload: Record<string, unknown>, pairs: string[]): Record<string, unknown>;
19
+ export declare function validateKnownEnums(properties: Record<string, unknown>, input: Record<string, unknown>): void;
20
+ export declare function asPairs(value: unknown): string[];
21
+ export {};
22
+ //# sourceMappingURL=set-values.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set-values.d.ts","sourceRoot":"","sources":["../../src/core/set-values.ts"],"names":[],"mappings":"AAAA,0FAA0F;AAE1F,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAUjD;AAED,KAAK,QAAQ,GACT;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC;IAAE,IAAI,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEvB,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CAQpE;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,QAAQ,EAAE,CA8BjD;AAwCD,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,IAAI,CAK7F;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAOzG;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS5G;AAED,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAGhD"}
@@ -0,0 +1,141 @@
1
+ /** Pixmax `_parse_value` plus fal's first `=` / `:=` split and `[index]` / `[]` paths. */
2
+ export function parseValue(value) {
3
+ const text = value.trim();
4
+ if (text.toLowerCase() === 'true')
5
+ return true;
6
+ if (text.toLowerCase() === 'false')
7
+ return false;
8
+ if (text.toLowerCase() === 'null')
9
+ return null;
10
+ try {
11
+ return JSON.parse(text);
12
+ }
13
+ catch {
14
+ return value;
15
+ }
16
+ }
17
+ export function splitPair(pair) {
18
+ const equalsAt = pair.indexOf('=');
19
+ const colonAt = pair.indexOf(':=');
20
+ if (equalsAt < 0 && colonAt < 0)
21
+ throw new Error(`Expected key=value, got: ${pair}`);
22
+ if (colonAt >= 0 && (equalsAt < 0 || colonAt < equalsAt)) {
23
+ return { key: pair.slice(0, colonAt), raw: pair.slice(colonAt + 2) };
24
+ }
25
+ return { key: pair.slice(0, equalsAt), raw: pair.slice(equalsAt + 1) };
26
+ }
27
+ export function parsePath(key) {
28
+ const steps = [];
29
+ let i = 0;
30
+ const pushKey = (name) => {
31
+ if (!name)
32
+ throw new Error('Empty key in key=value option.');
33
+ if (name === '__proto__' || name === 'constructor' || name === 'prototype')
34
+ throw new Error('Unsafe key in key=value option.');
35
+ steps.push({ kind: 'key', name });
36
+ };
37
+ while (i < key.length) {
38
+ if (key[i] === '.') {
39
+ i += 1;
40
+ continue;
41
+ }
42
+ if (key[i] === '[') {
43
+ const end = key.indexOf(']', i);
44
+ if (end < 0)
45
+ throw new Error(`Expected key=value, got: ${key}`);
46
+ const inside = key.slice(i + 1, end);
47
+ if (inside === '')
48
+ steps.push({ kind: 'append' });
49
+ else if (/^\d+$/.test(inside))
50
+ steps.push({ kind: 'index', index: Number(inside) });
51
+ else
52
+ pushKey(inside);
53
+ i = end + 1;
54
+ continue;
55
+ }
56
+ const next = key.slice(i).search(/[.[]/);
57
+ const name = next < 0 ? key.slice(i) : key.slice(i, i + next);
58
+ pushKey(name);
59
+ i += name.length;
60
+ }
61
+ if (steps.length === 0)
62
+ throw new Error('Empty key in key=value option.');
63
+ return steps;
64
+ }
65
+ function containerFor(step) {
66
+ return step.kind === 'key' ? {} : [];
67
+ }
68
+ function writeAt(cursor, step, value) {
69
+ if (step.kind === 'key') {
70
+ if (cursor === null || typeof cursor !== 'object' || Array.isArray(cursor))
71
+ throw new Error(`Cannot set key ${step.name} on a non-object.`);
72
+ cursor[step.name] = value;
73
+ return;
74
+ }
75
+ if (!Array.isArray(cursor))
76
+ throw new Error('Cannot index a non-array.');
77
+ if (step.kind === 'append') {
78
+ cursor.push(value);
79
+ return;
80
+ }
81
+ if (step.index < 0)
82
+ throw new Error('Negative indexes are not supported.');
83
+ while (cursor.length <= step.index)
84
+ cursor.push(null);
85
+ cursor[step.index] = value;
86
+ }
87
+ function descend(cursor, step, next) {
88
+ if (step.kind === 'key') {
89
+ if (cursor === null || typeof cursor !== 'object' || Array.isArray(cursor))
90
+ throw new Error(`Cannot set key ${step.name} on a non-object.`);
91
+ const record = cursor;
92
+ if (record[step.name] == null || typeof record[step.name] !== 'object')
93
+ record[step.name] = containerFor(next);
94
+ return record[step.name];
95
+ }
96
+ if (!Array.isArray(cursor))
97
+ throw new Error('Cannot index a non-array.');
98
+ if (step.kind === 'append') {
99
+ cursor.push(containerFor(next));
100
+ return cursor[cursor.length - 1];
101
+ }
102
+ if (step.index < 0)
103
+ throw new Error('Negative indexes are not supported.');
104
+ while (cursor.length <= step.index)
105
+ cursor.push(null);
106
+ if (cursor[step.index] == null || typeof cursor[step.index] !== 'object')
107
+ cursor[step.index] = containerFor(next);
108
+ return cursor[step.index];
109
+ }
110
+ export function setNested(payload, key, value) {
111
+ const steps = parsePath(key);
112
+ let cursor = payload;
113
+ for (let i = 0; i < steps.length - 1; i += 1)
114
+ cursor = descend(cursor, steps[i], steps[i + 1]);
115
+ writeAt(cursor, steps[steps.length - 1], value);
116
+ }
117
+ export function applyKeyValues(payload, pairs) {
118
+ const result = { ...payload };
119
+ for (const pair of pairs) {
120
+ const { key, raw } = splitPair(pair);
121
+ setNested(result, key, parseValue(raw));
122
+ }
123
+ return result;
124
+ }
125
+ export function validateKnownEnums(properties, input) {
126
+ for (const [key, value] of Object.entries(input)) {
127
+ const spec = properties[key];
128
+ if (!spec || typeof spec !== 'object' || Array.isArray(spec))
129
+ continue;
130
+ const options = spec.enum;
131
+ if (Array.isArray(options) && options.length > 0 && !options.includes(value)) {
132
+ throw new Error(`Invalid value for ${key}: ${String(value)}`);
133
+ }
134
+ }
135
+ }
136
+ export function asPairs(value) {
137
+ if (value == null)
138
+ return [];
139
+ return Array.isArray(value) ? value.map(String) : [String(value)];
140
+ }
141
+ //# sourceMappingURL=set-values.js.map