vibefast-cli 0.1.1
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/FINAL-STATUS.md +144 -0
- package/HOW-IT-WORKS.md +559 -0
- package/PLAN.md +453 -0
- package/README.md +129 -0
- package/RECIPES-READY.md +172 -0
- package/STATUS.md +199 -0
- package/SUCCESS.md +259 -0
- package/TESTING-CHECKLIST.md +450 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/64907821e2634080acce34618d2f3d4c/blobs/11f2769953c717e188062bc644da97c1fd1e4d6d0813a226ce7567dba759afab0000019a736fb8d4 +1 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite +0 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-shm +0 -0
- package/cloudflare-worker/.wrangler/state/v3/kv/miniflare-KVNamespaceObject/0b03767237c0408301af51ca35d4b09470cbc479c7e5f23cc9de774749d23c59.sqlite-wal +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-shm +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/miniflare-R2BucketObject/d1cc388a1a0ef44dd5669fd1a165d168b61362136c8b5fa50aefd96c72688e54.sqlite-wal +0 -0
- package/cloudflare-worker/.wrangler/state/v3/r2/vibefast-recipes/blobs/620e8cf7c35d9806da25dee237e1d7e8b2432bd98f755b60e2c7f08a48d2c7b90000019a73736484 +0 -0
- package/cloudflare-worker/MIGRATION.md +160 -0
- package/cloudflare-worker/QUICKSTART.md +200 -0
- package/cloudflare-worker/README.md +242 -0
- package/cloudflare-worker/generate-token.js +32 -0
- package/cloudflare-worker/mini-native@latest.zip +0 -0
- package/cloudflare-worker/setup.sh +143 -0
- package/cloudflare-worker/test-recipe/apps/native/src/app/mini/index.tsx +15 -0
- package/cloudflare-worker/test-recipe/recipe.json +16 -0
- package/cloudflare-worker/worker.js +308 -0
- package/cloudflare-worker/wrangler.toml +13 -0
- package/dist/commands/add.d.ts +3 -0
- package/dist/commands/add.d.ts.map +1 -0
- package/dist/commands/add.js +149 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/devices.d.ts +3 -0
- package/dist/commands/devices.d.ts.map +1 -0
- package/dist/commands/devices.js +35 -0
- package/dist/commands/devices.js.map +1 -0
- package/dist/commands/doctor.d.ts +3 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +67 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/list.d.ts +3 -0
- package/dist/commands/list.d.ts.map +1 -0
- package/dist/commands/list.js +40 -0
- package/dist/commands/list.js.map +1 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +23 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +3 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +16 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/commands/remove.d.ts +3 -0
- package/dist/commands/remove.d.ts.map +1 -0
- package/dist/commands/remove.js +67 -0
- package/dist/commands/remove.js.map +1 -0
- package/dist/core/__tests__/journal.test.d.ts +2 -0
- package/dist/core/__tests__/journal.test.d.ts.map +1 -0
- package/dist/core/__tests__/journal.test.js +101 -0
- package/dist/core/__tests__/journal.test.js.map +1 -0
- package/dist/core/__tests__/validate.test.d.ts +2 -0
- package/dist/core/__tests__/validate.test.d.ts.map +1 -0
- package/dist/core/__tests__/validate.test.js +53 -0
- package/dist/core/__tests__/validate.test.js.map +1 -0
- package/dist/core/archive.d.ts +2 -0
- package/dist/core/archive.d.ts.map +1 -0
- package/dist/core/archive.js +59 -0
- package/dist/core/archive.js.map +1 -0
- package/dist/core/auth.d.ts +15 -0
- package/dist/core/auth.d.ts.map +1 -0
- package/dist/core/auth.js +76 -0
- package/dist/core/auth.js.map +1 -0
- package/dist/core/codemod.d.ts +20 -0
- package/dist/core/codemod.d.ts.map +1 -0
- package/dist/core/codemod.js +150 -0
- package/dist/core/codemod.js.map +1 -0
- package/dist/core/fsx.d.ts +12 -0
- package/dist/core/fsx.d.ts.map +1 -0
- package/dist/core/fsx.js +70 -0
- package/dist/core/fsx.js.map +1 -0
- package/dist/core/http.d.ts +30 -0
- package/dist/core/http.d.ts.map +1 -0
- package/dist/core/http.js +95 -0
- package/dist/core/http.js.map +1 -0
- package/dist/core/journal.d.ts +18 -0
- package/dist/core/journal.d.ts.map +1 -0
- package/dist/core/journal.js +34 -0
- package/dist/core/journal.js.map +1 -0
- package/dist/core/log.d.ts +8 -0
- package/dist/core/log.d.ts.map +1 -0
- package/dist/core/log.js +9 -0
- package/dist/core/log.js.map +1 -0
- package/dist/core/pathGuard.d.ts +3 -0
- package/dist/core/pathGuard.d.ts.map +1 -0
- package/dist/core/pathGuard.js +18 -0
- package/dist/core/pathGuard.js.map +1 -0
- package/dist/core/paths.d.ts +11 -0
- package/dist/core/paths.d.ts.map +1 -0
- package/dist/core/paths.js +22 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/validate.d.ts +8 -0
- package/dist/core/validate.d.ts.map +1 -0
- package/dist/core/validate.js +27 -0
- package/dist/core/validate.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/docs/decisions.md +55 -0
- package/package.json +39 -0
- package/recipes/audio-recorder/apps/native/src/app/audio-recorder/index.tsx +5 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-player.tsx +301 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-recorder.tsx +373 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/audio-waveform.tsx +270 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/index.ts +4 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/components/recording-list.tsx +89 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-player-demo.tsx +66 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-cloud.tsx +68 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/audio-recorder-interview.tsx +102 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/basic.tsx +27 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/index.ts +5 -0
- package/recipes/audio-recorder/apps/native/src/features/audio-recorder/demo/with-recording-list-demo.tsx +82 -0
- package/recipes/audio-recorder/recipe.json +22 -0
- package/recipes/audio-recorder@latest.zip +0 -0
- package/recipes/charts/apps/native/src/app/charts/index.tsx +3 -0
- package/recipes/charts/apps/native/src/features/charts/README.md +185 -0
- package/recipes/charts/apps/native/src/features/charts/app/preview.tsx +223 -0
- package/recipes/charts/apps/native/src/features/charts/components/area-chart.tsx +40 -0
- package/recipes/charts/apps/native/src/features/charts/components/bar-chart.tsx +143 -0
- package/recipes/charts/apps/native/src/features/charts/components/candlestick-chart.tsx +196 -0
- package/recipes/charts/apps/native/src/features/charts/components/chart-card.tsx +65 -0
- package/recipes/charts/apps/native/src/features/charts/components/column-chart.tsx +143 -0
- package/recipes/charts/apps/native/src/features/charts/components/doughnut-chart.tsx +246 -0
- package/recipes/charts/apps/native/src/features/charts/components/index.ts +10 -0
- package/recipes/charts/apps/native/src/features/charts/components/line-chart.tsx +308 -0
- package/recipes/charts/apps/native/src/features/charts/components/radar-chart.tsx +180 -0
- package/recipes/charts/apps/native/src/features/charts/components/radial-bar-chart.tsx +188 -0
- package/recipes/charts/apps/native/src/features/charts/components/stacked-area-chart.tsx +265 -0
- package/recipes/charts/apps/native/src/features/charts/components/stacked-bar-chart.tsx +322 -0
- package/recipes/charts/apps/native/src/features/charts/data/mock-data.ts +183 -0
- package/recipes/charts/apps/native/src/features/charts/types/index.ts +66 -0
- package/recipes/charts/recipe.json +22 -0
- package/recipes/charts@latest.zip +0 -0
- package/recipes/chatbot/apps/native/src/app/chatbot/index.tsx +1 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/app/index.tsx +302 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-header-buttons.tsx +59 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-input-bar.tsx +469 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-markdown.tsx +575 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-message-bubble.tsx +246 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/chat-settings-modal.tsx +161 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/image-preview-list.tsx +115 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/code-block.tsx +165 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/index.ts +10 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/markdown/table-renderer.tsx +129 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/message-error-boundary.tsx +78 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/message-list.tsx +173 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/model-selector.tsx +283 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/report-content-modal.tsx +188 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/components/suggested-messages.tsx +67 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/constants/models.ts +20 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/constants/report-reasons.ts +9 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-attachment-cache.ts +143 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-config.ts +664 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chat-handlers.ts +359 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-chatbot-settings.ts +89 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-conversation.ts +79 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-image-picker.ts +122 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-keyboard-coordinator.ts +161 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/hooks/use-smart-scroll-manager.ts +207 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/index.ts +86 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/models.ts +162 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/providers.ts +62 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/models/types.ts +40 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/services/file-uploader.ts +238 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/services/message-handler-service.ts +180 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/types/index.ts +60 -0
- package/recipes/chatbot/apps/native/src/features/chatbot/utils/chat-telemetry.ts +91 -0
- package/recipes/chatbot/recipe.json +22 -0
- package/recipes/chatbot@latest.zip +0 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/gallery.tsx +3 -0
- package/recipes/image-generator/apps/native/src/app/image-generator/index.tsx +3 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/_layout.tsx +25 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/gallery.tsx +217 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/app/index.tsx +237 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/gallery-image.tsx +26 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-detail-modal.tsx +215 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-model-selector.tsx +210 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/components/image-placeholder.tsx +26 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-gallery.ts +71 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator-settings.ts +152 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/hooks/use-image-generator.ts +93 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/models/models.ts +66 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/services/image-gallery-service.ts +98 -0
- package/recipes/image-generator/apps/native/src/features/image-generator/services/image-save-service.ts +121 -0
- package/recipes/image-generator/recipe.json +22 -0
- package/recipes/image-generator@latest.zip +0 -0
- package/recipes/quiz/apps/native/src/app/quiz/index.tsx +47 -0
- package/recipes/quiz/apps/native/src/features/quiz/components/question.tsx +67 -0
- package/recipes/quiz/apps/native/src/features/quiz/config.ts +11 -0
- package/recipes/quiz/apps/native/src/features/quiz/index.tsx +133 -0
- package/recipes/quiz/recipe.json +22 -0
- package/recipes/quiz@latest.zip +0 -0
- package/recipes/tracker-app/apps/native/src/app/tracker-app/index.tsx +1 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/app/index.tsx +108 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/animated-number.tsx +102 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/calorie-card.tsx +66 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/circular-progress.tsx +97 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/floating-add-button.tsx +27 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/macro-card.tsx +80 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/promo-banner.tsx +98 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/recently-logged.tsx +64 -0
- package/recipes/tracker-app/apps/native/src/features/tracker-app/components/week-calendar.tsx +68 -0
- package/recipes/tracker-app/recipe.json +22 -0
- package/recipes/tracker-app@latest.zip +0 -0
- package/recipes/upload-all.sh +32 -0
- package/recipes/voice-bot/apps/native/src/app/voice-bot/index.tsx +27 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/README.md +185 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/conversation-status.tsx +76 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/index.ts +4 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/message-input.tsx +98 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-bot-screen.tsx +173 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/components/voice-controls.tsx +73 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/index.ts +3 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/services/index.ts +1 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/services/use-voice-bot.ts +161 -0
- package/recipes/voice-bot/apps/native/src/features/voice-bot/types.ts +29 -0
- package/recipes/voice-bot/recipe.json +22 -0
- package/recipes/voice-bot@latest.zip +0 -0
- package/scripts/create-recipes.mjs +189 -0
- package/src/commands/add.ts +183 -0
- package/src/commands/devices.ts +38 -0
- package/src/commands/doctor.ts +67 -0
- package/src/commands/list.ts +45 -0
- package/src/commands/login.ts +24 -0
- package/src/commands/logout.ts +15 -0
- package/src/commands/remove.ts +78 -0
- package/src/core/__tests__/journal.test.ts +119 -0
- package/src/core/__tests__/validate.test.ts +64 -0
- package/src/core/archive.ts +69 -0
- package/src/core/auth.ts +103 -0
- package/src/core/codemod.ts +211 -0
- package/src/core/fsx.ts +80 -0
- package/src/core/http.ts +136 -0
- package/src/core/journal.ts +64 -0
- package/src/core/log.ts +9 -0
- package/src/core/pathGuard.ts +22 -0
- package/src/core/paths.ts +33 -0
- package/src/core/validate.ts +44 -0
- package/src/index.ts +27 -0
- package/test-critical-cases.mjs +258 -0
- package/tsconfig.json +21 -0
- package/vitest.config.mts +12 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../src/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAE9C,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,OAAO,CAAC,MAAM,CAAC;KAC3C,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,MAAM,QAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,GAAG,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;QAE1C,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvD,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;YACjC,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC;QAC1E,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;QAEpE,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACpC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,EAAE;gBAC7B,GAAG,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,GAAG,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACtC,GAAG,CAAC,OAAO,CAAC,CAAC,MAAW,EAAE,EAAE;gBAC1B,GAAG,CAAC,KAAK,CAAC,OAAO,MAAM,CAAC,IAAI,MAAM,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;QACL,CAAC;QAED,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,GAAG,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,YAAY,SAmBrB,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { log } from '../core/log.js';
|
|
3
|
+
import { saveToken } from '../core/auth.js';
|
|
4
|
+
export const loginCommand = new Command('login')
|
|
5
|
+
.description('Authenticate with your VibeFast token')
|
|
6
|
+
.requiredOption('--token <token>', 'Your VibeFast license token')
|
|
7
|
+
.action(async (options) => {
|
|
8
|
+
try {
|
|
9
|
+
const token = options.token.trim();
|
|
10
|
+
if (!token || token.length < 10) {
|
|
11
|
+
log.error('Invalid token format');
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
await saveToken(token);
|
|
15
|
+
log.success('Token saved successfully');
|
|
16
|
+
log.info('Run "vf doctor" to verify your setup');
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
log.error(`Login failed: ${error.message}`);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=login.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC;KAC7C,WAAW,CAAC,uCAAuC,CAAC;KACpD,cAAc,CAAC,iBAAiB,EAAE,6BAA6B,CAAC;KAChE,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,EAAE;IACxB,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAEnC,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE,CAAC;YAChC,GAAG,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;YAClC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,SAAS,CAAC,KAAK,CAAC,CAAC;QACvB,GAAG,CAAC,OAAO,CAAC,0BAA0B,CAAC,CAAC;QACxC,GAAG,CAAC,IAAI,CAAC,sCAAsC,CAAC,CAAC;IACnD,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,GAAG,CAAC,KAAK,CAAC,iBAAiB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAIpC,eAAO,MAAM,aAAa,SAUtB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { log } from '../core/log.js';
|
|
3
|
+
import { clearToken } from '../core/auth.js';
|
|
4
|
+
export const logoutCommand = new Command('logout')
|
|
5
|
+
.description('Clear your stored VibeFast token')
|
|
6
|
+
.action(async () => {
|
|
7
|
+
try {
|
|
8
|
+
await clearToken();
|
|
9
|
+
log.success('Token cleared');
|
|
10
|
+
}
|
|
11
|
+
catch (error) {
|
|
12
|
+
log.error(`Logout failed: ${error.message}`);
|
|
13
|
+
process.exit(1);
|
|
14
|
+
}
|
|
15
|
+
});
|
|
16
|
+
//# sourceMappingURL=logout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logout.js","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KAC/C,WAAW,CAAC,kCAAkC,CAAC;KAC/C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,IAAI,CAAC;QACH,MAAM,UAAU,EAAE,CAAC;QACnB,GAAG,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAC/B,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,GAAG,CAAC,KAAK,CAAC,kBAAkB,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.d.ts","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQpC,eAAO,MAAM,aAAa,SAqEtB,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { log } from '../core/log.js';
|
|
3
|
+
import { getPaths } from '../core/paths.js';
|
|
4
|
+
import { validateSignature, validateTarget } from '../core/validate.js';
|
|
5
|
+
import { getEntry, removeEntry } from '../core/journal.js';
|
|
6
|
+
import { deleteFile } from '../core/fsx.js';
|
|
7
|
+
import { removeNavLinkNative, removeNavLinkWeb } from '../core/codemod.js';
|
|
8
|
+
export const removeCommand = new Command('remove')
|
|
9
|
+
.description('Remove a VibeFast feature from your project')
|
|
10
|
+
.argument('<feature>', 'Feature name to remove')
|
|
11
|
+
.option('--target <target>', 'Target platform (native or web)', 'native')
|
|
12
|
+
.option('--dry-run', 'Preview changes without applying')
|
|
13
|
+
.action(async (feature, options) => {
|
|
14
|
+
try {
|
|
15
|
+
const paths = getPaths();
|
|
16
|
+
const target = options.target;
|
|
17
|
+
// Validate setup
|
|
18
|
+
const config = await validateSignature(paths.signatureFile);
|
|
19
|
+
validateTarget(target, config.targets);
|
|
20
|
+
if (options.dryRun) {
|
|
21
|
+
log.info('[DRY RUN] No changes will be made');
|
|
22
|
+
}
|
|
23
|
+
// Get journal entry (do not mutate journal yet)
|
|
24
|
+
const entry = await getEntry(paths.journalFile, feature, target);
|
|
25
|
+
if (!entry) {
|
|
26
|
+
log.warn(`${feature} is not installed for ${target}`);
|
|
27
|
+
log.info('Run "vf list" to see installed features');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
log.info(`Removing ${feature} from ${target}...`);
|
|
31
|
+
// Delete files
|
|
32
|
+
for (const file of entry.files) {
|
|
33
|
+
log.info(`Deleting ${file}`);
|
|
34
|
+
if (!options.dryRun) {
|
|
35
|
+
await deleteFile(file);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Remove nav link
|
|
39
|
+
if (entry.insertedNav) {
|
|
40
|
+
log.info('Removing navigation link...');
|
|
41
|
+
const navFile = target === 'native' ? paths.nativeNavFile : paths.webNavFile;
|
|
42
|
+
const removeFn = target === 'native' ? removeNavLinkNative : removeNavLinkWeb;
|
|
43
|
+
const href = entry.navHref
|
|
44
|
+
? entry.navHref
|
|
45
|
+
: target === 'native'
|
|
46
|
+
? `/(root)/(protected)/${feature}`
|
|
47
|
+
: `/${feature}`;
|
|
48
|
+
if (!options.dryRun) {
|
|
49
|
+
await removeFn(navFile, href);
|
|
50
|
+
}
|
|
51
|
+
log.success('Navigation link removed');
|
|
52
|
+
}
|
|
53
|
+
if (!options.dryRun) {
|
|
54
|
+
await removeEntry(paths.journalFile, entry.feature, entry.target);
|
|
55
|
+
}
|
|
56
|
+
log.success(`${feature} removed successfully!`);
|
|
57
|
+
log.info(`Files deleted: ${entry.files.length}`);
|
|
58
|
+
if (options.dryRun) {
|
|
59
|
+
log.warn('This was a dry run. Run without --dry-run to apply changes.');
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
log.error(`Removal failed: ${error.message}`);
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
//# sourceMappingURL=remove.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"remove.js","sourceRoot":"","sources":["../../src/commands/remove.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.test.d.ts","sourceRoot":"","sources":["../../../src/core/__tests__/journal.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { readJournal, writeJournal, addEntry, removeEntry, getEntry } from '../journal.js';
|
|
3
|
+
import { deleteFile } from '../fsx.js';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
7
|
+
describe('journal', () => {
|
|
8
|
+
let testDir;
|
|
9
|
+
let journalPath;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
testDir = join(tmpdir(), 'vibefast-test', randomUUID());
|
|
12
|
+
journalPath = join(testDir, '.vibefast', 'journal.json');
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
await deleteFile(testDir);
|
|
16
|
+
});
|
|
17
|
+
it('should return empty journal if file missing', async () => {
|
|
18
|
+
const journal = await readJournal(journalPath);
|
|
19
|
+
expect(journal.entries).toEqual([]);
|
|
20
|
+
});
|
|
21
|
+
it('should write and read journal', async () => {
|
|
22
|
+
const journal = {
|
|
23
|
+
entries: [
|
|
24
|
+
{
|
|
25
|
+
feature: 'test',
|
|
26
|
+
target: 'native',
|
|
27
|
+
files: ['/test/file.ts'],
|
|
28
|
+
insertedNav: true,
|
|
29
|
+
ts: Date.now(),
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
};
|
|
33
|
+
await writeJournal(journalPath, journal);
|
|
34
|
+
const read = await readJournal(journalPath);
|
|
35
|
+
expect(read.entries).toHaveLength(1);
|
|
36
|
+
expect(read.entries[0].feature).toBe('test');
|
|
37
|
+
});
|
|
38
|
+
it('should add entry', async () => {
|
|
39
|
+
const entry = {
|
|
40
|
+
feature: 'mini-native',
|
|
41
|
+
target: 'native',
|
|
42
|
+
files: ['/apps/native/src/app/mini/index.tsx'],
|
|
43
|
+
insertedNav: true,
|
|
44
|
+
ts: Date.now(),
|
|
45
|
+
};
|
|
46
|
+
await addEntry(journalPath, entry);
|
|
47
|
+
const journal = await readJournal(journalPath);
|
|
48
|
+
expect(journal.entries).toHaveLength(1);
|
|
49
|
+
expect(journal.entries[0].feature).toBe('mini-native');
|
|
50
|
+
});
|
|
51
|
+
it('should replace existing entry for same feature+target', async () => {
|
|
52
|
+
const entry1 = {
|
|
53
|
+
feature: 'test',
|
|
54
|
+
target: 'native',
|
|
55
|
+
files: ['/file1.ts'],
|
|
56
|
+
insertedNav: true,
|
|
57
|
+
ts: 1000,
|
|
58
|
+
};
|
|
59
|
+
const entry2 = {
|
|
60
|
+
feature: 'test',
|
|
61
|
+
target: 'native',
|
|
62
|
+
files: ['/file2.ts'],
|
|
63
|
+
insertedNav: false,
|
|
64
|
+
ts: 2000,
|
|
65
|
+
};
|
|
66
|
+
await addEntry(journalPath, entry1);
|
|
67
|
+
await addEntry(journalPath, entry2);
|
|
68
|
+
const journal = await readJournal(journalPath);
|
|
69
|
+
expect(journal.entries).toHaveLength(1);
|
|
70
|
+
expect(journal.entries[0].ts).toBe(2000);
|
|
71
|
+
});
|
|
72
|
+
it('should remove entry', async () => {
|
|
73
|
+
const entry = {
|
|
74
|
+
feature: 'test',
|
|
75
|
+
target: 'native',
|
|
76
|
+
files: ['/file.ts'],
|
|
77
|
+
insertedNav: true,
|
|
78
|
+
ts: Date.now(),
|
|
79
|
+
};
|
|
80
|
+
await addEntry(journalPath, entry);
|
|
81
|
+
const removed = await removeEntry(journalPath, 'test', 'native');
|
|
82
|
+
expect(removed).not.toBeNull();
|
|
83
|
+
expect(removed?.feature).toBe('test');
|
|
84
|
+
const journal = await readJournal(journalPath);
|
|
85
|
+
expect(journal.entries).toHaveLength(0);
|
|
86
|
+
});
|
|
87
|
+
it('should get entry', async () => {
|
|
88
|
+
const entry = {
|
|
89
|
+
feature: 'test',
|
|
90
|
+
target: 'native',
|
|
91
|
+
files: ['/file.ts'],
|
|
92
|
+
insertedNav: true,
|
|
93
|
+
ts: Date.now(),
|
|
94
|
+
};
|
|
95
|
+
await addEntry(journalPath, entry);
|
|
96
|
+
const found = await getEntry(journalPath, 'test', 'native');
|
|
97
|
+
expect(found).not.toBeNull();
|
|
98
|
+
expect(found?.feature).toBe('test');
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
//# sourceMappingURL=journal.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"journal.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/journal.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.test.d.ts","sourceRoot":"","sources":["../../../src/core/__tests__/validate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'vitest';
|
|
2
|
+
import { validateSignature, validateTarget } from '../validate.js';
|
|
3
|
+
import { writeFileContent, deleteFile } from '../fsx.js';
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import { tmpdir } from 'os';
|
|
6
|
+
import { randomUUID } from 'crypto';
|
|
7
|
+
describe('validate', () => {
|
|
8
|
+
let testDir;
|
|
9
|
+
let signaturePath;
|
|
10
|
+
beforeEach(async () => {
|
|
11
|
+
testDir = join(tmpdir(), 'vibefast-test', randomUUID());
|
|
12
|
+
signaturePath = join(testDir, '.vibefast', 'starter.json');
|
|
13
|
+
});
|
|
14
|
+
afterEach(async () => {
|
|
15
|
+
await deleteFile(testDir);
|
|
16
|
+
});
|
|
17
|
+
describe('validateSignature', () => {
|
|
18
|
+
it('should validate correct signature', async () => {
|
|
19
|
+
const config = {
|
|
20
|
+
name: 'vibefast',
|
|
21
|
+
version: '1.0.0',
|
|
22
|
+
targets: ['native', 'web'],
|
|
23
|
+
};
|
|
24
|
+
await writeFileContent(signaturePath, JSON.stringify(config));
|
|
25
|
+
const result = await validateSignature(signaturePath);
|
|
26
|
+
expect(result.name).toBe('vibefast');
|
|
27
|
+
expect(result.version).toBe('1.0.0');
|
|
28
|
+
expect(result.targets).toEqual(['native', 'web']);
|
|
29
|
+
});
|
|
30
|
+
it('should throw if file missing', async () => {
|
|
31
|
+
await expect(validateSignature(signaturePath)).rejects.toThrow('Not a VibeFast repo');
|
|
32
|
+
});
|
|
33
|
+
it('should throw if name is wrong', async () => {
|
|
34
|
+
const config = { name: 'wrong', version: '1.0.0', targets: ['native'] };
|
|
35
|
+
await writeFileContent(signaturePath, JSON.stringify(config));
|
|
36
|
+
await expect(validateSignature(signaturePath)).rejects.toThrow('Invalid starter name');
|
|
37
|
+
});
|
|
38
|
+
it('should throw if targets empty', async () => {
|
|
39
|
+
const config = { name: 'vibefast', version: '1.0.0', targets: [] };
|
|
40
|
+
await writeFileContent(signaturePath, JSON.stringify(config));
|
|
41
|
+
await expect(validateSignature(signaturePath)).rejects.toThrow('targets must be a non-empty array');
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe('validateTarget', () => {
|
|
45
|
+
it('should accept valid target', () => {
|
|
46
|
+
expect(() => validateTarget('native', ['native', 'web'])).not.toThrow();
|
|
47
|
+
});
|
|
48
|
+
it('should reject invalid target', () => {
|
|
49
|
+
expect(() => validateTarget('invalid', ['native', 'web'])).toThrow('Invalid target');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
//# sourceMappingURL=validate.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.test.js","sourceRoot":"","sources":["../../../src/core/__tests__/validate.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.d.ts","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"AAaA,wBAAsB,cAAc,CAAC,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAuD3F"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import yauzl from 'yauzl';
|
|
2
|
+
import { ensureDir, deleteFile } from './fsx.js';
|
|
3
|
+
import { dirname, resolve } from 'path';
|
|
4
|
+
import { pipeline } from 'stream/promises';
|
|
5
|
+
import { createWriteStream } from 'fs';
|
|
6
|
+
import { ensureWithinBase } from './pathGuard.js';
|
|
7
|
+
function isSymlink(entry) {
|
|
8
|
+
// Upper 4 bits of external attributes encode the file type on Unix
|
|
9
|
+
const fileType = (entry.externalFileAttributes >>> 28) & 0xf;
|
|
10
|
+
return fileType === 0xa;
|
|
11
|
+
}
|
|
12
|
+
export async function extractZipSafe(zipPath, destinationDir) {
|
|
13
|
+
const destRoot = resolve(destinationDir);
|
|
14
|
+
await deleteFile(destRoot);
|
|
15
|
+
await ensureDir(destRoot);
|
|
16
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
17
|
+
yauzl.open(zipPath, { lazyEntries: true }, (openErr, zipfile) => {
|
|
18
|
+
if (openErr || !zipfile) {
|
|
19
|
+
rejectPromise(openErr || new Error('Unable to read zip archive'));
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
const bail = (err) => {
|
|
23
|
+
zipfile.close();
|
|
24
|
+
rejectPromise(err);
|
|
25
|
+
};
|
|
26
|
+
zipfile.readEntry();
|
|
27
|
+
zipfile.on('entry', (entry) => {
|
|
28
|
+
const normalizedName = entry.fileName.replace(/\\/g, '/');
|
|
29
|
+
const targetPath = ensureWithinBase(destRoot, resolve(destRoot, normalizedName), `Archive entry ${entry.fileName}`);
|
|
30
|
+
if (/\/$/.test(normalizedName)) {
|
|
31
|
+
ensureDir(targetPath)
|
|
32
|
+
.then(() => zipfile.readEntry())
|
|
33
|
+
.catch(bail);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (isSymlink(entry)) {
|
|
37
|
+
bail(new Error(`Archive entry ${entry.fileName} is a symlink, which is not supported`));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
zipfile.openReadStream(entry, (streamErr, readStream) => {
|
|
41
|
+
if (streamErr || !readStream) {
|
|
42
|
+
bail(streamErr || new Error(`Failed to read ${entry.fileName}`));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
ensureDir(dirname(targetPath))
|
|
46
|
+
.then(() => pipeline(readStream, createWriteStream(targetPath)))
|
|
47
|
+
.then(() => zipfile.readEntry())
|
|
48
|
+
.catch(bail);
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
zipfile.on('end', () => {
|
|
52
|
+
zipfile.close();
|
|
53
|
+
resolvePromise();
|
|
54
|
+
});
|
|
55
|
+
zipfile.on('error', bail);
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=archive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive.js","sourceRoot":"","sources":["../../src/core/archive.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export interface AuthConfig {
|
|
2
|
+
token?: string;
|
|
3
|
+
deviceId?: string;
|
|
4
|
+
}
|
|
5
|
+
export interface DeviceInfo {
|
|
6
|
+
id: string;
|
|
7
|
+
os: string;
|
|
8
|
+
arch: string;
|
|
9
|
+
version: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function saveToken(token: string): Promise<void>;
|
|
12
|
+
export declare function getToken(): Promise<string | null>;
|
|
13
|
+
export declare function clearToken(): Promise<void>;
|
|
14
|
+
export declare function getDeviceInfo(): Promise<DeviceInfo>;
|
|
15
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,UAAU;IACzB,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB5D;AAED,wBAAsB,QAAQ,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CASvD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAQhD;AAED,wBAAsB,aAAa,IAAI,OAAO,CAAC,UAAU,CAAC,CA6BzD"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { readFileContent, writeFileContent, ensureDir, exists } from './fsx.js';
|
|
2
|
+
import { getConfigPath } from './paths.js';
|
|
3
|
+
import { randomUUID } from 'crypto';
|
|
4
|
+
import { hostname, userInfo, platform, arch } from 'os';
|
|
5
|
+
import { dirname } from 'path';
|
|
6
|
+
export async function saveToken(token) {
|
|
7
|
+
const configPath = getConfigPath();
|
|
8
|
+
await ensureDir(dirname(configPath));
|
|
9
|
+
let config = {};
|
|
10
|
+
if (await exists(configPath)) {
|
|
11
|
+
const content = await readFileContent(configPath);
|
|
12
|
+
config = JSON.parse(content);
|
|
13
|
+
}
|
|
14
|
+
config.token = token;
|
|
15
|
+
// Generate device ID if not exists
|
|
16
|
+
if (!config.deviceId) {
|
|
17
|
+
config.deviceId = generateDeviceId();
|
|
18
|
+
}
|
|
19
|
+
await writeFileContent(configPath, JSON.stringify(config, null, 2), { force: true });
|
|
20
|
+
}
|
|
21
|
+
export async function getToken() {
|
|
22
|
+
const configPath = getConfigPath();
|
|
23
|
+
if (!(await exists(configPath))) {
|
|
24
|
+
return null;
|
|
25
|
+
}
|
|
26
|
+
const content = await readFileContent(configPath);
|
|
27
|
+
const config = JSON.parse(content);
|
|
28
|
+
return config.token || null;
|
|
29
|
+
}
|
|
30
|
+
export async function clearToken() {
|
|
31
|
+
const configPath = getConfigPath();
|
|
32
|
+
if (await exists(configPath)) {
|
|
33
|
+
const content = await readFileContent(configPath);
|
|
34
|
+
const config = JSON.parse(content);
|
|
35
|
+
delete config.token;
|
|
36
|
+
await writeFileContent(configPath, JSON.stringify(config, null, 2), { force: true });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
export async function getDeviceInfo() {
|
|
40
|
+
const configPath = getConfigPath();
|
|
41
|
+
let deviceId;
|
|
42
|
+
if (await exists(configPath)) {
|
|
43
|
+
const content = await readFileContent(configPath);
|
|
44
|
+
const config = JSON.parse(content);
|
|
45
|
+
deviceId = config.deviceId || generateDeviceId();
|
|
46
|
+
if (!config.deviceId) {
|
|
47
|
+
config.deviceId = deviceId;
|
|
48
|
+
await writeFileContent(configPath, JSON.stringify(config, null, 2), { force: true });
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
deviceId = generateDeviceId();
|
|
53
|
+
await ensureDir(dirname(configPath));
|
|
54
|
+
await writeFileContent(configPath, JSON.stringify({ deviceId }, null, 2), { force: true });
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
id: deviceId,
|
|
58
|
+
os: platform(),
|
|
59
|
+
arch: arch(),
|
|
60
|
+
version: '0.1.0',
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
function generateDeviceId() {
|
|
64
|
+
try {
|
|
65
|
+
const user = userInfo().username;
|
|
66
|
+
const host = hostname();
|
|
67
|
+
const os = platform();
|
|
68
|
+
const uuid = randomUUID();
|
|
69
|
+
// Create a stable but unique device ID
|
|
70
|
+
return `${user}-${host}-${os}-${uuid}`.slice(0, 64);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return randomUUID();
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/core/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export interface NavLink {
|
|
2
|
+
href: string;
|
|
3
|
+
label: string;
|
|
4
|
+
}
|
|
5
|
+
export declare function insertNavLinkNative(filePath: string, link: NavLink & {
|
|
6
|
+
icon?: string;
|
|
7
|
+
color?: string;
|
|
8
|
+
}, options?: {
|
|
9
|
+
dryRun?: boolean;
|
|
10
|
+
}): Promise<boolean>;
|
|
11
|
+
export declare function removeNavLinkNative(filePath: string, href: string, options?: {
|
|
12
|
+
dryRun?: boolean;
|
|
13
|
+
}): Promise<boolean>;
|
|
14
|
+
export declare function insertNavLinkWeb(filePath: string, link: NavLink, options?: {
|
|
15
|
+
dryRun?: boolean;
|
|
16
|
+
}): Promise<boolean>;
|
|
17
|
+
export declare function removeNavLinkWeb(filePath: string, href: string, options?: {
|
|
18
|
+
dryRun?: boolean;
|
|
19
|
+
}): Promise<boolean>;
|
|
20
|
+
//# sourceMappingURL=codemod.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codemod.d.ts","sourceRoot":"","sources":["../../src/core/codemod.ts"],"names":[],"mappings":"AAmCA,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,GAAG;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,EACjD,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,CAkDlB;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,CAuBlB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,OAAO,EACb,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,CAiClB;AAED,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,MAAM,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7B,OAAO,CAAC,OAAO,CAAC,CA0ClB"}
|