diff --git a/.eslintrc.json b/.eslintrc.json deleted file mode 100644 index 83479e8..0000000 --- a/.eslintrc.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "root": true, - "parser": "@typescript-eslint/parser", - "parserOptions": { - "ecmaVersion": 6, - "sourceType": "module" - }, - "plugins": [ - "@typescript-eslint" - ], - "rules": { - "@typescript-eslint/class-name-casing": "warn", - "@typescript-eslint/semi": "warn", - "curly": "warn", - "eqeqeq": "warn", - "no-throw-literal": "warn", - "semi": "off" - } -} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..ccc8051 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,7 @@ +# Enforce LF for all text files — prevents the CRLF spurious-diff problem +* text=auto eol=lf + +# Binary assets +*.png binary +*.gif binary +*.vsix binary diff --git a/.gitignore b/.gitignore index 5fe00fe..229be69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,19 @@ +# Build output out +dist +*.tsbuildinfo + +# Dependencies node_modules + +# VS Code extension testing & packaging .vscode-test/ *.vsix + +# Logs +*.log +npm-debug.log* + +# OS +.DS_Store +Thumbs.db diff --git a/.vscode-test.mjs b/.vscode-test.mjs new file mode 100644 index 0000000..f6b6399 --- /dev/null +++ b/.vscode-test.mjs @@ -0,0 +1,25 @@ +import { defineConfig } from '@vscode/test-cli'; +import os from 'node:os'; +import path from 'node:path'; + +// VS Code's default user-data-dir lives inside the project (.vscode-test/user-data). On deep project +// paths that pushes the Extension Host IPC socket past macOS's ~103-char unix-socket limit +// (listen EINVAL: ...-main.sock). Relocate it to a short temp path so `npm test` runs anywhere. +const userDataDir = path.join(os.tmpdir(), 'irt-vscode-test'); + +export default defineConfig({ + tests: [ + { + files: 'out/test/**/*.test.js', + mocha: { + ui: 'bdd', + }, + launchArgs: [ '--user-data-dir', userDataDir ], + }, + ], + coverage: { + includeAll: true, + exclude: [ '**/test/**', '**/*.test.*' ], + reporter: [ 'text', 'html' ], + }, +}); diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3ac9aeb..d7a3ca1 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,5 @@ { - // See http://go.microsoft.com/fwlink/?LinkId=827846 - // for the documentation about the extensions.json format - "recommendations": [ - "dbaeumer.vscode-eslint" - ] + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": ["dbaeumer.vscode-eslint", "connor4312.esbuild-problem-matchers", "ms-vscode.extension-test-runner"] } diff --git a/.vscode/launch.json b/.vscode/launch.json index b1fbaf5..c42edc0 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -9,26 +9,11 @@ "name": "Run Extension", "type": "extensionHost", "request": "launch", - "runtimeExecutable": "${execPath}", "args": [ "--extensionDevelopmentPath=${workspaceFolder}" ], "outFiles": [ - "${workspaceFolder}/out/**/*.js" - ], - "preLaunchTask": "${defaultBuildTask}" - }, - { - "name": "Extension Tests", - "type": "extensionHost", - "request": "launch", - "runtimeExecutable": "${execPath}", - "args": [ - "--extensionDevelopmentPath=${workspaceFolder}", - "--extensionTestsPath=${workspaceFolder}/out/test/suite/index" - ], - "outFiles": [ - "${workspaceFolder}/out/test/**/*.js" + "${workspaceFolder}/dist/**/*.js" ], "preLaunchTask": "${defaultBuildTask}" } diff --git a/.vscode/settings.json b/.vscode/settings.json index 30bf8c2..16a5c02 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,13 @@ // Place your settings in this file to overwrite default and user settings. { - "files.exclude": { - "out": false // set this to true to hide the "out" folder with the compiled JS files - }, - "search.exclude": { - "out": true // set this to false to include "out" folder in search results - }, - // Turn off tsc task auto detection since we have the necessary tasks as npm scripts - "typescript.tsc.autoDetect": "off" -} \ No newline at end of file + "files.exclude": { + "out": false, // set this to true to hide the "out" folder with the compiled JS files + "dist": false // set this to true to hide the "dist" folder with the compiled JS files + }, + "search.exclude": { + "out": true, // set this to false to include "out" folder in search results + "dist": true // set this to false to include "dist" folder in search results + }, + // Turn off tsc task auto detection since we have the necessary tasks as npm scripts + "typescript.tsc.autoDetect": "off" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 3b17e53..db5b3ad 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,10 +4,11 @@ "version": "2.0.0", "tasks": [ { - "type": "npm", - "script": "watch", - "problemMatcher": "$tsc-watch", - "isBackground": true, + "label": "watch", + "dependsOn": [ + "npm: watch:tsc", + "npm: watch:esbuild" + ], "presentation": { "reveal": "never" }, @@ -15,6 +16,49 @@ "kind": "build", "isDefault": true } + }, + { + "type": "npm", + "script": "watch:esbuild", + "group": "build", + "problemMatcher": "$esbuild-watch", + "isBackground": true, + "label": "npm: watch:esbuild", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "type": "npm", + "script": "watch:tsc", + "group": "build", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "label": "npm: watch:tsc", + "presentation": { + "group": "watch", + "reveal": "never" + } + }, + { + "type": "npm", + "script": "watch-tests", + "problemMatcher": "$tsc-watch", + "isBackground": true, + "presentation": { + "reveal": "never", + "group": "watchers" + }, + "group": "build" + }, + { + "label": "tasks: watch-tests", + "dependsOn": [ + "npm: watch", + "npm: watch-tests" + ], + "problemMatcher": [] } ] } diff --git a/.vscodeignore b/.vscodeignore index c06f4a7..e5df550 100644 --- a/.vscodeignore +++ b/.vscodeignore @@ -1,10 +1,20 @@ .vscode/** .vscode-test/** -out/test/** +out/** +node_modules/** src/** .gitignore -vsc-extension-quickstart.md +.gitattributes +esbuild.js **/tsconfig.json -**/.eslintrc.json +**/eslint.config.mjs **/*.map **/*.ts +**/.vscode-test.* +package-lock.json +CLAUDE.md +.claude/** +**/.DS_Store +icon-preview.html +images/icon-source.png +images/icon@256.png diff --git a/CHANGELOG.md b/CHANGELOG.md index 4da34a4..03cfc95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,30 @@ # Changelog +## v1.0.0 (2026-06-28) + +The first stable release — a ground-up relaunch as **Random & Fake Data Generator**. + +### Features + +- Switched the random engine to [`@faker-js/faker`](https://fakerjs.dev) (single locale) for realistic, coherent data. +- Expanded the catalog to ~24 data types — names, email, username, phone, UUID, hash, numbers, boolean, dates, country/city/address, IP/MAC/URL, color, password, words/sentences/lorem, and more. +- **Multi-cursor fill** — insert a different value at every cursor in one step. +- New **Insert Random: Pick…** command — choose any type from a searchable, grouped menu. +- **Clipboard insert type** — set `insertType` to `Clipboard` to copy a generated value to the clipboard instead of inserting it (no editor needed; resolves #4). +- New settings: `insertRandomText.uniquePerCursor`, `insertRandomText.seed` (reproducible output), `insertRandomText.bulkCount`, `insertRandomText.outputFormat` (`plain` / `jsonArray` / `quotedList`), and an opt-in editor context-menu submenu (`insertRandomText.contextMenu.enabled`). + +### Fixes + +- Lorem is now genuinely randomized (previously a fixed substring of one hardcoded string). +- Random string is alphanumeric, so it no longer breaks quote-wrapping. +- Removed the global notification-clearing side effect and a duplicate-draw bug in the animal command. + +### Changes + +- Removed the unused `loremSize`, `hashSize`, and `disableNotifs` settings. +- Existing `extension.insertRandom*` commands continue to work unchanged. +- Modernized the build (esbuild bundle; now requires VS Code 1.97+). + ## v0.1.3 (2020-7-25) ### Changes diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..42a05d3 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,67 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +VS Code extension (display name **"Random & Fake Data Generator"**, id `insert-random-text`, publisher `ElecTreeFrying`) that inserts random / fake / mock data — names, emails, addresses, numbers, dates, UUIDs, lorem ipsum, and ~24 types in all — at **every cursor**. Randomness comes from **`@faker-js/faker`** (single-locale `en`). + +### Project goals (north star) +1. Grow active installs in the random/mock-data category (near-term: pass the category mid-tier; long-term: challenge the leader). Active installs *subtract* on uninstall, so **retention is the real metric** — every defect fix is rank-defending. +2. Value is the engine: each generator is simultaneously a real feature, a searchable command title, and a Quick Pick entry. Breadth = discoverability + utility. + +## Commands + +- `npm run compile` — type-check + lint + **esbuild** bundle (`src/extension.ts` → `dist/extension.js`) +- `npm run watch` — incremental dev build; `watch:esbuild` + `watch:tsc` in parallel (`npm-run-all`). Default build task (auto-runs on F5 via `preLaunchTask`). +- `npm run check-types` — `tsc --noEmit` (esbuild does the actual transpile) +- `npm run lint` — `eslint src` (flat config, `eslint.config.mjs`) +- `npm run package` — production build: `check-types && lint && esbuild --production`. `vscode:prepublish` runs this. +- `npx @vscode/vsce package` — build the `.vsix` (runs prepublish first). Keep the packaged `.vsix` ≤ ~1.5 MB. + +`main` is `./dist/extension.js` (esbuild bundle, **faker inlined**). `dist/` and `out/` are gitignored — build before running. **esbuild's entry is `src/extension.ts`, so that file must keep its name/location** (the entry is configured in `esbuild.js`, which is out of the usual edit scope). + +### Verification (there is no test suite right now) +All tests were removed at the owner's request; **do not (re)introduce tests unless asked.** When they return, they belong in a dedicated **`/test`** directory (matching the sibling `auto-import-relative-path` layout) — never as loose `.spec.ts` files in `src/`. The `test` / `compile-tests` / `test:coverage` scripts and `.vscode-test.mjs` remain as scaffolding. Until then, verify with `check-types` + `lint` + `node esbuild.js --production` + `npx @vscode/vsce package`; for pure logic (`catalog` / `formatter`), a throwaway esbuild-bundled `node` script is the quick sanity check. + +### Running / debugging +Press F5 → **"Run Extension"** opens an Extension Development Host with the extension loaded (the `preLaunchTask` builds first). + +## Architecture + +Five single-responsibility modules. Generation is `vscode`-free and lives apart from the editor glue, so the logic that matters is decoupled from the API surface: + +- **`src/engine.ts`** — faker lifecycle: `load()` (lazy, idempotent), the `faker()` accessor, and `seed()`. Encapsulates the ESM/dynamic-import detail (see Gotchas). No `vscode` import. +- **`src/catalog.ts`** — the **generator registry**: the `Generator` interface and the readonly `generators` array (each `{ id, label, group, hidden?, generate() }`), plus `getGenerator(id)`. Single source of truth — drives generation, the commands, and the Quick Pick. No `vscode` import. +- **`src/formatter.ts`** — **pure** rendering: `buildBlocks(cursorCount, generator, options)` returns one block per cursor; `formatBlock` applies `bulkCount` + `outputFormat` (`plain` / `jsonArray` / `quotedList`) + quote/newline wrapping. No `vscode` import → trivially checkable. +- **`src/configuration.ts`** — `Configuration` reads workspace settings into a typed `Settings` via `read()`; `ConfigKey` holds the package.json key constants; the two enum settings are normalized to booleans here. Depends only on a narrow `WorkspaceLike` seam, not `vscode`. +- **`src/extension.ts`** — thin activation entry. `COMMAND_TO_GENERATOR` maps every command id → a generator id; `activate()` registers them all through one `insertGenerated(id)`, plus the `insertRandomText.pick` Quick Pick. `insertGenerated`: `load()` faker → `applySeed()` → read cached `settings` → `buildBlocks` over `editor.selections` (Cursor mode = multi-cursor fill; Top mode = one block at line 1). + +### Config flow (the key cross-file mechanism) +`extension.ts` holds a single module-level `settings: Settings`. On activate, `watchConfiguration()` snapshots it via `Configuration.read()`, then re-snapshots on any relevant `onDidChangeConfiguration`. Commands read this **cached** `settings`, never re-reading at invocation. Anything bypassing `watchConfiguration` sees stale config. + +### Commands & settings model +- **Two command namespaces.** The original 14 `extension.insertRandom*` ids are kept for **back-compat** (existing keybindings); every new type uses a namespaced `insertRandomText.` id. Both register via `COMMAND_TO_GENERATOR`. +- **Settings are split.** The 4 remaining legacy keys stay **flat & non-namespaced** (`quoteStyle`, `insertType`, `withQuote`, `withNewLine`) for back-compat; **all new keys are namespaced** under `insertRandomText.*` (`uniquePerCursor`, `seed`, `bulkCount`, `outputFormat`, `contextMenu.enabled`). Do **not** migrate the legacy keys. +- **Hidden generators.** The Lorem/Hash Small/Medium/Large back-compat generators carry `hidden: true` so they serve their legacy commands without cluttering the Quick Pick. + +### Adding a generator (the common case) +1. `src/catalog.ts` — add a `{ id, label, group, generate }` entry. It appears in the Quick Pick automatically. +2. `package.json` → `contributes.commands` — add `{ "command": "insertRandomText.", "title": "Insert Random: