@wasmsoft/fantastic 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -0
- package/bin/run.js +27 -0
- package/bin/supervisor.js +65 -0
- package/dist/acquire/central-url.d.ts +9 -0
- package/dist/acquire/central-url.d.ts.map +1 -0
- package/dist/acquire/central-url.js +74 -0
- package/dist/acquire/central-url.js.map +1 -0
- package/dist/acquire/code.d.ts +21 -0
- package/dist/acquire/code.d.ts.map +1 -0
- package/dist/acquire/code.js +66 -0
- package/dist/acquire/code.js.map +1 -0
- package/dist/acquire/compatibility.d.ts +18 -0
- package/dist/acquire/compatibility.d.ts.map +1 -0
- package/dist/acquire/compatibility.js +36 -0
- package/dist/acquire/compatibility.js.map +1 -0
- package/dist/acquire/fetch.d.ts +26 -0
- package/dist/acquire/fetch.d.ts.map +1 -0
- package/dist/acquire/fetch.js +72 -0
- package/dist/acquire/fetch.js.map +1 -0
- package/dist/acquire/latest.d.ts +24 -0
- package/dist/acquire/latest.d.ts.map +1 -0
- package/dist/acquire/latest.js +95 -0
- package/dist/acquire/latest.js.map +1 -0
- package/dist/backup/archive.d.ts +26 -0
- package/dist/backup/archive.d.ts.map +1 -0
- package/dist/backup/archive.js +123 -0
- package/dist/backup/archive.js.map +1 -0
- package/dist/backup/restore.d.ts +46 -0
- package/dist/backup/restore.d.ts.map +1 -0
- package/dist/backup/restore.js +164 -0
- package/dist/backup/restore.js.map +1 -0
- package/dist/base-command.d.ts +54 -0
- package/dist/base-command.d.ts.map +1 -0
- package/dist/base-command.js +120 -0
- package/dist/base-command.js.map +1 -0
- package/dist/bundle-format/index.d.ts +6 -0
- package/dist/bundle-format/index.d.ts.map +1 -0
- package/dist/bundle-format/index.js +36 -0
- package/dist/bundle-format/index.js.map +1 -0
- package/dist/commands/activate.d.ts +15 -0
- package/dist/commands/activate.d.ts.map +1 -0
- package/dist/commands/activate.js +139 -0
- package/dist/commands/activate.js.map +1 -0
- package/dist/commands/backup.d.ts +11 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +75 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/config/get.d.ts +10 -0
- package/dist/commands/config/get.d.ts.map +1 -0
- package/dist/commands/config/get.js +33 -0
- package/dist/commands/config/get.js.map +1 -0
- package/dist/commands/config/list.d.ts +7 -0
- package/dist/commands/config/list.d.ts.map +1 -0
- package/dist/commands/config/list.js +43 -0
- package/dist/commands/config/list.js.map +1 -0
- package/dist/commands/config/set.d.ts +11 -0
- package/dist/commands/config/set.d.ts.map +1 -0
- package/dist/commands/config/set.js +56 -0
- package/dist/commands/config/set.js.map +1 -0
- package/dist/commands/db/migrate.d.ts +10 -0
- package/dist/commands/db/migrate.d.ts.map +1 -0
- package/dist/commands/db/migrate.js +67 -0
- package/dist/commands/db/migrate.js.map +1 -0
- package/dist/commands/dev.d.ts +19 -0
- package/dist/commands/dev.d.ts.map +1 -0
- package/dist/commands/dev.js +149 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +75 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/health.d.ts +12 -0
- package/dist/commands/health.d.ts.map +1 -0
- package/dist/commands/health.js +109 -0
- package/dist/commands/health.js.map +1 -0
- package/dist/commands/install.d.ts +60 -0
- package/dist/commands/install.d.ts.map +1 -0
- package/dist/commands/install.js +486 -0
- package/dist/commands/install.js.map +1 -0
- package/dist/commands/iptv/snapshot.d.ts +10 -0
- package/dist/commands/iptv/snapshot.d.ts.map +1 -0
- package/dist/commands/iptv/snapshot.js +55 -0
- package/dist/commands/iptv/snapshot.js.map +1 -0
- package/dist/commands/library/drives.d.ts +7 -0
- package/dist/commands/library/drives.d.ts.map +1 -0
- package/dist/commands/library/drives.js +71 -0
- package/dist/commands/library/drives.js.map +1 -0
- package/dist/commands/library/relink.d.ts +10 -0
- package/dist/commands/library/relink.d.ts.map +1 -0
- package/dist/commands/library/relink.js +72 -0
- package/dist/commands/library/relink.js.map +1 -0
- package/dist/commands/library/scan.d.ts +16 -0
- package/dist/commands/library/scan.d.ts.map +1 -0
- package/dist/commands/library/scan.js +87 -0
- package/dist/commands/library/scan.js.map +1 -0
- package/dist/commands/library/sections.d.ts +7 -0
- package/dist/commands/library/sections.d.ts.map +1 -0
- package/dist/commands/library/sections.js +33 -0
- package/dist/commands/library/sections.js.map +1 -0
- package/dist/commands/library/status.d.ts +7 -0
- package/dist/commands/library/status.d.ts.map +1 -0
- package/dist/commands/library/status.js +37 -0
- package/dist/commands/library/status.js.map +1 -0
- package/dist/commands/list.d.ts +7 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +73 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/live/channels.d.ts +10 -0
- package/dist/commands/live/channels.d.ts.map +1 -0
- package/dist/commands/live/channels.js +55 -0
- package/dist/commands/live/channels.js.map +1 -0
- package/dist/commands/live/test.d.ts +15 -0
- package/dist/commands/live/test.d.ts.map +1 -0
- package/dist/commands/live/test.js +116 -0
- package/dist/commands/live/test.js.map +1 -0
- package/dist/commands/logs.d.ts +16 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +77 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/migrate-cli.d.ts +11 -0
- package/dist/commands/migrate-cli.d.ts.map +1 -0
- package/dist/commands/migrate-cli.js +116 -0
- package/dist/commands/migrate-cli.js.map +1 -0
- package/dist/commands/owner/reset.d.ts +7 -0
- package/dist/commands/owner/reset.d.ts.map +1 -0
- package/dist/commands/owner/reset.js +74 -0
- package/dist/commands/owner/reset.js.map +1 -0
- package/dist/commands/restart.d.ts +11 -0
- package/dist/commands/restart.d.ts.map +1 -0
- package/dist/commands/restart.js +53 -0
- package/dist/commands/restart.js.map +1 -0
- package/dist/commands/restore.d.ts +17 -0
- package/dist/commands/restore.d.ts.map +1 -0
- package/dist/commands/restore.js +148 -0
- package/dist/commands/restore.js.map +1 -0
- package/dist/commands/self-update.d.ts +10 -0
- package/dist/commands/self-update.d.ts.map +1 -0
- package/dist/commands/self-update.js +98 -0
- package/dist/commands/self-update.js.map +1 -0
- package/dist/commands/setup.d.ts +19 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +111 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/commands/shell.d.ts +118 -0
- package/dist/commands/shell.d.ts.map +1 -0
- package/dist/commands/shell.js +415 -0
- package/dist/commands/shell.js.map +1 -0
- package/dist/commands/start.d.ts +12 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +108 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/status.d.ts +8 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +115 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/commands/stop.d.ts +11 -0
- package/dist/commands/stop.d.ts.map +1 -0
- package/dist/commands/stop.js +45 -0
- package/dist/commands/stop.js.map +1 -0
- package/dist/commands/stream/cancel.d.ts +13 -0
- package/dist/commands/stream/cancel.d.ts.map +1 -0
- package/dist/commands/stream/cancel.js +31 -0
- package/dist/commands/stream/cancel.js.map +1 -0
- package/dist/commands/stream/encoders.d.ts +7 -0
- package/dist/commands/stream/encoders.d.ts.map +1 -0
- package/dist/commands/stream/encoders.js +42 -0
- package/dist/commands/stream/encoders.js.map +1 -0
- package/dist/commands/stream/queue.d.ts +7 -0
- package/dist/commands/stream/queue.d.ts.map +1 -0
- package/dist/commands/stream/queue.js +52 -0
- package/dist/commands/stream/queue.js.map +1 -0
- package/dist/commands/stream/sessions.d.ts +7 -0
- package/dist/commands/stream/sessions.d.ts.map +1 -0
- package/dist/commands/stream/sessions.js +44 -0
- package/dist/commands/stream/sessions.js.map +1 -0
- package/dist/commands/uninstall.d.ts +23 -0
- package/dist/commands/uninstall.d.ts.map +1 -0
- package/dist/commands/uninstall.js +290 -0
- package/dist/commands/uninstall.js.map +1 -0
- package/dist/commands/update.d.ts +21 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +290 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/commands/watch.d.ts +10 -0
- package/dist/commands/watch.d.ts.map +1 -0
- package/dist/commands/watch.js +38 -0
- package/dist/commands/watch.js.map +1 -0
- package/dist/config/local-config.d.ts +22 -0
- package/dist/config/local-config.d.ts.map +1 -0
- package/dist/config/local-config.js +79 -0
- package/dist/config/local-config.js.map +1 -0
- package/dist/core-scripts/run.d.ts +22 -0
- package/dist/core-scripts/run.d.ts.map +1 -0
- package/dist/core-scripts/run.js +65 -0
- package/dist/core-scripts/run.js.map +1 -0
- package/dist/doctor/check.types.d.ts +51 -0
- package/dist/doctor/check.types.d.ts.map +1 -0
- package/dist/doctor/check.types.js +14 -0
- package/dist/doctor/check.types.js.map +1 -0
- package/dist/doctor/checks/core.check.d.ts +11 -0
- package/dist/doctor/checks/core.check.d.ts.map +1 -0
- package/dist/doctor/checks/core.check.js +104 -0
- package/dist/doctor/checks/core.check.js.map +1 -0
- package/dist/doctor/checks/data.check.d.ts +11 -0
- package/dist/doctor/checks/data.check.d.ts.map +1 -0
- package/dist/doctor/checks/data.check.js +70 -0
- package/dist/doctor/checks/data.check.js.map +1 -0
- package/dist/doctor/checks/environment.check.d.ts +6 -0
- package/dist/doctor/checks/environment.check.d.ts.map +1 -0
- package/dist/doctor/checks/environment.check.js +70 -0
- package/dist/doctor/checks/environment.check.js.map +1 -0
- package/dist/doctor/checks/integrity.check.d.ts +4 -0
- package/dist/doctor/checks/integrity.check.d.ts.map +1 -0
- package/dist/doctor/checks/integrity.check.js +89 -0
- package/dist/doctor/checks/integrity.check.js.map +1 -0
- package/dist/doctor/checks/isolation.check.d.ts +49 -0
- package/dist/doctor/checks/isolation.check.d.ts.map +1 -0
- package/dist/doctor/checks/isolation.check.js +220 -0
- package/dist/doctor/checks/isolation.check.js.map +1 -0
- package/dist/doctor/checks/licence.check.d.ts +8 -0
- package/dist/doctor/checks/licence.check.d.ts.map +1 -0
- package/dist/doctor/checks/licence.check.js +172 -0
- package/dist/doctor/checks/licence.check.js.map +1 -0
- package/dist/doctor/checks/ports.check.d.ts +4 -0
- package/dist/doctor/checks/ports.check.d.ts.map +1 -0
- package/dist/doctor/checks/ports.check.js +52 -0
- package/dist/doctor/checks/ports.check.js.map +1 -0
- package/dist/doctor/checks/supervisor.check.d.ts +19 -0
- package/dist/doctor/checks/supervisor.check.d.ts.map +1 -0
- package/dist/doctor/checks/supervisor.check.js +152 -0
- package/dist/doctor/checks/supervisor.check.js.map +1 -0
- package/dist/doctor/checks/tooling.check.d.ts +3 -0
- package/dist/doctor/checks/tooling.check.d.ts.map +1 -0
- package/dist/doctor/checks/tooling.check.js +43 -0
- package/dist/doctor/checks/tooling.check.js.map +1 -0
- package/dist/doctor/registry.d.ts +15 -0
- package/dist/doctor/registry.d.ts.map +1 -0
- package/dist/doctor/registry.js +53 -0
- package/dist/doctor/registry.js.map +1 -0
- package/dist/exit-codes.d.ts +18 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +23 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/logs/sink.d.ts +11 -0
- package/dist/logs/sink.d.ts.map +1 -0
- package/dist/logs/sink.js +73 -0
- package/dist/logs/sink.js.map +1 -0
- package/dist/logs/tail.d.ts +17 -0
- package/dist/logs/tail.d.ts.map +1 -0
- package/dist/logs/tail.js +98 -0
- package/dist/logs/tail.js.map +1 -0
- package/dist/packaging/boot-task.d.ts +56 -0
- package/dist/packaging/boot-task.d.ts.map +1 -0
- package/dist/packaging/boot-task.js +151 -0
- package/dist/packaging/boot-task.js.map +1 -0
- package/dist/packaging/install.d.ts +154 -0
- package/dist/packaging/install.d.ts.map +1 -0
- package/dist/packaging/install.js +381 -0
- package/dist/packaging/install.js.map +1 -0
- package/dist/packaging/layout.d.ts +153 -0
- package/dist/packaging/layout.d.ts.map +1 -0
- package/dist/packaging/layout.js +168 -0
- package/dist/packaging/layout.js.map +1 -0
- package/dist/packaging/machine-path.d.ts +52 -0
- package/dist/packaging/machine-path.d.ts.map +1 -0
- package/dist/packaging/machine-path.js +237 -0
- package/dist/packaging/machine-path.js.map +1 -0
- package/dist/packaging/manifest.d.ts +37 -0
- package/dist/packaging/manifest.d.ts.map +1 -0
- package/dist/packaging/manifest.js +115 -0
- package/dist/packaging/manifest.js.map +1 -0
- package/dist/packaging/shims.d.ts +31 -0
- package/dist/packaging/shims.d.ts.map +1 -0
- package/dist/packaging/shims.js +165 -0
- package/dist/packaging/shims.js.map +1 -0
- package/dist/probes/internal-paths.d.ts +35 -0
- package/dist/probes/internal-paths.d.ts.map +1 -0
- package/dist/probes/internal-paths.js +58 -0
- package/dist/probes/internal-paths.js.map +1 -0
- package/dist/probes/internal.client.d.ts +54 -0
- package/dist/probes/internal.client.d.ts.map +1 -0
- package/dist/probes/internal.client.js +123 -0
- package/dist/probes/internal.client.js.map +1 -0
- package/dist/probes/port.probe.d.ts +21 -0
- package/dist/probes/port.probe.d.ts.map +1 -0
- package/dist/probes/port.probe.js +42 -0
- package/dist/probes/port.probe.js.map +1 -0
- package/dist/probes/service.probe.d.ts +29 -0
- package/dist/probes/service.probe.d.ts.map +1 -0
- package/dist/probes/service.probe.js +65 -0
- package/dist/probes/service.probe.js.map +1 -0
- package/dist/profiles/appliance.profile.d.ts +20 -0
- package/dist/profiles/appliance.profile.d.ts.map +1 -0
- package/dist/profiles/appliance.profile.js +137 -0
- package/dist/profiles/appliance.profile.js.map +1 -0
- package/dist/profiles/dev.profile.d.ts +22 -0
- package/dist/profiles/dev.profile.d.ts.map +1 -0
- package/dist/profiles/dev.profile.js +104 -0
- package/dist/profiles/dev.profile.js.map +1 -0
- package/dist/profiles/resolve.d.ts +37 -0
- package/dist/profiles/resolve.d.ts.map +1 -0
- package/dist/profiles/resolve.js +198 -0
- package/dist/profiles/resolve.js.map +1 -0
- package/dist/profiles/types.d.ts +57 -0
- package/dist/profiles/types.d.ts.map +1 -0
- package/dist/profiles/types.js +15 -0
- package/dist/profiles/types.js.map +1 -0
- package/dist/registry/local-registry.d.ts +79 -0
- package/dist/registry/local-registry.d.ts.map +1 -0
- package/dist/registry/local-registry.js +252 -0
- package/dist/registry/local-registry.js.map +1 -0
- package/dist/render/banner.d.ts +13 -0
- package/dist/render/banner.d.ts.map +1 -0
- package/dist/render/banner.js +83 -0
- package/dist/render/banner.js.map +1 -0
- package/dist/render/boot.render.d.ts +123 -0
- package/dist/render/boot.render.d.ts.map +1 -0
- package/dist/render/boot.render.js +288 -0
- package/dist/render/boot.render.js.map +1 -0
- package/dist/render/brand.d.ts +16 -0
- package/dist/render/brand.d.ts.map +1 -0
- package/dist/render/brand.js +22 -0
- package/dist/render/brand.js.map +1 -0
- package/dist/render/doctor.render.d.ts +12 -0
- package/dist/render/doctor.render.d.ts.map +1 -0
- package/dist/render/doctor.render.js +95 -0
- package/dist/render/doctor.render.js.map +1 -0
- package/dist/render/json.d.ts +29 -0
- package/dist/render/json.d.ts.map +1 -0
- package/dist/render/json.js +19 -0
- package/dist/render/json.js.map +1 -0
- package/dist/render/licence.render.d.ts +10 -0
- package/dist/render/licence.render.d.ts.map +1 -0
- package/dist/render/licence.render.js +167 -0
- package/dist/render/licence.render.js.map +1 -0
- package/dist/render/status.render.d.ts +6 -0
- package/dist/render/status.render.d.ts.map +1 -0
- package/dist/render/status.render.js +52 -0
- package/dist/render/status.render.js.map +1 -0
- package/dist/render/theme.d.ts +66 -0
- package/dist/render/theme.d.ts.map +1 -0
- package/dist/render/theme.js +89 -0
- package/dist/render/theme.js.map +1 -0
- package/dist/runtime-guard.d.ts +19 -0
- package/dist/runtime-guard.d.ts.map +1 -0
- package/dist/runtime-guard.js +57 -0
- package/dist/runtime-guard.js.map +1 -0
- package/dist/shell/input-mode.d.ts +25 -0
- package/dist/shell/input-mode.d.ts.map +1 -0
- package/dist/shell/input-mode.js +17 -0
- package/dist/shell/input-mode.js.map +1 -0
- package/dist/shell/parse-line.d.ts +6 -0
- package/dist/shell/parse-line.d.ts.map +1 -0
- package/dist/shell/parse-line.js +62 -0
- package/dist/shell/parse-line.js.map +1 -0
- package/dist/shell/suggestions.d.ts +14 -0
- package/dist/shell/suggestions.d.ts.map +1 -0
- package/dist/shell/suggestions.js +35 -0
- package/dist/shell/suggestions.js.map +1 -0
- package/dist/supervisor/dependencies.d.ts +2 -0
- package/dist/supervisor/dependencies.d.ts.map +1 -0
- package/dist/supervisor/dependencies.js +38 -0
- package/dist/supervisor/dependencies.js.map +1 -0
- package/dist/supervisor/entry.d.ts +36 -0
- package/dist/supervisor/entry.d.ts.map +1 -0
- package/dist/supervisor/entry.js +171 -0
- package/dist/supervisor/entry.js.map +1 -0
- package/dist/supervisor/inspect.d.ts +17 -0
- package/dist/supervisor/inspect.d.ts.map +1 -0
- package/dist/supervisor/inspect.js +39 -0
- package/dist/supervisor/inspect.js.map +1 -0
- package/dist/supervisor/invocation.d.ts +27 -0
- package/dist/supervisor/invocation.d.ts.map +1 -0
- package/dist/supervisor/invocation.js +33 -0
- package/dist/supervisor/invocation.js.map +1 -0
- package/dist/supervisor/monitor.d.ts +63 -0
- package/dist/supervisor/monitor.d.ts.map +1 -0
- package/dist/supervisor/monitor.js +141 -0
- package/dist/supervisor/monitor.js.map +1 -0
- package/dist/supervisor/orchestrator.d.ts +52 -0
- package/dist/supervisor/orchestrator.d.ts.map +1 -0
- package/dist/supervisor/orchestrator.js +154 -0
- package/dist/supervisor/orchestrator.js.map +1 -0
- package/dist/supervisor/pidfile.d.ts +21 -0
- package/dist/supervisor/pidfile.d.ts.map +1 -0
- package/dist/supervisor/pidfile.js +39 -0
- package/dist/supervisor/pidfile.js.map +1 -0
- package/dist/supervisor/process-identity.d.ts +19 -0
- package/dist/supervisor/process-identity.d.ts.map +1 -0
- package/dist/supervisor/process-identity.js +51 -0
- package/dist/supervisor/process-identity.js.map +1 -0
- package/dist/supervisor/readiness.d.ts +17 -0
- package/dist/supervisor/readiness.d.ts.map +1 -0
- package/dist/supervisor/readiness.js +52 -0
- package/dist/supervisor/readiness.js.map +1 -0
- package/dist/supervisor/restart-consumer.d.ts +37 -0
- package/dist/supervisor/restart-consumer.d.ts.map +1 -0
- package/dist/supervisor/restart-consumer.js +119 -0
- package/dist/supervisor/restart-consumer.js.map +1 -0
- package/dist/supervisor/runner.d.ts +2 -0
- package/dist/supervisor/runner.d.ts.map +1 -0
- package/dist/supervisor/runner.js +118 -0
- package/dist/supervisor/runner.js.map +1 -0
- package/dist/supervisor/schedule-timer.d.ts +38 -0
- package/dist/supervisor/schedule-timer.d.ts.map +1 -0
- package/dist/supervisor/schedule-timer.js +148 -0
- package/dist/supervisor/schedule-timer.js.map +1 -0
- package/dist/supervisor/spawn.d.ts +18 -0
- package/dist/supervisor/spawn.d.ts.map +1 -0
- package/dist/supervisor/spawn.js +119 -0
- package/dist/supervisor/spawn.js.map +1 -0
- package/dist/supervisor/state-files.d.ts +33 -0
- package/dist/supervisor/state-files.d.ts.map +1 -0
- package/dist/supervisor/state-files.js +110 -0
- package/dist/supervisor/state-files.js.map +1 -0
- package/dist/supervisor/tree-kill.d.ts +14 -0
- package/dist/supervisor/tree-kill.d.ts.map +1 -0
- package/dist/supervisor/tree-kill.js +82 -0
- package/dist/supervisor/tree-kill.js.map +1 -0
- package/dist/ui/health-panel.d.ts +8 -0
- package/dist/ui/health-panel.d.ts.map +1 -0
- package/dist/ui/health-panel.js +91 -0
- package/dist/ui/health-panel.js.map +1 -0
- package/dist/updating/apply.d.ts +50 -0
- package/dist/updating/apply.d.ts.map +1 -0
- package/dist/updating/apply.js +172 -0
- package/dist/updating/apply.js.map +1 -0
- package/dist/updating/download.d.ts +44 -0
- package/dist/updating/download.d.ts.map +1 -0
- package/dist/updating/download.js +144 -0
- package/dist/updating/download.js.map +1 -0
- package/dist/updating/rollback.d.ts +33 -0
- package/dist/updating/rollback.d.ts.map +1 -0
- package/dist/updating/rollback.js +54 -0
- package/dist/updating/rollback.js.map +1 -0
- package/dist/updating/self.d.ts +16 -0
- package/dist/updating/self.d.ts.map +1 -0
- package/dist/updating/self.js +50 -0
- package/dist/updating/self.js.map +1 -0
- package/dist/updating/verify.d.ts +25 -0
- package/dist/updating/verify.d.ts.map +1 -0
- package/dist/updating/verify.js +51 -0
- package/dist/updating/verify.js.map +1 -0
- package/dist/updating/versions.d.ts +31 -0
- package/dist/updating/versions.d.ts.map +1 -0
- package/dist/updating/versions.js +78 -0
- package/dist/updating/versions.js.map +1 -0
- package/dist/version.d.ts +4 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +29 -0
- package/dist/version.js.map +1 -0
- package/package.json +106 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { resolveCentralUrl } from "./central-url.js";
|
|
2
|
+
// AR: «ما أحدث حزمةٍ لهذا المنتج، وما بصمتها؟» — السؤال الذي يسبق التنزيل (٠٢٦).
|
|
3
|
+
//
|
|
4
|
+
// **والبصمة تُقرأ قبل البايتات لا معها.** هذا قرارٌ في المنصّة منذ سطح التثبيت الأوّل، وهو ما
|
|
5
|
+
// يجعل المطابقة ذات معنى: بصمةٌ تصل مع الملفّ الذي تصفه لا تُثبت شيئًا — من بدّل الملفّ يبدّل
|
|
6
|
+
// البصمة معه.
|
|
7
|
+
//
|
|
8
|
+
// ولا JSON في هذا الردّ بل key=value: قارئه الأصليّ سكربت cmd يقرؤه بـfor /f، وتحليل JSON
|
|
9
|
+
// هناك سطرٌ هشّ ينكسر أوّل ما يُضاف حقل. ونقرؤه نحن بنفس بساطته.
|
|
10
|
+
// EN: "What is the newest bundle for this product, and what is its digest?" — the question that
|
|
11
|
+
// precedes the download (026).
|
|
12
|
+
//
|
|
13
|
+
// **The digest is read before the bytes, not with them.** That is the centre's decision from the
|
|
14
|
+
// first-install surface onward, and it is what makes the comparison meaningful: a digest arriving
|
|
15
|
+
// alongside the file it describes proves nothing — whoever swapped the file swapped the digest
|
|
16
|
+
// with it.
|
|
17
|
+
//
|
|
18
|
+
// And the reply is `key=value` rather than JSON: its original reader is a `cmd` script parsing it
|
|
19
|
+
// with `for /f`, where JSON is a brittle line that breaks the first time a field is added. We
|
|
20
|
+
// read it with the same simplicity.
|
|
21
|
+
export const ACTIVATION_HEADER = "X-Activation-Code";
|
|
22
|
+
export class CentralRefused extends Error {
|
|
23
|
+
status;
|
|
24
|
+
constructor(status, message) {
|
|
25
|
+
super(message);
|
|
26
|
+
this.status = status;
|
|
27
|
+
this.name = "CentralRefused";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* AR: يحوّل ردّ المركز إلى رسالةٍ عربية تقول ما العمل. **الأكواد لا تُعرَض للفنّي**: 403 لا
|
|
32
|
+
* تخبره بشيء، و«رخصتك منتهية، تواصل مع الدعم» تخبره بكل شيء.
|
|
33
|
+
* EN: Turns the centre's answer into an Arabic message that says what to do. **Codes are not shown
|
|
34
|
+
* to the technician**: `403` tells them nothing, while "your licence has expired, contact
|
|
35
|
+
* support" tells them everything.
|
|
36
|
+
*/
|
|
37
|
+
function explain(status, body) {
|
|
38
|
+
if (status === 404)
|
|
39
|
+
return "كود التفعيل غير صحيح، أو لا توجد حزمة منشورة لهذا المنتج.";
|
|
40
|
+
if (status === 403)
|
|
41
|
+
return "الرخصة غير نشطة أو منتهية، أو المنتج غير مشمولٍ بها. تواصل مع الدعم.";
|
|
42
|
+
if (status === 429)
|
|
43
|
+
return "محاولات كثيرة في وقتٍ قصير. انتظر دقيقة ثم أعِد المحاولة.";
|
|
44
|
+
if (status >= 500)
|
|
45
|
+
return "المنصّة المركزية لا تستجيب الآن. أعِد المحاولة بعد قليل.";
|
|
46
|
+
const trimmed = body.trim().slice(0, 200);
|
|
47
|
+
return trimmed.length > 0 ? trimmed : `ردٌّ غير متوقَّع من المنصّة (${status}).`;
|
|
48
|
+
}
|
|
49
|
+
function parsePairs(text) {
|
|
50
|
+
const pairs = {};
|
|
51
|
+
for (const line of text.split("\n")) {
|
|
52
|
+
const index = line.indexOf("=");
|
|
53
|
+
if (index <= 0)
|
|
54
|
+
continue;
|
|
55
|
+
pairs[line.slice(0, index).trim()] = line.slice(index + 1).trim();
|
|
56
|
+
}
|
|
57
|
+
return pairs;
|
|
58
|
+
}
|
|
59
|
+
export function releaseUrl(path, product, platform = "win-x64") {
|
|
60
|
+
const { url } = resolveCentralUrl();
|
|
61
|
+
return `${url}/api/v1/setup/${path}?platform=${encodeURIComponent(platform)}&product=${encodeURIComponent(product)}`;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* AR: يسأل المركز عن أحدث حزمة. **لا يُستعمل عميل HTTP خارجيّ**: fetch مدمجٌ في Node 20،
|
|
65
|
+
* والدستور يمنع عميلًا ثانيًا — وحزمةٌ إضافية هنا تُشحن إلى كل جهاز فنّيّ بلا مقابل.
|
|
66
|
+
* EN: Asks the centre for the newest bundle. **No external HTTP client is used**: `fetch` is built
|
|
67
|
+
* into Node 20 and the constitution forbids a second client — and an extra package here ships to
|
|
68
|
+
* every technician's machine for nothing.
|
|
69
|
+
*/
|
|
70
|
+
export async function fetchLatest(code, product, platform = "win-x64") {
|
|
71
|
+
const response = await fetch(releaseUrl("latest", product, platform), {
|
|
72
|
+
headers: { [ACTIVATION_HEADER]: code },
|
|
73
|
+
});
|
|
74
|
+
const text = await response.text();
|
|
75
|
+
if (!response.ok)
|
|
76
|
+
throw new CentralRefused(response.status, explain(response.status, text));
|
|
77
|
+
const pairs = parsePairs(text);
|
|
78
|
+
if (!pairs.version || !pairs.sha256) {
|
|
79
|
+
throw new CentralRefused(response.status, "ردّ المنصّة لا يحمل إصدارًا ولا بصمة — تواصل مع الدعم.");
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
version: pairs.version,
|
|
83
|
+
sha256: pairs.sha256,
|
|
84
|
+
sizeBytes: Number.parseInt(pairs.size ?? "0", 10) || 0,
|
|
85
|
+
fileName: pairs.file ?? `Fantastic-${pairs.version}-${platform}.zip`,
|
|
86
|
+
// AR: حقلان أُضيفا في ٠٢٦ ويردّهما مركزٌ محدَّث وحده. وغيابهما ليس عطلًا: مركزٌ أقدم يخدم
|
|
87
|
+
// منتجًا واحدًا ولا يشترط إصدار واجهة، وهو بالضبط ما كان قبل هذه الميزة.
|
|
88
|
+
// EN: Two fields added in 026 and returned only by an updated centre. Their absence is not a
|
|
89
|
+
// fault: an older centre serves one product and requires no CLI version — precisely what was
|
|
90
|
+
// true before this feature.
|
|
91
|
+
product: pairs.product ?? product,
|
|
92
|
+
minCliVersion: pairs.minCliVersion ?? "",
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=latest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"latest.js","sourceRoot":"","sources":["../../src/acquire/latest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Profile } from "../profiles/types.js";
|
|
2
|
+
export declare const ARCHIVE_VERSION = 1;
|
|
3
|
+
export declare const SNAPSHOT_NAME = "fantastic.db";
|
|
4
|
+
export interface BackupManifest {
|
|
5
|
+
archiveVersion: number;
|
|
6
|
+
createdAt: string;
|
|
7
|
+
profile: string;
|
|
8
|
+
/** إصدار النواة وقت النسخ، لتشخيص استعادة عبر إصدارات. */
|
|
9
|
+
coreVersion?: string;
|
|
10
|
+
/** عدد الهجرات المطبَّقة. الاستعادة إلى قاعدة أقدم تُرفَض عليه. */
|
|
11
|
+
schemaRevision: number;
|
|
12
|
+
includesLogs: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface BackupOptions {
|
|
15
|
+
outDir: string;
|
|
16
|
+
includeLogs?: boolean;
|
|
17
|
+
/** يُستدعى عند كل خطوة للعرض. */
|
|
18
|
+
onStep?: (message: string) => void;
|
|
19
|
+
}
|
|
20
|
+
export interface BackupResult {
|
|
21
|
+
file: string;
|
|
22
|
+
bytes: number;
|
|
23
|
+
manifest: BackupManifest;
|
|
24
|
+
}
|
|
25
|
+
export declare function createBackup(profile: Profile, options: BackupOptions): Promise<BackupResult>;
|
|
26
|
+
//# sourceMappingURL=archive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/backup/archive.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAmCpD,eAAO,MAAM,eAAe,IAAI,CAAC;AACjC,eAAO,MAAM,aAAa,iBAAiB,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,mEAAmE;IACnE,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iCAAiC;IACjC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACpC;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,cAAc,CAAC;CAC1B;AAyBD,wBAAsB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAgElG"}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { createWriteStream, existsSync, mkdirSync, readdirSync, rmSync, statSync } from "node:fs";
|
|
2
|
+
import { join, relative } from "node:path";
|
|
3
|
+
import { ZipArchive } from "archiver";
|
|
4
|
+
import { INTERNAL_PATHS } from "../probes/internal-paths.js";
|
|
5
|
+
import { postInternal } from "../probes/internal.client.js";
|
|
6
|
+
// AR: بناء أرشيف النسخ الاحتياطي.
|
|
7
|
+
//
|
|
8
|
+
// **ما يدخل وما لا يدخل قرارٌ لا تفصيل.**
|
|
9
|
+
// يدخل: لقطة القاعدة (VACUUM INTO من النواة)، وأصول لا تُولَّد ثانيةً — الشعار وشعارات القنوات
|
|
10
|
+
// وأغلفة المزوّدين — وprovider-keys.key، ومِلفّ إعدادات الـ CLI.
|
|
11
|
+
// لا يدخل: **الوسائط أبدًا** (الدستور II: الأقراص هي مصدر الحقيقة، وأرشيفٌ ينسخها كذبةٌ عن قدرته
|
|
12
|
+
// على الاستعادة)، ولا المخابئ المُولَّدة (image-cache، transcode-cache، live-relay) لأنها
|
|
13
|
+
// تُبنى ثانيةً ولا شيء يضيع بغيابها.
|
|
14
|
+
//
|
|
15
|
+
// provider-keys.key يدخل عمدًا وهو الأدقّ في القائمة: مفاتيح التكاملات مخزَّنة **مشفَّرة** في
|
|
16
|
+
// القاعدة، فأرشيفٌ يحمل القاعدة بلا المفتاح يُستعاد بمفاتيح لا تُفَكّ — نسخة تبدو كاملة وتفشل
|
|
17
|
+
// في أوّل مزامنة.
|
|
18
|
+
// EN: Building the backup archive.
|
|
19
|
+
//
|
|
20
|
+
// **What goes in and what stays out is a decision, not a detail.**
|
|
21
|
+
// In: the database snapshot (VACUUM INTO, performed by the core), assets that cannot be
|
|
22
|
+
// regenerated — the brand logo, channel logos, provider artwork — provider-keys.key, and the
|
|
23
|
+
// CLI's config file.
|
|
24
|
+
// Out: **media, never** (constitution II: the drives are the source of truth, and an archive
|
|
25
|
+
// that copies them lies about what it can restore), and generated caches (image-cache,
|
|
26
|
+
// transcode-cache, live-relay), which rebuild themselves and lose nothing.
|
|
27
|
+
//
|
|
28
|
+
// provider-keys.key is included deliberately and is the subtlest item here: integration keys are
|
|
29
|
+
// stored **encrypted** in the database, so an archive carrying the database without the key
|
|
30
|
+
// restores to keys that cannot be decrypted — a backup that looks complete and fails at the
|
|
31
|
+
// first sync.
|
|
32
|
+
/** مجلدات داخل data/ تُولَّد ثانيةً، فلا معنى لتضخيم الأرشيف بها. */
|
|
33
|
+
const REGENERABLE = new Set(["image-cache", "transcode-cache", "live-relay"]);
|
|
34
|
+
/** ملفات القاعدة الحيّة. تُستبعَد لأن اللقطة تحلّ محلّها؛ نسخها حيّةً هو الخطأ الذي نتفاداه أصلًا. */
|
|
35
|
+
const LIVE_DB_FILES = new Set(["fantastic.db", "fantastic.db-wal", "fantastic.db-shm"]);
|
|
36
|
+
export const ARCHIVE_VERSION = 1;
|
|
37
|
+
export const SNAPSHOT_NAME = "fantastic.db";
|
|
38
|
+
function timestamp(date) {
|
|
39
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
40
|
+
return (`${date.getFullYear()}${pad(date.getMonth() + 1)}${pad(date.getDate())}` +
|
|
41
|
+
`-${pad(date.getHours())}${pad(date.getMinutes())}${pad(date.getSeconds())}`);
|
|
42
|
+
}
|
|
43
|
+
/** عدد ملفات الهجرة المطبَّقة، كتقريب لمراجعة المخطَّط. يُقرأ من القرص لا من القاعدة. */
|
|
44
|
+
function schemaRevision(profile) {
|
|
45
|
+
const candidates = [
|
|
46
|
+
join(profile.root, "apps", "core", "dist", "db", "migrations"),
|
|
47
|
+
join(profile.root, "core", "db", "migrations"),
|
|
48
|
+
];
|
|
49
|
+
for (const dir of candidates) {
|
|
50
|
+
if (!existsSync(dir))
|
|
51
|
+
continue;
|
|
52
|
+
return readdirSync(dir).filter((entry) => entry.endsWith(".sql")).length;
|
|
53
|
+
}
|
|
54
|
+
return 0;
|
|
55
|
+
}
|
|
56
|
+
export async function createBackup(profile, options) {
|
|
57
|
+
const { outDir, includeLogs = false, onStep } = options;
|
|
58
|
+
mkdirSync(outDir, { recursive: true });
|
|
59
|
+
const stamp = timestamp(new Date());
|
|
60
|
+
const file = join(outDir, `fantastic-backup-${stamp}.zip`);
|
|
61
|
+
const staging = join(outDir, `.staging-${stamp}`);
|
|
62
|
+
mkdirSync(staging, { recursive: true });
|
|
63
|
+
try {
|
|
64
|
+
// ١ — لقطة القاعدة من النواة. تفشل بوضوح إن كانت متوقّفة: نسخةٌ بلا قاعدة ليست نسخة.
|
|
65
|
+
onStep?.("asking the core for a consistent database snapshot…");
|
|
66
|
+
const snapshotPath = join(staging, SNAPSHOT_NAME);
|
|
67
|
+
const snapshot = await postInternal(profile, INTERNAL_PATHS.BACKUP_SNAPSHOT, {
|
|
68
|
+
destination: snapshotPath,
|
|
69
|
+
});
|
|
70
|
+
if (!snapshot.ok) {
|
|
71
|
+
throw new Error(`the core could not produce a database snapshot (${snapshot.reason}). ` +
|
|
72
|
+
"Start it first: fantastic start");
|
|
73
|
+
}
|
|
74
|
+
const manifest = {
|
|
75
|
+
archiveVersion: ARCHIVE_VERSION,
|
|
76
|
+
createdAt: new Date().toISOString(),
|
|
77
|
+
profile: profile.kind,
|
|
78
|
+
schemaRevision: schemaRevision(profile),
|
|
79
|
+
includesLogs: includeLogs,
|
|
80
|
+
};
|
|
81
|
+
// ٢ — الأرشفة بالتدفّق. archiver يمرّر البايتات ولا يحمل أرشيفًا بحجم القاعدة في الذاكرة.
|
|
82
|
+
onStep?.("packing…");
|
|
83
|
+
const output = createWriteStream(file);
|
|
84
|
+
const archive = new ZipArchive({ zlib: { level: 9 } });
|
|
85
|
+
const finished = new Promise((resolvePromise, rejectPromise) => {
|
|
86
|
+
output.on("close", () => resolvePromise());
|
|
87
|
+
output.on("error", rejectPromise);
|
|
88
|
+
archive.on("error", rejectPromise);
|
|
89
|
+
});
|
|
90
|
+
archive.pipe(output);
|
|
91
|
+
archive.append(JSON.stringify(manifest, null, 2), { name: "manifest.json" });
|
|
92
|
+
archive.file(snapshotPath, { name: `database/${SNAPSHOT_NAME}` });
|
|
93
|
+
appendDataDirectory(archive, profile);
|
|
94
|
+
const configFile = join(profile.stateDir, "config.json");
|
|
95
|
+
if (existsSync(configFile))
|
|
96
|
+
archive.file(configFile, { name: "state/config.json" });
|
|
97
|
+
if (includeLogs && existsSync(profile.logDir)) {
|
|
98
|
+
archive.directory(profile.logDir, "logs");
|
|
99
|
+
}
|
|
100
|
+
await archive.finalize();
|
|
101
|
+
await finished;
|
|
102
|
+
return { file, bytes: statSync(file).size, manifest };
|
|
103
|
+
}
|
|
104
|
+
finally {
|
|
105
|
+
rmSync(staging, { recursive: true, force: true });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/** يضيف data/ عدا المخابئ وملفات القاعدة الحيّة. */
|
|
109
|
+
function appendDataDirectory(archive, profile) {
|
|
110
|
+
if (!existsSync(profile.dataDir))
|
|
111
|
+
return;
|
|
112
|
+
for (const entry of readdirSync(profile.dataDir, { withFileTypes: true })) {
|
|
113
|
+
if (REGENERABLE.has(entry.name) || LIVE_DB_FILES.has(entry.name))
|
|
114
|
+
continue;
|
|
115
|
+
const full = join(profile.dataDir, entry.name);
|
|
116
|
+
const name = `data/${relative(profile.dataDir, full).replace(/\\/g, "/")}`;
|
|
117
|
+
if (entry.isDirectory())
|
|
118
|
+
archive.directory(full, name);
|
|
119
|
+
else if (entry.isFile())
|
|
120
|
+
archive.file(full, { name });
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/backup/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import type { Profile } from "../profiles/types.js";
|
|
2
|
+
import { type BackupManifest } from "./archive.js";
|
|
3
|
+
export interface ArchiveEntry {
|
|
4
|
+
name: string;
|
|
5
|
+
bytes: number;
|
|
6
|
+
}
|
|
7
|
+
export interface ArchiveContents {
|
|
8
|
+
manifest: BackupManifest;
|
|
9
|
+
entries: ArchiveEntry[];
|
|
10
|
+
}
|
|
11
|
+
/** يقرأ البيان وقائمة المحتويات بلا كتابة أي بايت. أساس --dry-run. */
|
|
12
|
+
export declare function inspectArchive(file: string): Promise<ArchiveContents>;
|
|
13
|
+
export declare class RestoreRefused extends Error {
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* يتحقّق من التوافق **قبل** أي كتابة.
|
|
17
|
+
*
|
|
18
|
+
* أحدث ⇒ رفض. أقدم ⇒ مقبول: الهجرات تمضي إلى الأمام عند أول إقلاع، وذاك مسار مدعوم.
|
|
19
|
+
*/
|
|
20
|
+
export declare function assertCompatible(manifest: BackupManifest, currentRevision: number): void;
|
|
21
|
+
/**
|
|
22
|
+
* وجهة كل مدخل داخل الأرشيف. يُعيد undefined لما لا يُستعاد (السجلّات مثلًا).
|
|
23
|
+
*
|
|
24
|
+
* **يرفض المسارات الهاربة.** أرشيف مُعَدّ يدويًا يستطيع حمل ../../windows/system32/...، وفكّه
|
|
25
|
+
* بلا فحص يكتب خارج مجلد التثبيت. الفحص هنا لأن هذا هو الموضع الوحيد الذي يتحوّل فيه اسمٌ داخل
|
|
26
|
+
* أرشيف إلى مسار على القرص.
|
|
27
|
+
*/
|
|
28
|
+
export declare function destinationFor(profile: Profile, entryName: string): string | undefined;
|
|
29
|
+
export interface RestorePlanEntry {
|
|
30
|
+
from: string;
|
|
31
|
+
to: string;
|
|
32
|
+
bytes: number;
|
|
33
|
+
overwrites: boolean;
|
|
34
|
+
}
|
|
35
|
+
/** ما الذي سيُكتب وما الذي سيُكتب **فوقه**. هذا هو مخرَج --dry-run. */
|
|
36
|
+
export declare function planRestore(profile: Profile, contents: ArchiveContents): RestorePlanEntry[];
|
|
37
|
+
/** يفكّ الأرشيف فعلًا. يُستدعى بعد assertCompatible وبعد تأكيد صريح من المستخدم. */
|
|
38
|
+
export declare function extractArchive(profile: Profile, file: string): Promise<number>;
|
|
39
|
+
/**
|
|
40
|
+
* يزيل ملفَّي WAL المرافقَين قبل الاستعادة.
|
|
41
|
+
*
|
|
42
|
+
* لولا ذلك لبقي -wal قديمٌ بجوار قاعدةٍ مستعادة، فيعيد SQLite تشغيل كتاباتٍ لا تخصّها ويُنتج حالةً
|
|
43
|
+
* مختلطة: نصف القاعدة من الأرشيف ونصفها من قبل الاستعادة. تُحذَف بعد التحقّق وقبل الكتابة.
|
|
44
|
+
*/
|
|
45
|
+
export declare function clearWalSiblings(profile: Profile): void;
|
|
46
|
+
//# sourceMappingURL=restore.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.d.ts","sourceRoot":"","sources":["../../src/backup/restore.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAkC,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAcnF,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,cAAc,CAAC;IACzB,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAwBD,wEAAwE;AACxE,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAqC3E;AAED,qBAAa,cAAe,SAAQ,KAAK;CAAG;AAE5C;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAaxF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAuBtF;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,yEAAyE;AACzE,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,GAAG,gBAAgB,EAAE,CAa3F;AAED,sFAAsF;AACtF,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAsCpF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAKvD"}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import { createWriteStream, existsSync, mkdirSync, rmSync } from "node:fs";
|
|
2
|
+
import { dirname, join, normalize, resolve, sep } from "node:path";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
import yauzl from "yauzl";
|
|
5
|
+
import { ARCHIVE_VERSION, SNAPSHOT_NAME } from "./archive.js";
|
|
6
|
+
function openArchive(file) {
|
|
7
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
8
|
+
yauzl.open(file, { lazyEntries: true, autoClose: false }, (error, zip) => {
|
|
9
|
+
if (error || !zip)
|
|
10
|
+
rejectPromise(error ?? new Error("the archive could not be opened"));
|
|
11
|
+
else
|
|
12
|
+
resolvePromise(zip);
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
}
|
|
16
|
+
function readEntryText(zip, entry) {
|
|
17
|
+
return new Promise((resolvePromise, rejectPromise) => {
|
|
18
|
+
zip.openReadStream(entry, (error, stream) => {
|
|
19
|
+
if (error || !stream)
|
|
20
|
+
return rejectPromise(error ?? new Error("unreadable entry"));
|
|
21
|
+
const chunks = [];
|
|
22
|
+
stream.on("data", (chunk) => chunks.push(chunk));
|
|
23
|
+
stream.on("end", () => resolvePromise(Buffer.concat(chunks).toString("utf8")));
|
|
24
|
+
stream.on("error", rejectPromise);
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
/** يقرأ البيان وقائمة المحتويات بلا كتابة أي بايت. أساس --dry-run. */
|
|
29
|
+
export async function inspectArchive(file) {
|
|
30
|
+
const zip = await openArchive(file);
|
|
31
|
+
const entries = [];
|
|
32
|
+
let manifest;
|
|
33
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
34
|
+
zip.on("entry", (entry) => {
|
|
35
|
+
if (entry.fileName.endsWith("/")) {
|
|
36
|
+
zip.readEntry();
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
entries.push({ name: entry.fileName, bytes: entry.uncompressedSize });
|
|
40
|
+
if (entry.fileName === "manifest.json") {
|
|
41
|
+
readEntryText(zip, entry)
|
|
42
|
+
.then((text) => {
|
|
43
|
+
manifest = JSON.parse(text);
|
|
44
|
+
zip.readEntry();
|
|
45
|
+
})
|
|
46
|
+
.catch(rejectPromise);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
zip.readEntry();
|
|
50
|
+
});
|
|
51
|
+
zip.on("end", () => resolvePromise());
|
|
52
|
+
zip.on("error", rejectPromise);
|
|
53
|
+
zip.readEntry();
|
|
54
|
+
});
|
|
55
|
+
zip.close();
|
|
56
|
+
if (!manifest)
|
|
57
|
+
throw new Error("this archive has no manifest.json — it was not produced by fantastic backup.");
|
|
58
|
+
return { manifest, entries };
|
|
59
|
+
}
|
|
60
|
+
export class RestoreRefused extends Error {
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* يتحقّق من التوافق **قبل** أي كتابة.
|
|
64
|
+
*
|
|
65
|
+
* أحدث ⇒ رفض. أقدم ⇒ مقبول: الهجرات تمضي إلى الأمام عند أول إقلاع، وذاك مسار مدعوم.
|
|
66
|
+
*/
|
|
67
|
+
export function assertCompatible(manifest, currentRevision) {
|
|
68
|
+
if (manifest.archiveVersion > ARCHIVE_VERSION) {
|
|
69
|
+
throw new RestoreRefused(`This archive uses format ${manifest.archiveVersion}; this CLI understands ${ARCHIVE_VERSION}. Update the CLI.`);
|
|
70
|
+
}
|
|
71
|
+
if (manifest.schemaRevision > currentRevision) {
|
|
72
|
+
throw new RestoreRefused(`This archive was taken at schema revision ${manifest.schemaRevision}, but this installation is at ` +
|
|
73
|
+
`${currentRevision}. Restoring it would leave the database ahead of the code. Update Fantastic first.`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* وجهة كل مدخل داخل الأرشيف. يُعيد undefined لما لا يُستعاد (السجلّات مثلًا).
|
|
78
|
+
*
|
|
79
|
+
* **يرفض المسارات الهاربة.** أرشيف مُعَدّ يدويًا يستطيع حمل ../../windows/system32/...، وفكّه
|
|
80
|
+
* بلا فحص يكتب خارج مجلد التثبيت. الفحص هنا لأن هذا هو الموضع الوحيد الذي يتحوّل فيه اسمٌ داخل
|
|
81
|
+
* أرشيف إلى مسار على القرص.
|
|
82
|
+
*/
|
|
83
|
+
export function destinationFor(profile, entryName) {
|
|
84
|
+
const parts = entryName.split("/");
|
|
85
|
+
const [top, ...rest] = parts;
|
|
86
|
+
if (rest.length === 0 && top !== "manifest.json")
|
|
87
|
+
return undefined;
|
|
88
|
+
const base = top === "database"
|
|
89
|
+
? profile.dataDir
|
|
90
|
+
: top === "data"
|
|
91
|
+
? profile.dataDir
|
|
92
|
+
: top === "state"
|
|
93
|
+
? profile.stateDir
|
|
94
|
+
: undefined;
|
|
95
|
+
if (!base)
|
|
96
|
+
return undefined;
|
|
97
|
+
const target = resolve(base, ...rest);
|
|
98
|
+
const root = resolve(base);
|
|
99
|
+
// خارج الجذر ⇒ محاولة هروب. لا نصحّحها بل نتجاهل المدخل ونمضي.
|
|
100
|
+
if (target !== root && !normalize(target).startsWith(root + sep))
|
|
101
|
+
return undefined;
|
|
102
|
+
return target;
|
|
103
|
+
}
|
|
104
|
+
/** ما الذي سيُكتب وما الذي سيُكتب **فوقه**. هذا هو مخرَج --dry-run. */
|
|
105
|
+
export function planRestore(profile, contents) {
|
|
106
|
+
const plan = [];
|
|
107
|
+
for (const entry of contents.entries) {
|
|
108
|
+
if (entry.name === "manifest.json")
|
|
109
|
+
continue;
|
|
110
|
+
const to = destinationFor(profile, entry.name);
|
|
111
|
+
if (!to)
|
|
112
|
+
continue;
|
|
113
|
+
plan.push({ from: entry.name, to, bytes: entry.bytes, overwrites: existsSync(to) });
|
|
114
|
+
}
|
|
115
|
+
return plan;
|
|
116
|
+
}
|
|
117
|
+
/** يفكّ الأرشيف فعلًا. يُستدعى بعد assertCompatible وبعد تأكيد صريح من المستخدم. */
|
|
118
|
+
export async function extractArchive(profile, file) {
|
|
119
|
+
const zip = await openArchive(file);
|
|
120
|
+
let written = 0;
|
|
121
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
122
|
+
zip.on("entry", (entry) => {
|
|
123
|
+
if (entry.fileName.endsWith("/") || entry.fileName === "manifest.json") {
|
|
124
|
+
zip.readEntry();
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
const destination = destinationFor(profile, entry.fileName);
|
|
128
|
+
if (!destination) {
|
|
129
|
+
zip.readEntry();
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
zip.openReadStream(entry, (error, stream) => {
|
|
133
|
+
if (error || !stream)
|
|
134
|
+
return rejectPromise(error ?? new Error(`unreadable: ${entry.fileName}`));
|
|
135
|
+
mkdirSync(dirname(destination), { recursive: true });
|
|
136
|
+
pipeline(stream, createWriteStream(destination))
|
|
137
|
+
.then(() => {
|
|
138
|
+
written += 1;
|
|
139
|
+
zip.readEntry();
|
|
140
|
+
})
|
|
141
|
+
.catch(rejectPromise);
|
|
142
|
+
});
|
|
143
|
+
});
|
|
144
|
+
zip.on("end", () => resolvePromise());
|
|
145
|
+
zip.on("error", rejectPromise);
|
|
146
|
+
zip.readEntry();
|
|
147
|
+
});
|
|
148
|
+
zip.close();
|
|
149
|
+
return written;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* يزيل ملفَّي WAL المرافقَين قبل الاستعادة.
|
|
153
|
+
*
|
|
154
|
+
* لولا ذلك لبقي -wal قديمٌ بجوار قاعدةٍ مستعادة، فيعيد SQLite تشغيل كتاباتٍ لا تخصّها ويُنتج حالةً
|
|
155
|
+
* مختلطة: نصف القاعدة من الأرشيف ونصفها من قبل الاستعادة. تُحذَف بعد التحقّق وقبل الكتابة.
|
|
156
|
+
*/
|
|
157
|
+
export function clearWalSiblings(profile) {
|
|
158
|
+
for (const suffix of ["-wal", "-shm"]) {
|
|
159
|
+
const path = join(profile.dataDir, `${SNAPSHOT_NAME}${suffix}`);
|
|
160
|
+
if (existsSync(path))
|
|
161
|
+
rmSync(path, { force: true });
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
//# sourceMappingURL=restore.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"restore.js","sourceRoot":"","sources":["../../src/backup/restore.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { Command } from "@oclif/core";
|
|
2
|
+
import type { Profile } from "./profiles/types.js";
|
|
3
|
+
/**
|
|
4
|
+
* AR: عقد رموز الخروج، معروضًا في مساعدة كل أمر (017/FR-032، T075). ليس تفصيلًا داخليًا: سكربت
|
|
5
|
+
* بوّابة يفرّق به بين «المنفذ محجوز» و«التشخيص وجد عائقًا» دون أن يحلّل نصًّا إنجليزيًا.
|
|
6
|
+
* EN: The exit-code contract, shown in every command's help (017/FR-032, T075). Not an internal
|
|
7
|
+
* detail: a gate script uses it to tell "the port was busy" from "diagnosis found a blocker"
|
|
8
|
+
* without parsing English prose.
|
|
9
|
+
*/
|
|
10
|
+
export declare const EXIT_CODE_HELP: string;
|
|
11
|
+
export declare abstract class BaseCommand extends Command {
|
|
12
|
+
static baseFlags: {
|
|
13
|
+
profile: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
14
|
+
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
|
|
15
|
+
/**
|
|
16
|
+
* AR: أيّ منتجٍ يقصد هذا الأمر؟ (٠٢٦)
|
|
17
|
+
*
|
|
18
|
+
* **يُستنتَج عند الوحدة ويُطلَب عند التعدّد.** أمرُ إيقافٍ يصيب الجهاز الخطأ في استراحةٍ
|
|
19
|
+
* تعمل أسوأ من أمرٍ يسأل — ولذلك لا تخمين هنا، والرفض يعدّد الأسماء بدل أن يقول «حدّد».
|
|
20
|
+
*
|
|
21
|
+
* وموضعه في الأساس لا في كل أمر: سطرٌ يُكرَّر في ستّةٍ وثلاثين ملفًّا يُنسى في السابع
|
|
22
|
+
* والثلاثين، فيصير أمرٌ واحدٌ لا يقبل العَلَم بلا أن يلاحظ أحد.
|
|
23
|
+
* EN: Which product does this command act on? (026)
|
|
24
|
+
*
|
|
25
|
+
* **Inferred when there is one, required when there are several.** A stop command hitting
|
|
26
|
+
* the wrong appliance in a working rest-house is worse than a command that asks — so nothing
|
|
27
|
+
* is guessed here, and the refusal lists the names rather than saying "specify one".
|
|
28
|
+
*
|
|
29
|
+
* It belongs in the base rather than in every command: a line repeated across thirty-six
|
|
30
|
+
* files is forgotten in the thirty-seventh, leaving one command that ignores the flag with
|
|
31
|
+
* nobody noticing.
|
|
32
|
+
*/
|
|
33
|
+
product: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
|
|
34
|
+
};
|
|
35
|
+
/**
|
|
36
|
+
* AR: يُنفَّذ قبل جسم أيّ أمر (oclif يناديها لكل أمر). وهو الموضع الوحيد الذي يضمن أن **كل**
|
|
37
|
+
* أمرٍ يمرّ بفحص بيئة التشغيل، بلا سطرٍ مكرَّرٍ في ستّةٍ وثلاثين ملفًّا يُنسى في السابع
|
|
38
|
+
* والثلاثين.
|
|
39
|
+
* EN: Runs before any command's body (oclif calls it for every command). It is the one place that
|
|
40
|
+
* guarantees **every** command passes the runtime check, with no line repeated across
|
|
41
|
+
* thirty-six files and forgotten in the thirty-seventh.
|
|
42
|
+
*/
|
|
43
|
+
init(): Promise<void>;
|
|
44
|
+
protected loadProfile(kind?: string, ensureDirs?: boolean, product?: string): Profile;
|
|
45
|
+
/**
|
|
46
|
+
* جواب موحّد حين لا تُجيب النواة (017/FR-015).
|
|
47
|
+
*
|
|
48
|
+
* كل أمر إدارة يمرّ بهذه الحالة، وتكرار صياغتها في اثني عشر ملفًا يُنتج اثنتي عشرة صياغة تختلف
|
|
49
|
+
* قليلًا وتتباعد مع الوقت. **ولا يتراجع أي أمر إلى قراءة البيانات بنفسه**: هذا هو الحدّ الذي
|
|
50
|
+
* يفصل «الـ CLI يعرض» عن «الـ CLI يقرّر».
|
|
51
|
+
*/
|
|
52
|
+
protected coreUnreachable(command: string, profile: Profile, reason: string, json: boolean): never;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=base-command.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-command.d.ts","sourceRoot":"","sources":["../src/base-command.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAC;AAC7C,OAAO,KAAK,EAAE,OAAO,EAAe,MAAM,qBAAqB,CAAC;AAahE;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,QAOkC,CAAC;AAE9D,8BAAsB,WAAY,SAAQ,OAAO;IAC/C,MAAM,CAAC,SAAS;;;QASd;;;;;;;;;;;;;;;;;WAiBG;;MAIH;IAEF;;;;;;;OAOG;IACU,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAalC,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,UAAU,UAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO;IAWlF;;;;;;OAMG;IACH,SAAS,CAAC,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,GAAG,KAAK;CA0BnG"}
|