@soederpop/luca 0.0.2
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/CLAUDE.md +71 -0
- package/README.md +78 -0
- package/bun.lock +2928 -0
- package/bunfig.toml +3 -0
- package/commands/audit-docs.ts +740 -0
- package/commands/build-scaffolds.ts +154 -0
- package/commands/generate-api-docs.ts +114 -0
- package/commands/update-introspection.ts +67 -0
- package/docs/CLI.md +335 -0
- package/docs/README.md +88 -0
- package/docs/TABLE-OF-CONTENTS.md +157 -0
- package/docs/apis/clients/elevenlabs.md +84 -0
- package/docs/apis/clients/graph.md +56 -0
- package/docs/apis/clients/openai.md +69 -0
- package/docs/apis/clients/rest.md +41 -0
- package/docs/apis/clients/websocket.md +107 -0
- package/docs/apis/features/agi/assistant.md +471 -0
- package/docs/apis/features/agi/assistants-manager.md +154 -0
- package/docs/apis/features/agi/claude-code.md +602 -0
- package/docs/apis/features/agi/conversation-history.md +352 -0
- package/docs/apis/features/agi/conversation.md +333 -0
- package/docs/apis/features/agi/docs-reader.md +121 -0
- package/docs/apis/features/agi/openai-codex.md +318 -0
- package/docs/apis/features/agi/openapi.md +138 -0
- package/docs/apis/features/agi/semantic-search.md +387 -0
- package/docs/apis/features/agi/skills-library.md +216 -0
- package/docs/apis/features/node/container-link.md +133 -0
- package/docs/apis/features/node/content-db.md +313 -0
- package/docs/apis/features/node/disk-cache.md +379 -0
- package/docs/apis/features/node/dns.md +651 -0
- package/docs/apis/features/node/docker.md +705 -0
- package/docs/apis/features/node/downloader.md +81 -0
- package/docs/apis/features/node/esbuild.md +59 -0
- package/docs/apis/features/node/file-manager.md +182 -0
- package/docs/apis/features/node/fs.md +581 -0
- package/docs/apis/features/node/git.md +330 -0
- package/docs/apis/features/node/google-auth.md +174 -0
- package/docs/apis/features/node/google-calendar.md +187 -0
- package/docs/apis/features/node/google-docs.md +151 -0
- package/docs/apis/features/node/google-drive.md +225 -0
- package/docs/apis/features/node/google-sheets.md +179 -0
- package/docs/apis/features/node/grep.md +290 -0
- package/docs/apis/features/node/helpers.md +135 -0
- package/docs/apis/features/node/ink.md +334 -0
- package/docs/apis/features/node/ipc-socket.md +260 -0
- package/docs/apis/features/node/json-tree.md +86 -0
- package/docs/apis/features/node/launcher-app-command-listener.md +145 -0
- package/docs/apis/features/node/networking.md +281 -0
- package/docs/apis/features/node/nlp.md +133 -0
- package/docs/apis/features/node/opener.md +97 -0
- package/docs/apis/features/node/os.md +118 -0
- package/docs/apis/features/node/package-finder.md +402 -0
- package/docs/apis/features/node/postgres.md +212 -0
- package/docs/apis/features/node/proc.md +430 -0
- package/docs/apis/features/node/process-manager.md +210 -0
- package/docs/apis/features/node/python.md +278 -0
- package/docs/apis/features/node/repl.md +88 -0
- package/docs/apis/features/node/runpod.md +673 -0
- package/docs/apis/features/node/secure-shell.md +169 -0
- package/docs/apis/features/node/semantic-search.md +401 -0
- package/docs/apis/features/node/sqlite.md +211 -0
- package/docs/apis/features/node/telegram.md +254 -0
- package/docs/apis/features/node/tts.md +118 -0
- package/docs/apis/features/node/ui.md +703 -0
- package/docs/apis/features/node/vault.md +64 -0
- package/docs/apis/features/node/vm.md +84 -0
- package/docs/apis/features/node/window-manager.md +337 -0
- package/docs/apis/features/node/yaml-tree.md +85 -0
- package/docs/apis/features/node/yaml.md +176 -0
- package/docs/apis/features/web/asset-loader.md +47 -0
- package/docs/apis/features/web/container-link.md +133 -0
- package/docs/apis/features/web/esbuild.md +59 -0
- package/docs/apis/features/web/helpers.md +135 -0
- package/docs/apis/features/web/network.md +30 -0
- package/docs/apis/features/web/speech.md +55 -0
- package/docs/apis/features/web/vault.md +64 -0
- package/docs/apis/features/web/vm.md +84 -0
- package/docs/apis/features/web/voice.md +67 -0
- package/docs/apis/servers/express.md +127 -0
- package/docs/apis/servers/mcp.md +213 -0
- package/docs/apis/servers/websocket.md +99 -0
- package/docs/documentation-audit.md +134 -0
- package/docs/examples/content-db.md +77 -0
- package/docs/examples/disk-cache.md +83 -0
- package/docs/examples/docker.md +101 -0
- package/docs/examples/downloader.md +70 -0
- package/docs/examples/esbuild.md +80 -0
- package/docs/examples/file-manager.md +82 -0
- package/docs/examples/fs.md +83 -0
- package/docs/examples/git.md +85 -0
- package/docs/examples/google-auth.md +88 -0
- package/docs/examples/google-calendar.md +94 -0
- package/docs/examples/google-docs.md +82 -0
- package/docs/examples/google-drive.md +96 -0
- package/docs/examples/google-sheets.md +95 -0
- package/docs/examples/grep.md +85 -0
- package/docs/examples/ink-blocks.md +75 -0
- package/docs/examples/ink-renderer.md +41 -0
- package/docs/examples/ink.md +103 -0
- package/docs/examples/ipc-socket.md +103 -0
- package/docs/examples/json-tree.md +91 -0
- package/docs/examples/launcher-app-command-listener.md +120 -0
- package/docs/examples/networking.md +58 -0
- package/docs/examples/nlp.md +91 -0
- package/docs/examples/opener.md +78 -0
- package/docs/examples/os.md +72 -0
- package/docs/examples/package-finder.md +89 -0
- package/docs/examples/port-exposer.md +89 -0
- package/docs/examples/postgres.md +91 -0
- package/docs/examples/proc.md +81 -0
- package/docs/examples/process-manager.md +79 -0
- package/docs/examples/python.md +91 -0
- package/docs/examples/repl.md +93 -0
- package/docs/examples/runpod.md +119 -0
- package/docs/examples/secure-shell.md +92 -0
- package/docs/examples/sqlite.md +86 -0
- package/docs/examples/telegram.md +77 -0
- package/docs/examples/tts.md +86 -0
- package/docs/examples/ui.md +80 -0
- package/docs/examples/vault.md +70 -0
- package/docs/examples/vm.md +86 -0
- package/docs/examples/window-manager.md +125 -0
- package/docs/examples/yaml-tree.md +93 -0
- package/docs/examples/yaml.md +104 -0
- package/docs/ideas/class-registration-refactor-possibilities.md +197 -0
- package/docs/ideas/container-use-api.md +9 -0
- package/docs/ideas/easy-auth-for-express-servers-and-luca-serve.md +0 -0
- package/docs/ideas/feature-stacks.md +22 -0
- package/docs/ideas/luca-cli-self-sufficiency-demo.md +23 -0
- package/docs/ideas/mcp-design.md +9 -0
- package/docs/ideas/web-container-debugging-feature.md +13 -0
- package/docs/introspection-audit.md +49 -0
- package/docs/introspection.md +154 -0
- package/docs/mcp/readme.md +162 -0
- package/docs/models.ts +38 -0
- package/docs/philosophy.md +85 -0
- package/docs/principles.md +7 -0
- package/docs/prompts/audit-codebase-for-failures-to-use-the-container.md +34 -0
- package/docs/prompts/mcp-test-easy-command.md +27 -0
- package/docs/reports/assistant-bugs.md +38 -0
- package/docs/reports/attach-pattern-usage.md +18 -0
- package/docs/reports/code-audit-results.md +391 -0
- package/docs/reports/introspection-audit-tasks.md +378 -0
- package/docs/reports/luca-mcp-improvements.md +128 -0
- package/docs/scaffolds/client.md +140 -0
- package/docs/scaffolds/command.md +106 -0
- package/docs/scaffolds/endpoint.md +176 -0
- package/docs/scaffolds/feature.md +148 -0
- package/docs/scaffolds/server.md +187 -0
- package/docs/tasks/web-container-helper-discovery.md +71 -0
- package/docs/todos.md +1 -0
- package/docs/tutorials/01-getting-started.md +106 -0
- package/docs/tutorials/02-container.md +210 -0
- package/docs/tutorials/03-scripts.md +194 -0
- package/docs/tutorials/04-features-overview.md +196 -0
- package/docs/tutorials/05-state-and-events.md +171 -0
- package/docs/tutorials/06-servers.md +157 -0
- package/docs/tutorials/07-endpoints.md +198 -0
- package/docs/tutorials/08-commands.md +171 -0
- package/docs/tutorials/09-clients.md +162 -0
- package/docs/tutorials/10-creating-features.md +198 -0
- package/docs/tutorials/11-contentbase.md +191 -0
- package/docs/tutorials/12-assistants.md +215 -0
- package/docs/tutorials/13-introspection.md +147 -0
- package/docs/tutorials/14-type-system.md +174 -0
- package/docs/tutorials/15-project-patterns.md +222 -0
- package/docs/tutorials/16-google-features.md +534 -0
- package/docs/tutorials/17-tui-blocks.md +530 -0
- package/docs/tutorials/18-semantic-search.md +334 -0
- package/index.ts +1 -0
- package/luca.console.ts +9 -0
- package/main.py +6 -0
- package/package.json +154 -0
- package/pyproject.toml +7 -0
- package/scripts/animations/chrome-glitch.ts +55 -0
- package/scripts/animations/index.ts +16 -0
- package/scripts/animations/neon-pulse.ts +64 -0
- package/scripts/animations/types.ts +6 -0
- package/scripts/build-web.ts +28 -0
- package/scripts/examples/ask-luca-expert.ts +42 -0
- package/scripts/examples/assistant-questions.ts +12 -0
- package/scripts/examples/excalidraw-expert.ts +75 -0
- package/scripts/examples/expert-chat.ts +0 -0
- package/scripts/examples/file-manager.ts +14 -0
- package/scripts/examples/ideas.ts +12 -0
- package/scripts/examples/interactive-chat.ts +20 -0
- package/scripts/examples/openai-tool-calls.ts +113 -0
- package/scripts/examples/opening-a-web-browser.ts +5 -0
- package/scripts/examples/telegram-bot.ts +79 -0
- package/scripts/examples/telegram-ink-ui.ts +302 -0
- package/scripts/examples/using-assistant-with-mcp.ts +560 -0
- package/scripts/examples/using-claude-code.ts +10 -0
- package/scripts/examples/using-contentdb.ts +35 -0
- package/scripts/examples/using-conversations.ts +35 -0
- package/scripts/examples/using-disk-cache.ts +10 -0
- package/scripts/examples/using-docker-shell.ts +75 -0
- package/scripts/examples/using-elevenlabs.ts +25 -0
- package/scripts/examples/using-google-calendar.ts +57 -0
- package/scripts/examples/using-google-docs.ts +74 -0
- package/scripts/examples/using-google-drive.ts +74 -0
- package/scripts/examples/using-google-sheets.ts +89 -0
- package/scripts/examples/using-nlp.ts +55 -0
- package/scripts/examples/using-ollama.ts +10 -0
- package/scripts/examples/using-openai-codex.ts +23 -0
- package/scripts/examples/using-postgres.ts +55 -0
- package/scripts/examples/using-runpod.ts +32 -0
- package/scripts/examples/using-tts.ts +40 -0
- package/scripts/examples/vm-loading-esm-modules.ts +16 -0
- package/scripts/scaffold.ts +391 -0
- package/scripts/scratch.ts +15 -0
- package/scripts/test-command-listener.ts +123 -0
- package/scripts/test-window-manager-lifecycle.ts +86 -0
- package/scripts/test-window-manager.ts +43 -0
- package/scripts/update-introspection-data.ts +58 -0
- package/src/agi/README.md +14 -0
- package/src/agi/container.server.ts +114 -0
- package/src/agi/endpoints/ask.ts +60 -0
- package/src/agi/endpoints/conversations/[id].ts +45 -0
- package/src/agi/endpoints/conversations.ts +31 -0
- package/src/agi/endpoints/experts.ts +37 -0
- package/src/agi/features/assistant.ts +767 -0
- package/src/agi/features/assistants-manager.ts +260 -0
- package/src/agi/features/claude-code.ts +1111 -0
- package/src/agi/features/conversation-history.ts +497 -0
- package/src/agi/features/conversation.ts +799 -0
- package/src/agi/features/openai-codex.ts +631 -0
- package/src/agi/features/openapi.ts +438 -0
- package/src/agi/features/skills-library.ts +425 -0
- package/src/agi/index.ts +6 -0
- package/src/agi/lib/token-counter.ts +122 -0
- package/src/browser.ts +25 -0
- package/src/bus.ts +100 -0
- package/src/cli/cli.ts +70 -0
- package/src/client.ts +461 -0
- package/src/clients/civitai/index.ts +541 -0
- package/src/clients/client-template.ts +41 -0
- package/src/clients/comfyui/index.ts +597 -0
- package/src/clients/elevenlabs/index.ts +291 -0
- package/src/clients/openai/index.ts +451 -0
- package/src/clients/supabase/index.ts +366 -0
- package/src/command.ts +164 -0
- package/src/commands/chat.ts +182 -0
- package/src/commands/console.ts +192 -0
- package/src/commands/describe.ts +433 -0
- package/src/commands/eval.ts +116 -0
- package/src/commands/help.ts +214 -0
- package/src/commands/index.ts +14 -0
- package/src/commands/mcp.ts +64 -0
- package/src/commands/prompt.ts +807 -0
- package/src/commands/run.ts +257 -0
- package/src/commands/sandbox-mcp.ts +439 -0
- package/src/commands/scaffold.ts +79 -0
- package/src/commands/serve.ts +172 -0
- package/src/container.ts +781 -0
- package/src/endpoint.ts +340 -0
- package/src/feature.ts +75 -0
- package/src/hash-object.ts +97 -0
- package/src/helper.ts +543 -0
- package/src/introspection/generated.agi.ts +23388 -0
- package/src/introspection/generated.node.ts +18899 -0
- package/src/introspection/generated.web.ts +2021 -0
- package/src/introspection/index.ts +256 -0
- package/src/introspection/scan.ts +912 -0
- package/src/node/container.ts +354 -0
- package/src/node/feature.ts +13 -0
- package/src/node/features/container-link.ts +558 -0
- package/src/node/features/content-db.ts +475 -0
- package/src/node/features/disk-cache.ts +382 -0
- package/src/node/features/dns.ts +655 -0
- package/src/node/features/docker.ts +912 -0
- package/src/node/features/downloader.ts +92 -0
- package/src/node/features/esbuild.ts +68 -0
- package/src/node/features/file-manager.ts +357 -0
- package/src/node/features/fs.ts +534 -0
- package/src/node/features/git.ts +492 -0
- package/src/node/features/google-auth.ts +502 -0
- package/src/node/features/google-calendar.ts +300 -0
- package/src/node/features/google-docs.ts +404 -0
- package/src/node/features/google-drive.ts +339 -0
- package/src/node/features/google-sheets.ts +279 -0
- package/src/node/features/grep.ts +406 -0
- package/src/node/features/helpers.ts +374 -0
- package/src/node/features/ink.ts +490 -0
- package/src/node/features/ipc-socket.ts +459 -0
- package/src/node/features/json-tree.ts +188 -0
- package/src/node/features/launcher-app-command-listener.ts +388 -0
- package/src/node/features/networking.ts +925 -0
- package/src/node/features/nlp.ts +211 -0
- package/src/node/features/opener.ts +166 -0
- package/src/node/features/os.ts +157 -0
- package/src/node/features/package-finder.ts +539 -0
- package/src/node/features/port-exposer.ts +342 -0
- package/src/node/features/postgres.ts +273 -0
- package/src/node/features/proc.ts +502 -0
- package/src/node/features/process-manager.ts +542 -0
- package/src/node/features/python.ts +444 -0
- package/src/node/features/repl.ts +194 -0
- package/src/node/features/runpod.ts +802 -0
- package/src/node/features/secure-shell.ts +248 -0
- package/src/node/features/semantic-search.ts +924 -0
- package/src/node/features/sqlite.ts +289 -0
- package/src/node/features/telegram.ts +342 -0
- package/src/node/features/tts.ts +184 -0
- package/src/node/features/ui.ts +857 -0
- package/src/node/features/vault.ts +164 -0
- package/src/node/features/vm.ts +312 -0
- package/src/node/features/window-manager.ts +804 -0
- package/src/node/features/yaml-tree.ts +149 -0
- package/src/node/features/yaml.ts +132 -0
- package/src/node.ts +70 -0
- package/src/react/index.ts +175 -0
- package/src/registry.ts +199 -0
- package/src/scaffolds/generated.ts +1613 -0
- package/src/scaffolds/template.ts +37 -0
- package/src/schemas/base.ts +255 -0
- package/src/server.ts +135 -0
- package/src/servers/express.ts +209 -0
- package/src/servers/mcp.ts +805 -0
- package/src/servers/socket.ts +120 -0
- package/src/state.ts +101 -0
- package/src/web/clients/socket.ts +82 -0
- package/src/web/container.ts +74 -0
- package/src/web/extension.ts +30 -0
- package/src/web/feature.ts +12 -0
- package/src/web/features/asset-loader.ts +64 -0
- package/src/web/features/container-link.ts +385 -0
- package/src/web/features/esbuild.ts +79 -0
- package/src/web/features/helpers.ts +267 -0
- package/src/web/features/network.ts +61 -0
- package/src/web/features/speech.ts +87 -0
- package/src/web/features/vault.ts +189 -0
- package/src/web/features/vm.ts +78 -0
- package/src/web/features/voice-recognition.ts +129 -0
- package/src/web/shims/isomorphic-vm.ts +149 -0
- package/test/bus.test.ts +134 -0
- package/test/clients-servers.test.ts +216 -0
- package/test/container-link.test.ts +274 -0
- package/test/features.test.ts +160 -0
- package/test/integration.test.ts +787 -0
- package/test/node-container.test.ts +121 -0
- package/test/rate-limit.test.ts +272 -0
- package/test/semantic-search.test.ts +550 -0
- package/test/state.test.ts +121 -0
- package/test-integration/assistant.test.ts +138 -0
- package/test-integration/assistants-manager.test.ts +123 -0
- package/test-integration/claude-code.test.ts +98 -0
- package/test-integration/conversation-history.test.ts +205 -0
- package/test-integration/conversation.test.ts +137 -0
- package/test-integration/elevenlabs.test.ts +55 -0
- package/test-integration/google-services.test.ts +80 -0
- package/test-integration/helpers.ts +89 -0
- package/test-integration/openai-codex.test.ts +93 -0
- package/test-integration/runpod.test.ts +58 -0
- package/test-integration/server-endpoints.test.ts +97 -0
- package/test-integration/skills-library.test.ts +157 -0
- package/test-integration/telegram.test.ts +46 -0
- package/tsconfig.json +58 -0
- package/uv.lock +8 -0
|
@@ -0,0 +1,382 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { FeatureStateSchema, FeatureOptionsSchema } from '../../schemas/base.js'
|
|
3
|
+
import cacache from "cacache";
|
|
4
|
+
import { Feature, type FeatureState, features } from "../feature.js";
|
|
5
|
+
import { NodeContainer } from "../container.js";
|
|
6
|
+
import { partial } from "lodash-es";
|
|
7
|
+
import type { ContainerContext } from "../../container.js";
|
|
8
|
+
|
|
9
|
+
export const DiskCacheOptionsSchema = FeatureOptionsSchema.extend({
|
|
10
|
+
/** Whether to enable encryption for cached data */
|
|
11
|
+
encrypt: z.boolean().optional().describe('Whether to enable encryption for cached data'),
|
|
12
|
+
/** Secret key used for encryption operations */
|
|
13
|
+
secret: z.custom<Buffer>().optional().describe('Secret key buffer used for encryption operations'),
|
|
14
|
+
/** Custom directory path for the cache storage */
|
|
15
|
+
path: z.string().optional().describe('Custom directory path for the cache storage'),
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export type DiskCacheOptions = z.infer<typeof DiskCacheOptionsSchema>
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* File-backed key-value cache built on top of the cacache library (the same store
|
|
22
|
+
* that powers npm). Suitable for persisting arbitrary data including very large
|
|
23
|
+
* blobs when necessary, with optional encryption support.
|
|
24
|
+
*
|
|
25
|
+
* @extends Feature
|
|
26
|
+
* @example
|
|
27
|
+
* ```typescript
|
|
28
|
+
* const diskCache = container.feature('diskCache', { path: '/tmp/cache' })
|
|
29
|
+
* await diskCache.set('greeting', 'Hello World')
|
|
30
|
+
* const value = await diskCache.get('greeting')
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export class DiskCache extends Feature<FeatureState,DiskCacheOptions> {
|
|
34
|
+
static override shortcut = "features.diskCache" as const
|
|
35
|
+
static override stateSchema = FeatureStateSchema
|
|
36
|
+
static override optionsSchema = DiskCacheOptionsSchema
|
|
37
|
+
|
|
38
|
+
static attach(c: NodeContainer) {}
|
|
39
|
+
|
|
40
|
+
constructor(options: DiskCacheOptions, context: ContainerContext) {
|
|
41
|
+
super(options, context)
|
|
42
|
+
this._cache = this.create()
|
|
43
|
+
this.hide('_cache')
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Returns the underlying cacache instance configured with the cache directory path. */
|
|
47
|
+
get cache() {
|
|
48
|
+
return this._cache
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Retrieve a file from the disk cache and save it to the local disk
|
|
53
|
+
* @param key - The cache key to retrieve
|
|
54
|
+
* @param outputPath - The local path where the file should be saved
|
|
55
|
+
* @param isBase64 - Whether the cached content is base64 encoded
|
|
56
|
+
* @returns Promise that resolves to the file data as Buffer
|
|
57
|
+
* @example
|
|
58
|
+
* ```typescript
|
|
59
|
+
* await diskCache.saveFile('myFile', './output/file.txt')
|
|
60
|
+
* await diskCache.saveFile('encodedImage', './images/photo.jpg', true)
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
async saveFile(key: string, outputPath: string, isBase64 = false) {
|
|
64
|
+
const outPath = this.container.paths.resolve(outputPath)
|
|
65
|
+
const content = await this.get(key)
|
|
66
|
+
const data = isBase64 ? Buffer.from(content, 'base64') : content
|
|
67
|
+
await this.container.fs.writeFileAsync(outPath, data)
|
|
68
|
+
return data
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Ensure a key exists in the cache, setting it with the provided content if it doesn't exist
|
|
73
|
+
* @param key - The cache key to check/set
|
|
74
|
+
* @param content - The content to set if the key doesn't exist
|
|
75
|
+
* @returns Promise that resolves to the key
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* await diskCache.ensure('config', JSON.stringify(defaultConfig))
|
|
79
|
+
* ```
|
|
80
|
+
*/
|
|
81
|
+
async ensure(key: string, content: string) {
|
|
82
|
+
const exists = await this.has(key)
|
|
83
|
+
|
|
84
|
+
if (!exists) {
|
|
85
|
+
await this.set(key, content)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return key
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Copy a cached item from one key to another
|
|
93
|
+
* @param source - The source cache key
|
|
94
|
+
* @param destination - The destination cache key
|
|
95
|
+
* @param overwrite - Whether to overwrite if destination exists (default: false)
|
|
96
|
+
* @returns Promise that resolves to the destination key
|
|
97
|
+
* @throws Error if destination exists and overwrite is false
|
|
98
|
+
* @example
|
|
99
|
+
* ```typescript
|
|
100
|
+
* await diskCache.copy('original', 'backup')
|
|
101
|
+
* await diskCache.copy('file1', 'file2', true) // force overwrite
|
|
102
|
+
* ```
|
|
103
|
+
*/
|
|
104
|
+
async copy(source: string, destination: string, overwrite: boolean = false) {
|
|
105
|
+
if(!overwrite && (await this.has(destination))) {
|
|
106
|
+
throw new Error('Destination already exists')
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
const content = await this.get(source)
|
|
110
|
+
await this.set(destination, content)
|
|
111
|
+
return destination
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Move a cached item from one key to another (copy then delete source)
|
|
116
|
+
* @param source - The source cache key
|
|
117
|
+
* @param destination - The destination cache key
|
|
118
|
+
* @param overwrite - Whether to overwrite if destination exists (default: false)
|
|
119
|
+
* @returns Promise that resolves to the destination key
|
|
120
|
+
* @throws Error if destination exists and overwrite is false
|
|
121
|
+
* @example
|
|
122
|
+
* ```typescript
|
|
123
|
+
* await diskCache.move('temp', 'permanent')
|
|
124
|
+
* await diskCache.move('old_key', 'new_key', true) // force overwrite
|
|
125
|
+
* ```
|
|
126
|
+
*/
|
|
127
|
+
async move(source: string, destination: string, overwrite: boolean = false) {
|
|
128
|
+
if(!overwrite && (await this.has(destination))) {
|
|
129
|
+
throw new Error('Destination already exists')
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const content = await this.get(source)
|
|
133
|
+
await this.set(destination, content)
|
|
134
|
+
await this.rm(source)
|
|
135
|
+
return destination
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Check if a key exists in the cache
|
|
140
|
+
* @param key - The cache key to check
|
|
141
|
+
* @returns Promise that resolves to true if key exists, false otherwise
|
|
142
|
+
* @example
|
|
143
|
+
* ```typescript
|
|
144
|
+
* if (await diskCache.has('myKey')) {
|
|
145
|
+
* console.log('Key exists!')
|
|
146
|
+
* }
|
|
147
|
+
* ```
|
|
148
|
+
*/
|
|
149
|
+
async has(key: string) {
|
|
150
|
+
return this.cache.get.info(key).then((r:any) => r != null)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Retrieve a value from the cache
|
|
155
|
+
* @param key - The cache key to retrieve
|
|
156
|
+
* @param json - Whether to parse the value as JSON (default: false)
|
|
157
|
+
* @returns Promise that resolves to the cached value (string or parsed JSON)
|
|
158
|
+
* @example
|
|
159
|
+
* ```typescript
|
|
160
|
+
* const text = await diskCache.get('myText')
|
|
161
|
+
* const data = await diskCache.get('myData', true) // parse as JSON
|
|
162
|
+
* ```
|
|
163
|
+
*/
|
|
164
|
+
async get(key: string, json = false) {
|
|
165
|
+
const val = this.options.encrypt
|
|
166
|
+
? await this.securely.get(key)
|
|
167
|
+
: await this.cache.get(key).then((data: any) => data.data.toString())
|
|
168
|
+
|
|
169
|
+
if (json) {
|
|
170
|
+
try {
|
|
171
|
+
return JSON.parse(val)
|
|
172
|
+
} catch(error) {
|
|
173
|
+
return { error: "parse error "}
|
|
174
|
+
}
|
|
175
|
+
} else {
|
|
176
|
+
return val
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Store a value in the cache
|
|
182
|
+
* @param key - The cache key to store under
|
|
183
|
+
* @param value - The value to store (string, object, or any serializable data)
|
|
184
|
+
* @param meta - Optional metadata to associate with the cached item
|
|
185
|
+
* @returns Promise that resolves when the value is stored
|
|
186
|
+
* @example
|
|
187
|
+
* ```typescript
|
|
188
|
+
* await diskCache.set('myKey', 'Hello World')
|
|
189
|
+
* await diskCache.set('userData', { name: 'John', age: 30 })
|
|
190
|
+
* await diskCache.set('file', content, { size: 1024, type: 'image' })
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
async set(key: string, value: any, meta?: any) {
|
|
194
|
+
if (this.options.encrypt) {
|
|
195
|
+
return this.securely.set(key, value, meta)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
if(typeof value !== 'string') {
|
|
199
|
+
return this.cache.put(key, Buffer.from(JSON.stringify(value)), {
|
|
200
|
+
...(meta && { metadata: meta })
|
|
201
|
+
})
|
|
202
|
+
} else {
|
|
203
|
+
return this.cache.put(key, Buffer.from(value), {
|
|
204
|
+
...(meta && { metadata: meta })
|
|
205
|
+
})
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Remove a cached item
|
|
211
|
+
* @param key - The cache key to remove
|
|
212
|
+
* @returns Promise that resolves when the item is removed
|
|
213
|
+
* @example
|
|
214
|
+
* ```typescript
|
|
215
|
+
* await diskCache.rm('obsoleteKey')
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
async rm(key: string) {
|
|
219
|
+
return this.cache.rm.entry(key)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Clear all cached items
|
|
224
|
+
* @param confirm - Must be set to true to confirm the operation
|
|
225
|
+
* @returns Promise that resolves to this instance for chaining
|
|
226
|
+
* @throws Error if confirm is not true
|
|
227
|
+
* @example
|
|
228
|
+
* ```typescript
|
|
229
|
+
* await diskCache.clearAll(true) // Must explicitly confirm
|
|
230
|
+
* ```
|
|
231
|
+
*/
|
|
232
|
+
async clearAll(confirm = false) {
|
|
233
|
+
if(confirm !== true) {
|
|
234
|
+
throw new Error('Must confirm with clearAll(true)')
|
|
235
|
+
}
|
|
236
|
+
await this.cache.rm.all()
|
|
237
|
+
return this
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Get all cache keys
|
|
242
|
+
* @returns Promise that resolves to an array of all cache keys
|
|
243
|
+
* @example
|
|
244
|
+
* ```typescript
|
|
245
|
+
* const allKeys = await diskCache.keys()
|
|
246
|
+
* console.log(`Cache contains ${allKeys.length} items`)
|
|
247
|
+
* ```
|
|
248
|
+
*/
|
|
249
|
+
async keys() : Promise<string[]> {
|
|
250
|
+
return this.cache.ls().then((results: Record<string,any>) => Object.keys(results))
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* List all cache keys (alias for keys())
|
|
255
|
+
* @returns Promise that resolves to an array of all cache keys
|
|
256
|
+
* @example
|
|
257
|
+
* ```typescript
|
|
258
|
+
* const keyList = await diskCache.listKeys()
|
|
259
|
+
* ```
|
|
260
|
+
*/
|
|
261
|
+
async listKeys() : Promise<string[]> {
|
|
262
|
+
return this.cache.ls().then((results: Record<string,any>) => Object.keys(results))
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Get encrypted cache operations interface
|
|
267
|
+
* Requires encryption to be enabled and a secret to be provided
|
|
268
|
+
* @returns Object with encrypted get/set operations
|
|
269
|
+
* @throws Error if encryption is not enabled or no secret is provided
|
|
270
|
+
* @example
|
|
271
|
+
* ```typescript
|
|
272
|
+
* // Initialize with encryption
|
|
273
|
+
* const cache = container.feature('diskCache', {
|
|
274
|
+
* encrypt: true,
|
|
275
|
+
* secret: Buffer.from('my-secret-key')
|
|
276
|
+
* })
|
|
277
|
+
*
|
|
278
|
+
* // Use encrypted operations
|
|
279
|
+
* await cache.securely.set('sensitive', 'secret data')
|
|
280
|
+
* const decrypted = await cache.securely.get('sensitive')
|
|
281
|
+
* ```
|
|
282
|
+
*/
|
|
283
|
+
get securely() {
|
|
284
|
+
const { secret, encrypt } = this.options
|
|
285
|
+
|
|
286
|
+
if (!encrypt) {
|
|
287
|
+
throw new Error(`Cannot use securely without encryption enabled`)
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
if (!secret) {
|
|
291
|
+
throw new Error(`Cannot use securely without a secret`)
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const vault = this.container.feature('vault', {
|
|
295
|
+
secret
|
|
296
|
+
})
|
|
297
|
+
|
|
298
|
+
const { cache } = this
|
|
299
|
+
|
|
300
|
+
return {
|
|
301
|
+
/**
|
|
302
|
+
* Store an encrypted value in the cache
|
|
303
|
+
* @param name - The cache key
|
|
304
|
+
* @param payload - The data to encrypt and store
|
|
305
|
+
* @param meta - Optional metadata (will also be encrypted)
|
|
306
|
+
* @returns Promise that resolves when stored
|
|
307
|
+
*/
|
|
308
|
+
async set(name: string, payload: any, meta?: any) {
|
|
309
|
+
const encrypted = vault.encrypt(payload)
|
|
310
|
+
return cache.put(name, Buffer.from(encrypted), {
|
|
311
|
+
...(meta && { metadata: {
|
|
312
|
+
encrypted: vault.encrypt(JSON.stringify(meta))
|
|
313
|
+
}})
|
|
314
|
+
})
|
|
315
|
+
},
|
|
316
|
+
/**
|
|
317
|
+
* Retrieve and decrypt a value from the cache
|
|
318
|
+
* @param name - The cache key
|
|
319
|
+
* @returns Promise that resolves to the decrypted data
|
|
320
|
+
*/
|
|
321
|
+
async get(name: string) {
|
|
322
|
+
const value = await cache.get(name).then((data: any) => data.data.toString())
|
|
323
|
+
return vault.decrypt(value)
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
_cache!: ReturnType<typeof this.create>
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Create a cacache instance with the specified path
|
|
332
|
+
* @param path - Optional cache directory path (defaults to options.path or node_modules/.cache/luca-disk-cache)
|
|
333
|
+
* @returns Configured cacache instance with all methods bound to the path
|
|
334
|
+
* @example
|
|
335
|
+
* ```typescript
|
|
336
|
+
* const customCache = diskCache.create('/custom/cache/path')
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
create(path?: string) {
|
|
340
|
+
path = path || this.options.path || this.container.paths.resolve('node_modules', '.cache', 'luca-disk-cache')
|
|
341
|
+
this.container.fs.ensureFolder(path)
|
|
342
|
+
const arg = (fn: (...args: any) => any) => partial(fn, path);
|
|
343
|
+
|
|
344
|
+
const ls = arg(cacache.ls);
|
|
345
|
+
const get = arg(cacache.get);
|
|
346
|
+
const put = arg(cacache.put);
|
|
347
|
+
const rm = arg(cacache.rm);
|
|
348
|
+
const verify = arg(cacache.verify);
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
...cacache,
|
|
352
|
+
cachePath: path,
|
|
353
|
+
ls: Object.assign(ls, {
|
|
354
|
+
stream: arg(cacache.ls.stream),
|
|
355
|
+
}),
|
|
356
|
+
get: Object.assign(get, {
|
|
357
|
+
stream: arg(cacache.get.stream),
|
|
358
|
+
byDigest: arg(cacache.get.byDigest),
|
|
359
|
+
copy: arg(cacache.get.copy),
|
|
360
|
+
info: arg(cacache.get.info),
|
|
361
|
+
hasContent: arg(cacache.get.hasContent),
|
|
362
|
+
}),
|
|
363
|
+
put: Object.assign(put, {
|
|
364
|
+
stream: arg(cacache.put.stream),
|
|
365
|
+
}),
|
|
366
|
+
rm: Object.assign(rm, {
|
|
367
|
+
all: arg(cacache.rm.all),
|
|
368
|
+
entry: arg(cacache.rm.entry),
|
|
369
|
+
content: arg(cacache.rm.content),
|
|
370
|
+
}),
|
|
371
|
+
tmp: {
|
|
372
|
+
mkdir: arg(cacache.tmp.mkdir),
|
|
373
|
+
withTmp: arg(cacache.tmp.withTmp),
|
|
374
|
+
},
|
|
375
|
+
verify: Object.assign(verify, {
|
|
376
|
+
lastRun: arg(cacache.verify.lastRun),
|
|
377
|
+
}),
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export default features.register("diskCache", DiskCache);
|