@camstack/system 1.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/dist/addon/addon-api-factory.d.ts +35 -0
- package/dist/addon-routes/addon-route-registry.d.ts +37 -0
- package/dist/addon-runner.js +599 -0
- package/dist/addon-runner.mjs +597 -0
- package/dist/auth/api-key-manager.d.ts +26 -0
- package/dist/auth/auth-manager.d.ts +109 -0
- package/dist/auth/parse-record.d.ts +18 -0
- package/dist/auth/scope-matcher.d.ts +7 -0
- package/dist/auth/scoped-token-manager.d.ts +40 -0
- package/dist/auth/totp-manager.d.ts +51 -0
- package/dist/auth/user-manager.d.ts +34 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.d.ts +53 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.js +259 -0
- package/dist/builtins/addon-pages-aggregator/addon-pages-aggregator.addon.mjs +251 -0
- package/dist/builtins/addon-pages-aggregator/dedupe-pages.d.ts +6 -0
- package/dist/builtins/addon-pages-aggregator/index.d.ts +1 -0
- package/dist/builtins/addon-pages-aggregator/index.js +8 -0
- package/dist/builtins/addon-pages-aggregator/index.mjs +2 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.d.ts +47 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.js +228 -0
- package/dist/builtins/addon-widgets-aggregator/addon-widgets-aggregator.addon.mjs +220 -0
- package/dist/builtins/addon-widgets-aggregator/index.d.ts +1 -0
- package/dist/builtins/addon-widgets-aggregator/index.js +8 -0
- package/dist/builtins/addon-widgets-aggregator/index.mjs +2 -0
- package/dist/builtins/alerts/alerts.addon.d.ts +81 -0
- package/dist/builtins/alerts/alerts.addon.js +601 -0
- package/dist/builtins/alerts/alerts.addon.mjs +595 -0
- package/dist/builtins/alerts/index.d.ts +1 -0
- package/dist/builtins/alerts/index.js +4 -0
- package/dist/builtins/alerts/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.d.ts +147 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.js +2229 -0
- package/dist/builtins/backup-orchestrator/backup-orchestrator.addon.mjs +2220 -0
- package/dist/builtins/backup-orchestrator/cron-helpers.d.ts +23 -0
- package/dist/builtins/backup-orchestrator/destination-policy.d.ts +72 -0
- package/dist/builtins/backup-orchestrator/download-helpers.d.ts +12 -0
- package/dist/builtins/backup-orchestrator/index.d.ts +2 -0
- package/dist/builtins/backup-orchestrator/index.js +8 -0
- package/dist/builtins/backup-orchestrator/index.mjs +2 -0
- package/dist/builtins/backup-orchestrator/manifest-store.d.ts +77 -0
- package/dist/builtins/console-logging/console-destination.d.ts +13 -0
- package/dist/builtins/console-logging/console-logging.addon.d.ts +25 -0
- package/dist/builtins/console-logging/index.d.ts +3 -0
- package/dist/builtins/console-logging/index.js +104 -0
- package/dist/builtins/console-logging/index.mjs +95 -0
- package/dist/builtins/device-manager/device-config-contribution.d.ts +32 -0
- package/dist/builtins/device-manager/device-event-propagator.d.ts +26 -0
- package/dist/builtins/device-manager/device-link-overlay.d.ts +23 -0
- package/dist/builtins/device-manager/device-link-resolver.d.ts +15 -0
- package/dist/builtins/device-manager/device-manager.addon.d.ts +452 -0
- package/dist/builtins/device-manager/device-manager.addon.js +3299 -0
- package/dist/builtins/device-manager/device-manager.addon.mjs +3292 -0
- package/dist/builtins/device-manager/index.d.ts +2 -0
- package/dist/builtins/device-manager/index.js +8 -0
- package/dist/builtins/device-manager/index.mjs +2 -0
- package/dist/builtins/hub-forwarder/hub-forwarder-destination.d.ts +44 -0
- package/dist/builtins/hub-forwarder/hub-forwarder.addon.d.ts +15 -0
- package/dist/builtins/hub-forwarder/index.d.ts +3 -0
- package/dist/builtins/hub-forwarder/index.js +154 -0
- package/dist/builtins/hub-forwarder/index.mjs +145 -0
- package/dist/builtins/local-auth/auth-schema.d.ts +26 -0
- package/dist/builtins/local-auth/index.d.ts +1 -0
- package/dist/builtins/local-auth/index.js +4 -0
- package/dist/builtins/local-auth/index.mjs +2 -0
- package/dist/builtins/local-auth/local-auth.addon.d.ts +18 -0
- package/dist/builtins/local-auth/local-auth.addon.js +8094 -0
- package/dist/builtins/local-auth/local-auth.addon.mjs +8063 -0
- package/dist/builtins/local-auth/oauth-grants.d.ts +45 -0
- package/dist/builtins/local-auth/oauth-session-manager.d.ts +50 -0
- package/dist/builtins/local-network/index.d.ts +2 -0
- package/dist/builtins/local-network/index.js +10 -0
- package/dist/builtins/local-network/index.mjs +2 -0
- package/dist/builtins/local-network/local-network.addon.d.ts +150 -0
- package/dist/builtins/local-network/local-network.addon.js +489 -0
- package/dist/builtins/local-network/local-network.addon.mjs +477 -0
- package/dist/builtins/native-metrics/index.d.ts +2 -0
- package/dist/builtins/native-metrics/native-metrics-provider.d.ts +48 -0
- package/dist/builtins/native-metrics/native-metrics.addon.d.ts +73 -0
- package/dist/builtins/native-metrics/native-metrics.addon.js +922 -0
- package/dist/builtins/native-metrics/native-metrics.addon.mjs +914 -0
- package/dist/builtins/platform-probe/hardware-decode-accel-probe.d.ts +37 -0
- package/dist/builtins/platform-probe/hardware-encoder-probe.d.ts +13 -0
- package/dist/builtins/platform-probe/index.d.ts +22 -0
- package/dist/builtins/platform-probe/index.js +834 -0
- package/dist/builtins/platform-probe/index.mjs +822 -0
- package/dist/builtins/platform-probe/inference-config-resolver.d.ts +29 -0
- package/dist/builtins/platform-probe/intel-accelerators.d.ts +11 -0
- package/dist/builtins/platform-probe/platform-scorer.d.ts +30 -0
- package/dist/builtins/platform-probe/runtime-packages.d.ts +6 -0
- package/dist/builtins/remote-access-orchestrator/enabled-providers-reconcile.d.ts +96 -0
- package/dist/builtins/remote-access-orchestrator/index.d.ts +1 -0
- package/dist/builtins/remote-access-orchestrator/index.js +8 -0
- package/dist/builtins/remote-access-orchestrator/index.mjs +2 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.d.ts +40 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.js +214 -0
- package/dist/builtins/remote-access-orchestrator/remote-access-orchestrator.addon.mjs +208 -0
- package/dist/builtins/shared/settle-sources.d.ts +22 -0
- package/dist/builtins/snapshot/index.d.ts +2 -0
- package/dist/builtins/snapshot/index.js +494 -0
- package/dist/builtins/snapshot/index.mjs +488 -0
- package/dist/builtins/snapshot/snapshot.addon.d.ts +120 -0
- package/dist/builtins/sqlite-storage/config-store.d.ts +8 -0
- package/dist/builtins/sqlite-storage/device-store.d.ts +23 -0
- package/dist/builtins/sqlite-storage/filesystem-browse-provider.d.ts +25 -0
- package/dist/builtins/sqlite-storage/filesystem-storage-provider.d.ts +83 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.d.ts +32 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.js +396 -0
- package/dist/builtins/sqlite-storage/filesystem-storage.addon.mjs +388 -0
- package/dist/builtins/sqlite-storage/index.d.ts +8 -0
- package/dist/builtins/sqlite-storage/index.js +62 -0
- package/dist/builtins/sqlite-storage/index.mjs +49 -0
- package/dist/builtins/sqlite-storage/integration-registry.d.ts +27 -0
- package/dist/builtins/sqlite-storage/path-guard.d.ts +4 -0
- package/dist/builtins/sqlite-storage/sqlite-settings-backend.d.ts +102 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.d.ts +14 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.js +644 -0
- package/dist/builtins/sqlite-storage/sqlite-settings.addon.mjs +636 -0
- package/dist/builtins/storage-orchestrator/index.d.ts +6 -0
- package/dist/builtins/storage-orchestrator/index.js +10 -0
- package/dist/builtins/storage-orchestrator/index.mjs +2 -0
- package/dist/builtins/storage-orchestrator/location-store.d.ts +49 -0
- package/dist/builtins/storage-orchestrator/provider-discovery.d.ts +10 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.d.ts +103 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.js +1138 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.addon.mjs +1128 -0
- package/dist/builtins/storage-orchestrator/storage-orchestrator.service.d.ts +236 -0
- package/dist/builtins/storage-orchestrator/storage-pressure-manager.d.ts +38 -0
- package/dist/builtins/system-backup/system-backup.service.d.ts +137 -0
- package/dist/builtins/system-config/index.d.ts +1 -0
- package/dist/builtins/system-config/index.js +8 -0
- package/dist/builtins/system-config/index.mjs +2 -0
- package/dist/builtins/system-config/system-config.addon.d.ts +10 -0
- package/dist/builtins/system-config/system-config.addon.js +232 -0
- package/dist/builtins/system-config/system-config.addon.mjs +226 -0
- package/dist/builtins/winston-logging/index.d.ts +3 -0
- package/dist/builtins/winston-logging/index.js +156 -0
- package/dist/builtins/winston-logging/index.mjs +144 -0
- package/dist/builtins/winston-logging/winston-destination.d.ts +21 -0
- package/dist/builtins/winston-logging/winston-logging.addon.d.ts +19 -0
- package/dist/chunk-CNf5ZN-e.mjs +37 -0
- package/dist/chunk-Cek0wNdY.js +64 -0
- package/dist/download/model-download-service.d.ts +41 -0
- package/dist/download/model-downloader.d.ts +31 -0
- package/dist/events/event-bus.d.ts +10 -0
- package/dist/events/system-event-bus.d.ts +14 -0
- package/dist/feature/feature-manager.d.ts +11 -0
- package/dist/formatter-B7qW8bPJ.mjs +162 -0
- package/dist/formatter-DqAKDlvN.js +167 -0
- package/dist/http/authenticated-file-server.d.ts +53 -0
- package/dist/http/data-plane-registry.d.ts +23 -0
- package/dist/http/file-data-plane.d.ts +10 -0
- package/dist/http/reverse-proxy.d.ts +15 -0
- package/dist/index.d.ts +82 -0
- package/dist/index.js +93485 -0
- package/dist/index.mjs +93179 -0
- package/dist/intel-accelerators-Gg0P5mnl.js +20 -0
- package/dist/intel-accelerators-hGgpZ0pX.mjs +19 -0
- package/dist/kernel/addon-class-resolver.d.ts +4 -0
- package/dist/kernel/addon-engine-manager.d.ts +22 -0
- package/dist/kernel/addon-health-monitor.d.ts +154 -0
- package/dist/kernel/addon-installer.d.ts +208 -0
- package/dist/kernel/addon-loader.d.ts +106 -0
- package/dist/kernel/addon-manifest.d.ts +77 -0
- package/dist/kernel/capability-handle.d.ts +46 -0
- package/dist/kernel/capability-registry.d.ts +412 -0
- package/dist/kernel/config-manager.d.ts +212 -0
- package/dist/kernel/config-schema.d.ts +93 -0
- package/dist/kernel/custom-action-registry.d.ts +23 -0
- package/dist/kernel/deps/addon-deps-manager.d.ts +19 -0
- package/dist/kernel/deps/manifest-native-deps.d.ts +25 -0
- package/dist/kernel/deps/manifest-python-deps.d.ts +20 -0
- package/dist/kernel/device-registry.d.ts +29 -0
- package/dist/kernel/fs-utils.d.ts +41 -0
- package/dist/kernel/hwaccel/hwaccel-resolver.d.ts +19 -0
- package/dist/kernel/hwaccel/hwaccel-service.d.ts +4 -0
- package/dist/kernel/index.d.ts +74 -0
- package/dist/kernel/infra-capabilities.d.ts +13 -0
- package/dist/kernel/moleculer/addon-context-factory.d.ts +91 -0
- package/dist/kernel/moleculer/addon-data-plane-facility.d.ts +19 -0
- package/dist/kernel/moleculer/addon-runner.d.ts +1 -0
- package/dist/kernel/moleculer/addon-service-factory.d.ts +50 -0
- package/dist/kernel/moleculer/broker-factory.d.ts +50 -0
- package/dist/kernel/moleculer/cap-usage-registry.d.ts +46 -0
- package/dist/kernel/moleculer/capabilities-access.d.ts +21 -0
- package/dist/kernel/moleculer/child-addon-call-dispatch.d.ts +46 -0
- package/dist/kernel/moleculer/child-cap-dispatch.d.ts +20 -0
- package/dist/kernel/moleculer/cluster-secret.d.ts +15 -0
- package/dist/kernel/moleculer/core-cap-service.d.ts +50 -0
- package/dist/kernel/moleculer/crash-supervisor.d.ts +50 -0
- package/dist/kernel/moleculer/device-cap-proxy.d.ts +79 -0
- package/dist/kernel/moleculer/event-bus-core.d.ts +53 -0
- package/dist/kernel/moleculer/event-bus.d.ts +53 -0
- package/dist/kernel/moleculer/hub-log-forwarder.d.ts +36 -0
- package/dist/kernel/moleculer/hub-service.d.ts +35 -0
- package/dist/kernel/moleculer/node-registry.d.ts +126 -0
- package/dist/kernel/moleculer/process-context.d.ts +4 -0
- package/dist/kernel/moleculer/process-service.d.ts +72 -0
- package/dist/kernel/moleculer/provider-registry.d.ts +28 -0
- package/dist/kernel/moleculer/readiness-context.d.ts +62 -0
- package/dist/kernel/moleculer/readiness-service.d.ts +7 -0
- package/dist/kernel/moleculer/register-node-client.d.ts +35 -0
- package/dist/kernel/moleculer/remote-logger.d.ts +43 -0
- package/dist/kernel/moleculer/resilient-cap-call.d.ts +28 -0
- package/dist/kernel/moleculer/stream-probe-service.d.ts +9 -0
- package/dist/kernel/moleculer/trpc-links.d.ts +189 -0
- package/dist/kernel/moleculer/typed-array-serde.d.ts +25 -0
- package/dist/kernel/moleculer/worker-device-restore.d.ts +10 -0
- package/dist/kernel/provider-kind-drift.d.ts +12 -0
- package/dist/kernel/restart-coordinator.d.ts +90 -0
- package/dist/kernel/storage-location-registry.d.ts +40 -0
- package/dist/kernel/transport/cap-action-name.d.ts +100 -0
- package/dist/kernel/transport/cap-route-resolver.d.ts +148 -0
- package/dist/kernel/transport/cap-route.d.ts +148 -0
- package/dist/kernel/transport/child-cap-protocol.d.ts +136 -0
- package/dist/kernel/transport/create-local-transport.d.ts +7 -0
- package/dist/kernel/transport/frame-codec.d.ts +7 -0
- package/dist/kernel/transport/index.d.ts +27 -0
- package/dist/kernel/transport/local-child-client.d.ts +136 -0
- package/dist/kernel/transport/local-child-registry.d.ts +179 -0
- package/dist/kernel/transport/local-endpoint-path.d.ts +6 -0
- package/dist/kernel/transport/local-transport.d.ts +46 -0
- package/dist/kernel/transport/parent-unowned-call.d.ts +75 -0
- package/dist/kernel/transport/socket-channel.d.ts +27 -0
- package/dist/kernel/transport/uds-event-bridge.d.ts +36 -0
- package/dist/kernel/transport/uds-event-bus.d.ts +22 -0
- package/dist/kernel/transport/uds-local-transport.d.ts +18 -0
- package/dist/kernel/transport/uds-log-ingest.d.ts +28 -0
- package/dist/kernel/transport/uds-logger.d.ts +44 -0
- package/dist/kernel/utils/ring-buffer.d.ts +15 -0
- package/dist/kernel/workspace-detect.d.ts +9 -0
- package/dist/lifecycle/lifecycle-state-machine.d.ts +28 -0
- package/dist/logging/formatter.d.ts +30 -0
- package/dist/logging/log-manager.d.ts +54 -0
- package/dist/logging/log-ring-buffer.d.ts +47 -0
- package/dist/logging/partitioned-log-buffer.d.ts +35 -0
- package/dist/logging/scoped-logger.d.ts +17 -0
- package/dist/main-DNnMW7Z2.js +9983 -0
- package/dist/main-rtjOwPBR.mjs +9976 -0
- package/dist/manifest-python-deps-D1DbAQEv.js +6724 -0
- package/dist/manifest-python-deps-DZsKTbs1.mjs +6315 -0
- package/dist/network/network-quality.d.ts +11 -0
- package/dist/notification/notification-service.d.ts +37 -0
- package/dist/notification/toast-service.d.ts +22 -0
- package/dist/pipeline/engine-manager-resolver.d.ts +15 -0
- package/dist/pipeline/pipeline-runner.d.ts +8 -0
- package/dist/pipeline/pipeline-validator.d.ts +13 -0
- package/dist/process/resource-monitor.d.ts +11 -0
- package/dist/python/python-env-manager.d.ts +12 -0
- package/dist/repl/interfaces.d.ts +31 -0
- package/dist/repl/repl-engine.d.ts +8 -0
- package/dist/resource-monitor-ClDGFyf6.mjs +57 -0
- package/dist/resource-monitor-IIEanuJt.js +74 -0
- package/dist/settle-sources-Bhsy57y-.js +38 -0
- package/dist/settle-sources-CDtNC8ub.mjs +33 -0
- package/dist/storage/fs-storage-backend.d.ts +40 -0
- package/dist/storage/storage-location-manager.d.ts +23 -0
- package/dist/storage/storage-manager.d.ts +83 -0
- package/dist/tar-BgAEMRBR.js +5434 -0
- package/dist/tar-ByMOPNM0.mjs +5429 -0
- package/dist/tls/cert-manager.d.ts +26 -0
- package/dist/tls/index.d.ts +1 -0
- package/package.json +343 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { IStorageProviderImpl, StorageLocation, StorageProviderInfoSchema } from '@camstack/types';
|
|
3
|
+
type StorageProviderInfo = z.infer<typeof StorageProviderInfoSchema>;
|
|
4
|
+
export declare class FilesystemStorageProvider implements IStorageProviderImpl {
|
|
5
|
+
static readonly providerId = "filesystem-storage";
|
|
6
|
+
static readonly displayName = "Filesystem";
|
|
7
|
+
private readonly uploads;
|
|
8
|
+
private readonly downloads;
|
|
9
|
+
getProviderInfo(): Promise<StorageProviderInfo>;
|
|
10
|
+
testLocation({ config }: {
|
|
11
|
+
readonly config: Record<string, unknown>;
|
|
12
|
+
}): Promise<{
|
|
13
|
+
readonly ok: boolean;
|
|
14
|
+
readonly error?: string;
|
|
15
|
+
}>;
|
|
16
|
+
resolve({ location, relativePath, }: {
|
|
17
|
+
readonly location: StorageLocation;
|
|
18
|
+
readonly relativePath: string;
|
|
19
|
+
}): Promise<string>;
|
|
20
|
+
write({ location, relativePath, data, }: {
|
|
21
|
+
readonly location: StorageLocation;
|
|
22
|
+
readonly relativePath: string;
|
|
23
|
+
readonly data: Uint8Array;
|
|
24
|
+
}): Promise<void>;
|
|
25
|
+
read({ location, relativePath, }: {
|
|
26
|
+
readonly location: StorageLocation;
|
|
27
|
+
readonly relativePath: string;
|
|
28
|
+
}): Promise<Uint8Array<ArrayBuffer>>;
|
|
29
|
+
exists({ location, relativePath, }: {
|
|
30
|
+
readonly location: StorageLocation;
|
|
31
|
+
readonly relativePath: string;
|
|
32
|
+
}): Promise<boolean>;
|
|
33
|
+
list({ location, prefix, }: {
|
|
34
|
+
readonly location: StorageLocation;
|
|
35
|
+
readonly prefix?: string;
|
|
36
|
+
}): Promise<readonly string[]>;
|
|
37
|
+
delete({ location, relativePath, }: {
|
|
38
|
+
readonly location: StorageLocation;
|
|
39
|
+
readonly relativePath: string;
|
|
40
|
+
}): Promise<void>;
|
|
41
|
+
getAvailableSpace({ location, }: {
|
|
42
|
+
readonly location: StorageLocation;
|
|
43
|
+
}): Promise<number | null>;
|
|
44
|
+
beginUpload({ location, relativePath, }: {
|
|
45
|
+
readonly location: StorageLocation;
|
|
46
|
+
readonly relativePath: string;
|
|
47
|
+
readonly sizeBytes?: number;
|
|
48
|
+
}): Promise<{
|
|
49
|
+
readonly uploadId: string;
|
|
50
|
+
}>;
|
|
51
|
+
writeChunk({ uploadId, offset, data, }: {
|
|
52
|
+
readonly uploadId: string;
|
|
53
|
+
readonly offset: number;
|
|
54
|
+
readonly data: Uint8Array;
|
|
55
|
+
}): Promise<void>;
|
|
56
|
+
finalizeUpload({ uploadId }: {
|
|
57
|
+
readonly uploadId: string;
|
|
58
|
+
}): Promise<void>;
|
|
59
|
+
abortUpload({ uploadId }: {
|
|
60
|
+
readonly uploadId: string;
|
|
61
|
+
}): Promise<void>;
|
|
62
|
+
beginDownload({ location, relativePath, }: {
|
|
63
|
+
readonly location: StorageLocation;
|
|
64
|
+
readonly relativePath: string;
|
|
65
|
+
}): Promise<{
|
|
66
|
+
readonly downloadId: string;
|
|
67
|
+
readonly sizeBytes: number;
|
|
68
|
+
}>;
|
|
69
|
+
readChunk({ downloadId, offset, length, }: {
|
|
70
|
+
readonly downloadId: string;
|
|
71
|
+
readonly offset: number;
|
|
72
|
+
readonly length: number;
|
|
73
|
+
}): Promise<Uint8Array<ArrayBuffer>>;
|
|
74
|
+
endDownload({ downloadId }: {
|
|
75
|
+
readonly downloadId: string;
|
|
76
|
+
}): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Abort all outstanding sessions. Called on addon shutdown so timers
|
|
79
|
+
* don't leak across hot-reload cycles.
|
|
80
|
+
*/
|
|
81
|
+
dispose(): Promise<void>;
|
|
82
|
+
}
|
|
83
|
+
export default FilesystemStorageProvider;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ProviderRegistration, BaseAddon } from '@camstack/types';
|
|
2
|
+
import { FilesystemStorageProvider } from './filesystem-storage-provider.js';
|
|
3
|
+
interface FilesystemStorageConfig {
|
|
4
|
+
readonly rootPath: string;
|
|
5
|
+
readonly storageAllowedRoots: readonly string[];
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Filesystem Storage addon — registers a filesystem-backed
|
|
9
|
+
* `storage-provider` (Task 7).
|
|
10
|
+
*
|
|
11
|
+
* Pre-Task 7 this addon registered against the (then-collection)
|
|
12
|
+
* `storage` cap. After Tasks 2/3/4 the consumer-facing `storage` cap is
|
|
13
|
+
* a singleton owned by `storage-orchestrator`; the orchestrator
|
|
14
|
+
* dispatches each call to whichever `storage-provider` matches
|
|
15
|
+
* `location.providerId`.
|
|
16
|
+
*
|
|
17
|
+
* The OLD `rootPath` config field is preserved for back-compat: the
|
|
18
|
+
* orchestrator's first-boot seeding step still uses the same env-var
|
|
19
|
+
* resolution chain (operator override → `CAMSTACK_DATA` → fallback) to
|
|
20
|
+
* derive the base path of every default location, then writes
|
|
21
|
+
* `config.basePath` into each persisted `StorageLocation` row. The
|
|
22
|
+
* provider itself is now stateless — every call carries the live
|
|
23
|
+
* `StorageLocation` inline.
|
|
24
|
+
*/
|
|
25
|
+
export declare class FilesystemStorageAddon extends BaseAddon<FilesystemStorageConfig> {
|
|
26
|
+
private provider;
|
|
27
|
+
constructor();
|
|
28
|
+
protected onInitialize(): Promise<ProviderRegistration[]>;
|
|
29
|
+
protected onShutdown(): Promise<void>;
|
|
30
|
+
getProvider(): FilesystemStorageProvider | null;
|
|
31
|
+
}
|
|
32
|
+
export default FilesystemStorageAddon;
|
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
6
|
+
let node_fs = require("node:fs");
|
|
7
|
+
node_fs = require_chunk.__toESM(node_fs);
|
|
8
|
+
let node_path = require("node:path");
|
|
9
|
+
node_path = require_chunk.__toESM(node_path);
|
|
10
|
+
let _camstack_types = require("@camstack/types");
|
|
11
|
+
let node_crypto = require("node:crypto");
|
|
12
|
+
let node_os = require("node:os");
|
|
13
|
+
let node_fs_promises = require("node:fs/promises");
|
|
14
|
+
//#region src/builtins/sqlite-storage/filesystem-storage-provider.ts
|
|
15
|
+
/**
|
|
16
|
+
* Filesystem `storage-provider` (Task 7).
|
|
17
|
+
*
|
|
18
|
+
* Implements the `storage-provider` collection cap. Replaces the legacy
|
|
19
|
+
* sync `IStorageProvider` shape — every method now takes the live
|
|
20
|
+
* `StorageLocation` inline (no per-provider location state) and works
|
|
21
|
+
* off `location.config.basePath`.
|
|
22
|
+
*
|
|
23
|
+
* Adds chunked upload (`.partial` rename trick) + chunked download
|
|
24
|
+
* sessions for moving multi-GB archives without buffering the whole
|
|
25
|
+
* archive in memory. Sessions auto-expire after 5 minutes idle.
|
|
26
|
+
*
|
|
27
|
+
* The legacy `FilesystemStorageProvider` in `@camstack/types/node` is
|
|
28
|
+
* deliberately untouched — it still backs the sync `ctx.kernel.storage`
|
|
29
|
+
* helper that addons like `pipeline-analytics` use to derive paths
|
|
30
|
+
* synchronously. That sync API will be retired in a later refactor;
|
|
31
|
+
* Task 7 is scoped to the cap surface only.
|
|
32
|
+
*/
|
|
33
|
+
/** Idle TTL for upload + download sessions. */
|
|
34
|
+
var SESSION_IDLE_TTL_MS = 300 * 1e3;
|
|
35
|
+
/**
|
|
36
|
+
* Resolve `location.config.basePath` into a string. Throws an actionable
|
|
37
|
+
* error when the field is missing or wrong-typed — every primitive
|
|
38
|
+
* funnels through here, so a missing field surfaces as a single clear
|
|
39
|
+
* message instead of a downstream `path.join` TypeError.
|
|
40
|
+
*/
|
|
41
|
+
function getBasePath(location) {
|
|
42
|
+
const basePath = location.config["basePath"];
|
|
43
|
+
if (typeof basePath !== "string" || basePath.length === 0) throw new Error(`filesystem-storage: location "${location.id}" missing string config.basePath`);
|
|
44
|
+
return basePath;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Resolve a relative path against the location's base, rejecting any
|
|
48
|
+
* traversal that escapes the base directory. Mirrors the
|
|
49
|
+
* `addon-asset` endpoint security check in `main.ts`: normalize both
|
|
50
|
+
* the base + the joined target, then enforce `target.startsWith(base + sep)`
|
|
51
|
+
* (with the `+ sep` guard so `/data` doesn't accidentally allow
|
|
52
|
+
* `/datasecret`).
|
|
53
|
+
*/
|
|
54
|
+
function safeResolve(base, relativePath) {
|
|
55
|
+
const normalizedBase = node_path.resolve(base);
|
|
56
|
+
const target = node_path.resolve(normalizedBase, relativePath);
|
|
57
|
+
if (target !== normalizedBase && !target.startsWith(normalizedBase + node_path.sep)) throw new Error(`filesystem-storage: relativePath "${relativePath}" escapes basePath "${normalizedBase}"`);
|
|
58
|
+
return target;
|
|
59
|
+
}
|
|
60
|
+
var FilesystemStorageProvider = class FilesystemStorageProvider {
|
|
61
|
+
static providerId = "filesystem-storage";
|
|
62
|
+
static displayName = "Filesystem";
|
|
63
|
+
uploads = /* @__PURE__ */ new Map();
|
|
64
|
+
downloads = /* @__PURE__ */ new Map();
|
|
65
|
+
async getProviderInfo() {
|
|
66
|
+
return {
|
|
67
|
+
providerId: FilesystemStorageProvider.providerId,
|
|
68
|
+
displayName: FilesystemStorageProvider.displayName,
|
|
69
|
+
shouldSaveDiskSpace: true,
|
|
70
|
+
minFreePercent: 10,
|
|
71
|
+
nodeLocal: true,
|
|
72
|
+
configSchema: { sections: [{
|
|
73
|
+
id: "filesystem-storage",
|
|
74
|
+
title: "Filesystem",
|
|
75
|
+
fields: [{
|
|
76
|
+
type: "text",
|
|
77
|
+
key: "basePath",
|
|
78
|
+
label: "Base path",
|
|
79
|
+
description: "Absolute directory path where files are stored.",
|
|
80
|
+
required: true
|
|
81
|
+
}]
|
|
82
|
+
}] }
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async testLocation({ config }) {
|
|
86
|
+
const basePath = config["basePath"];
|
|
87
|
+
if (typeof basePath !== "string" || basePath.length === 0) return {
|
|
88
|
+
ok: false,
|
|
89
|
+
error: "config.basePath must be a non-empty string"
|
|
90
|
+
};
|
|
91
|
+
try {
|
|
92
|
+
const stat = await node_fs.promises.stat(basePath).catch(() => null);
|
|
93
|
+
if (stat) {
|
|
94
|
+
if (!stat.isDirectory()) return {
|
|
95
|
+
ok: false,
|
|
96
|
+
error: `Path "${basePath}" exists but is not a directory`
|
|
97
|
+
};
|
|
98
|
+
await node_fs.promises.access(basePath, node_fs.constants.W_OK);
|
|
99
|
+
return { ok: true };
|
|
100
|
+
}
|
|
101
|
+
await node_fs.promises.mkdir(basePath, { recursive: true });
|
|
102
|
+
return { ok: true };
|
|
103
|
+
} catch (err) {
|
|
104
|
+
return {
|
|
105
|
+
ok: false,
|
|
106
|
+
error: err instanceof Error ? err.message : String(err)
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
async resolve({ location, relativePath }) {
|
|
111
|
+
return safeResolve(getBasePath(location), relativePath);
|
|
112
|
+
}
|
|
113
|
+
async write({ location, relativePath, data }) {
|
|
114
|
+
const filePath = safeResolve(getBasePath(location), relativePath);
|
|
115
|
+
await node_fs.promises.mkdir(node_path.dirname(filePath), { recursive: true });
|
|
116
|
+
await node_fs.promises.writeFile(filePath, data);
|
|
117
|
+
}
|
|
118
|
+
async read({ location, relativePath }) {
|
|
119
|
+
const filePath = safeResolve(getBasePath(location), relativePath);
|
|
120
|
+
const buf = await node_fs.promises.readFile(filePath);
|
|
121
|
+
const out = new Uint8Array(new ArrayBuffer(buf.byteLength));
|
|
122
|
+
out.set(buf);
|
|
123
|
+
return out;
|
|
124
|
+
}
|
|
125
|
+
async exists({ location, relativePath }) {
|
|
126
|
+
const filePath = safeResolve(getBasePath(location), relativePath);
|
|
127
|
+
try {
|
|
128
|
+
await node_fs.promises.access(filePath);
|
|
129
|
+
return true;
|
|
130
|
+
} catch {
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
async list({ location, prefix }) {
|
|
135
|
+
const base = getBasePath(location);
|
|
136
|
+
const dir = prefix ? safeResolve(base, prefix) : node_path.resolve(base);
|
|
137
|
+
try {
|
|
138
|
+
return (await node_fs.promises.readdir(dir, { withFileTypes: true })).map((e) => prefix ? `${prefix}/${e.name}` : e.name);
|
|
139
|
+
} catch {
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
async delete({ location, relativePath }) {
|
|
144
|
+
const filePath = safeResolve(getBasePath(location), relativePath);
|
|
145
|
+
await node_fs.promises.rm(filePath, { force: true });
|
|
146
|
+
}
|
|
147
|
+
async getAvailableSpace({ location }) {
|
|
148
|
+
const base = node_path.resolve(getBasePath(location));
|
|
149
|
+
try {
|
|
150
|
+
let target = base;
|
|
151
|
+
while (!node_fs.existsSync(target)) {
|
|
152
|
+
const parent = node_path.dirname(target);
|
|
153
|
+
if (!parent || parent === target) return null;
|
|
154
|
+
target = parent;
|
|
155
|
+
}
|
|
156
|
+
const stats = await node_fs.promises.statfs(target);
|
|
157
|
+
return stats.bavail * stats.bsize;
|
|
158
|
+
} catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
async beginUpload({ location, relativePath }) {
|
|
163
|
+
const target = safeResolve(getBasePath(location), relativePath);
|
|
164
|
+
const partial = `${target}.partial`;
|
|
165
|
+
await node_fs.promises.mkdir(node_path.dirname(target), { recursive: true });
|
|
166
|
+
await node_fs.promises.unlink(partial).catch(() => {});
|
|
167
|
+
const stream = node_fs.createWriteStream(partial);
|
|
168
|
+
const uploadId = (0, node_crypto.randomUUID)();
|
|
169
|
+
const session = {
|
|
170
|
+
stream,
|
|
171
|
+
target,
|
|
172
|
+
partial,
|
|
173
|
+
bytesWritten: 0,
|
|
174
|
+
timer: setTimeout(() => {
|
|
175
|
+
this.abortUpload({ uploadId }).catch(() => {});
|
|
176
|
+
}, SESSION_IDLE_TTL_MS)
|
|
177
|
+
};
|
|
178
|
+
this.uploads.set(uploadId, session);
|
|
179
|
+
return { uploadId };
|
|
180
|
+
}
|
|
181
|
+
async writeChunk({ uploadId, offset, data }) {
|
|
182
|
+
const session = this.uploads.get(uploadId);
|
|
183
|
+
if (!session) throw new Error(`filesystem-storage: upload session "${uploadId}" not found`);
|
|
184
|
+
if (offset !== session.bytesWritten) throw new Error(`filesystem-storage: chunk offset mismatch (expected ${session.bytesWritten}, got ${offset})`);
|
|
185
|
+
await new Promise((resolve, reject) => {
|
|
186
|
+
session.stream.write(data, (err) => {
|
|
187
|
+
if (err) reject(err);
|
|
188
|
+
else resolve();
|
|
189
|
+
});
|
|
190
|
+
});
|
|
191
|
+
clearTimeout(session.timer);
|
|
192
|
+
const nextBytesWritten = session.bytesWritten + data.length;
|
|
193
|
+
this.uploads.set(uploadId, {
|
|
194
|
+
...session,
|
|
195
|
+
bytesWritten: nextBytesWritten,
|
|
196
|
+
timer: setTimeout(() => {
|
|
197
|
+
this.abortUpload({ uploadId }).catch(() => {});
|
|
198
|
+
}, SESSION_IDLE_TTL_MS)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
async finalizeUpload({ uploadId }) {
|
|
202
|
+
const session = this.uploads.get(uploadId);
|
|
203
|
+
if (!session) throw new Error(`filesystem-storage: upload session "${uploadId}" not found`);
|
|
204
|
+
await new Promise((resolve, reject) => {
|
|
205
|
+
session.stream.end(() => resolve());
|
|
206
|
+
session.stream.on("error", reject);
|
|
207
|
+
});
|
|
208
|
+
await node_fs.promises.rename(session.partial, session.target);
|
|
209
|
+
clearTimeout(session.timer);
|
|
210
|
+
this.uploads.delete(uploadId);
|
|
211
|
+
}
|
|
212
|
+
async abortUpload({ uploadId }) {
|
|
213
|
+
const session = this.uploads.get(uploadId);
|
|
214
|
+
if (!session) return;
|
|
215
|
+
try {
|
|
216
|
+
session.stream.destroy();
|
|
217
|
+
} catch {}
|
|
218
|
+
await node_fs.promises.unlink(session.partial).catch(() => {});
|
|
219
|
+
clearTimeout(session.timer);
|
|
220
|
+
this.uploads.delete(uploadId);
|
|
221
|
+
}
|
|
222
|
+
async beginDownload({ location, relativePath }) {
|
|
223
|
+
const target = safeResolve(getBasePath(location), relativePath);
|
|
224
|
+
const stat = await node_fs.promises.stat(target);
|
|
225
|
+
const fd = await node_fs.promises.open(target, "r");
|
|
226
|
+
const downloadId = (0, node_crypto.randomUUID)();
|
|
227
|
+
const session = {
|
|
228
|
+
fd,
|
|
229
|
+
sizeBytes: stat.size,
|
|
230
|
+
timer: setTimeout(() => {
|
|
231
|
+
this.endDownload({ downloadId }).catch(() => {});
|
|
232
|
+
}, SESSION_IDLE_TTL_MS)
|
|
233
|
+
};
|
|
234
|
+
this.downloads.set(downloadId, session);
|
|
235
|
+
return {
|
|
236
|
+
downloadId,
|
|
237
|
+
sizeBytes: stat.size
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
async readChunk({ downloadId, offset, length }) {
|
|
241
|
+
const session = this.downloads.get(downloadId);
|
|
242
|
+
if (!session) throw new Error(`filesystem-storage: download session "${downloadId}" not found`);
|
|
243
|
+
const out = new Uint8Array(new ArrayBuffer(length));
|
|
244
|
+
const { bytesRead } = await session.fd.read(out, 0, length, offset);
|
|
245
|
+
clearTimeout(session.timer);
|
|
246
|
+
this.downloads.set(downloadId, {
|
|
247
|
+
...session,
|
|
248
|
+
timer: setTimeout(() => {
|
|
249
|
+
this.endDownload({ downloadId }).catch(() => {});
|
|
250
|
+
}, SESSION_IDLE_TTL_MS)
|
|
251
|
+
});
|
|
252
|
+
return out.subarray(0, bytesRead);
|
|
253
|
+
}
|
|
254
|
+
async endDownload({ downloadId }) {
|
|
255
|
+
const session = this.downloads.get(downloadId);
|
|
256
|
+
if (!session) return;
|
|
257
|
+
try {
|
|
258
|
+
await session.fd.close();
|
|
259
|
+
} catch {}
|
|
260
|
+
clearTimeout(session.timer);
|
|
261
|
+
this.downloads.delete(downloadId);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Abort all outstanding sessions. Called on addon shutdown so timers
|
|
265
|
+
* don't leak across hot-reload cycles.
|
|
266
|
+
*/
|
|
267
|
+
async dispose() {
|
|
268
|
+
const uploadIds = [...this.uploads.keys()];
|
|
269
|
+
const downloadIds = [...this.downloads.keys()];
|
|
270
|
+
await Promise.all(uploadIds.map((uploadId) => this.abortUpload({ uploadId })));
|
|
271
|
+
await Promise.all(downloadIds.map((downloadId) => this.endDownload({ downloadId })));
|
|
272
|
+
}
|
|
273
|
+
};
|
|
274
|
+
//#endregion
|
|
275
|
+
//#region src/builtins/sqlite-storage/path-guard.ts
|
|
276
|
+
/**
|
|
277
|
+
* Allowed-root containment guard for the filesystem-browse cap. Pure +
|
|
278
|
+
* synchronous so it is trivially unit-testable; the provider applies it AFTER
|
|
279
|
+
* resolving the real path (so symlink escapes are also caught upstream).
|
|
280
|
+
*/
|
|
281
|
+
/** True iff `candidate` is one of, or nested under, an allowed root. */
|
|
282
|
+
function isWithinAllowedRoots(candidate, allowedRoots) {
|
|
283
|
+
const norm = (0, node_path.resolve)(candidate);
|
|
284
|
+
return allowedRoots.some((root) => {
|
|
285
|
+
const r = (0, node_path.resolve)(root);
|
|
286
|
+
return norm === r || norm.startsWith(r.endsWith(node_path.sep) ? r : r + node_path.sep);
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
/** Throws unless `candidate` is within an allowed root. */
|
|
290
|
+
function assertWithinAllowedRoots(candidate, allowedRoots) {
|
|
291
|
+
if (!isWithinAllowedRoots(candidate, allowedRoots)) throw new Error(`path "${candidate}" is not within an allowed root`);
|
|
292
|
+
}
|
|
293
|
+
//#endregion
|
|
294
|
+
//#region src/builtins/sqlite-storage/filesystem-browse-provider.ts
|
|
295
|
+
/**
|
|
296
|
+
* Per-node filesystem-browse provider. Lists/creates directories under
|
|
297
|
+
* operator-configured allowed roots only (sandboxed by `path-guard`). Backs the
|
|
298
|
+
* `filesystem-browse` cap so the admin UI can pick a node + path for a
|
|
299
|
+
* node-local storage location.
|
|
300
|
+
*/
|
|
301
|
+
var FilesystemBrowseProvider = class {
|
|
302
|
+
allowedRoots;
|
|
303
|
+
/** allowedRoots is injected (read from addon config) so it stays per-node + testable. */
|
|
304
|
+
constructor(allowedRoots) {
|
|
305
|
+
this.allowedRoots = allowedRoots;
|
|
306
|
+
}
|
|
307
|
+
async listAllowedRoots() {
|
|
308
|
+
return [...this.allowedRoots()];
|
|
309
|
+
}
|
|
310
|
+
async browse({ path }) {
|
|
311
|
+
const real = await (0, node_fs_promises.realpath)(path).catch(() => path);
|
|
312
|
+
assertWithinAllowedRoots(real, await this.resolvedRoots());
|
|
313
|
+
const entries = (await (0, node_fs_promises.readdir)(real, { withFileTypes: true })).filter((d) => d.isDirectory()).map((d) => ({
|
|
314
|
+
name: d.name,
|
|
315
|
+
path: (0, node_path.join)(real, d.name)
|
|
316
|
+
}));
|
|
317
|
+
const fs = await (0, node_fs_promises.statfs)(real);
|
|
318
|
+
const totalBytes = fs.blocks * fs.bsize;
|
|
319
|
+
return {
|
|
320
|
+
path: real,
|
|
321
|
+
entries,
|
|
322
|
+
freeBytes: fs.bavail * fs.bsize,
|
|
323
|
+
totalBytes
|
|
324
|
+
};
|
|
325
|
+
}
|
|
326
|
+
async createDir({ path }) {
|
|
327
|
+
const parent = (0, node_path.dirname)(path);
|
|
328
|
+
assertWithinAllowedRoots((0, node_path.join)(await (0, node_fs_promises.realpath)(parent).catch(() => parent), (0, node_path.basename)(path)), await this.resolvedRoots());
|
|
329
|
+
await (0, node_fs_promises.mkdir)(path, { recursive: true });
|
|
330
|
+
return { path };
|
|
331
|
+
}
|
|
332
|
+
/** Allowed roots with symlinks resolved (falls back to the raw root if it does not exist). */
|
|
333
|
+
async resolvedRoots() {
|
|
334
|
+
return Promise.all(this.allowedRoots().map((r) => (0, node_fs_promises.realpath)(r).catch(() => r)));
|
|
335
|
+
}
|
|
336
|
+
};
|
|
337
|
+
//#endregion
|
|
338
|
+
//#region src/builtins/sqlite-storage/filesystem-storage.addon.ts
|
|
339
|
+
function defaultAllowedRoots() {
|
|
340
|
+
return [
|
|
341
|
+
"/mnt",
|
|
342
|
+
"/Volumes",
|
|
343
|
+
"/media",
|
|
344
|
+
(0, node_os.homedir)()
|
|
345
|
+
];
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Filesystem Storage addon — registers a filesystem-backed
|
|
349
|
+
* `storage-provider` (Task 7).
|
|
350
|
+
*
|
|
351
|
+
* Pre-Task 7 this addon registered against the (then-collection)
|
|
352
|
+
* `storage` cap. After Tasks 2/3/4 the consumer-facing `storage` cap is
|
|
353
|
+
* a singleton owned by `storage-orchestrator`; the orchestrator
|
|
354
|
+
* dispatches each call to whichever `storage-provider` matches
|
|
355
|
+
* `location.providerId`.
|
|
356
|
+
*
|
|
357
|
+
* The OLD `rootPath` config field is preserved for back-compat: the
|
|
358
|
+
* orchestrator's first-boot seeding step still uses the same env-var
|
|
359
|
+
* resolution chain (operator override → `CAMSTACK_DATA` → fallback) to
|
|
360
|
+
* derive the base path of every default location, then writes
|
|
361
|
+
* `config.basePath` into each persisted `StorageLocation` row. The
|
|
362
|
+
* provider itself is now stateless — every call carries the live
|
|
363
|
+
* `StorageLocation` inline.
|
|
364
|
+
*/
|
|
365
|
+
var FilesystemStorageAddon = class extends _camstack_types.BaseAddon {
|
|
366
|
+
provider = null;
|
|
367
|
+
constructor() {
|
|
368
|
+
super({
|
|
369
|
+
rootPath: "camstack-data",
|
|
370
|
+
storageAllowedRoots: defaultAllowedRoots()
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
async onInitialize() {
|
|
374
|
+
this.provider = new FilesystemStorageProvider();
|
|
375
|
+
const browse = new FilesystemBrowseProvider(() => this.config.storageAllowedRoots);
|
|
376
|
+
this.ctx.logger.info("Filesystem storage-provider initialized");
|
|
377
|
+
return [{
|
|
378
|
+
capability: _camstack_types.storageProviderCapability,
|
|
379
|
+
provider: this.provider
|
|
380
|
+
}, {
|
|
381
|
+
capability: _camstack_types.filesystemBrowseCapability,
|
|
382
|
+
provider: browse
|
|
383
|
+
}];
|
|
384
|
+
}
|
|
385
|
+
async onShutdown() {
|
|
386
|
+
await this.provider?.dispose();
|
|
387
|
+
this.provider = null;
|
|
388
|
+
}
|
|
389
|
+
getProvider() {
|
|
390
|
+
return this.provider;
|
|
391
|
+
}
|
|
392
|
+
};
|
|
393
|
+
//#endregion
|
|
394
|
+
exports.FilesystemStorageAddon = FilesystemStorageAddon;
|
|
395
|
+
exports.default = FilesystemStorageAddon;
|
|
396
|
+
exports.FilesystemStorageProvider = FilesystemStorageProvider;
|