🚨 Shai-Hulud Strikes Again:834 Packages Compromised.Technical Analysis
Socket
Book a DemoInstallSign in
Socket

appstash

Package Overview
Dependencies
Maintainers
1
Versions
5
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

appstash

Simple, clean application directory resolution

latest
Source
npmnpm
Version
0.2.4
Version published
Weekly downloads
512
406.93%
Maintainers
1
Weekly downloads
 
Created
Source

appstash

Simple, clean application directory resolution for Node.js applications.

Installation

npm install appstash

Features

  • Simple API: Just one function to get all your app directories
  • Clean structure: ~/.<tool>/{config,cache,data,logs} + /tmp/<tool>
  • Graceful fallback: XDG directories → tmp if home fails
  • No throws: Always returns valid paths, never throws errors
  • TypeScript: Full type definitions included
  • Zero dependencies: Pure Node.js implementation

Usage

Basic Usage

import { appstash } from 'appstash';

// Get directories for your tool
const dirs = appstash('pgpm');

console.log(dirs.config); // ~/.pgpm/config
console.log(dirs.cache);  // ~/.pgpm/cache
console.log(dirs.data);   // ~/.pgpm/data
console.log(dirs.logs);   // ~/.pgpm/logs
console.log(dirs.tmp);    // /tmp/pgpm

Create Directories

import { appstash } from 'appstash';

// Get directories and create them
const dirs = appstash('pgpm', { ensure: true });

// All directories now exist
// dirs.usedFallback will be true if XDG or tmp fallback was used

Resolve Paths

import { appstash, resolve } from 'appstash';

const dirs = appstash('pgpm');

// Resolve paths within directories
const configFile = resolve(dirs, 'config', 'settings.json');
// Returns: ~/.pgpm/config/settings.json

const cacheDir = resolve(dirs, 'cache', 'repos', 'my-repo');
// Returns: ~/.pgpm/cache/repos/my-repo

Manual Ensure

import { appstash, ensure } from 'appstash';

const dirs = appstash('pgpm');

// Create directories later
const result = ensure(dirs);

console.log(result.created);      // ['~/.pgpm', '~/.pgpm/config', ...]
console.log(result.usedFallback); // false (or true if fallback was used)

API

appstash(tool, options?)

Get application directories for a tool.

Parameters:

  • tool (string): Tool name (e.g., 'pgpm', 'lql')
  • options (object, optional):
    • baseDir (string): Base directory (defaults to os.homedir())
    • useXdgFallback (boolean): Use XDG fallback if home fails (default: true)
    • ensure (boolean): Automatically create directories (default: false)
    • tmpRoot (string): Root for temp directory (defaults to os.tmpdir())

Returns: AppStashResult

{
  root: string;        // ~/.<tool>
  config: string;      // ~/.<tool>/config
  cache: string;       // ~/.<tool>/cache
  data: string;        // ~/.<tool>/data
  logs: string;        // ~/.<tool>/logs
  tmp: string;         // /tmp/<tool>
  usedFallback?: boolean; // true if XDG or tmp fallback was used
}

ensure(dirs)

Create directories if they don't exist. Never throws.

Parameters:

  • dirs (AppStashResult): Directory paths from appstash()

Returns: EnsureResult

{
  created: string[];     // Directories that were created
  usedFallback: boolean; // true if XDG or tmp fallback was used
}

resolve(dirs, kind, ...parts)

Resolve a path within a specific directory.

Parameters:

  • dirs (AppStashResult): Directory paths from appstash()
  • kind ('config' | 'cache' | 'data' | 'logs' | 'tmp'): Directory kind
  • parts (string[]): Path parts to join

Returns: string - Resolved path

Directory Structure

Primary (POSIX-style)

~/.<tool>/
  ├── config/    # Configuration files
  ├── cache/     # Cached data
  ├── data/      # Application data
  └── logs/      # Log files

/tmp/<tool>/     # Temporary files

Fallback (XDG)

If home directory is unavailable or creation fails, falls back to XDG:

~/.config/<tool>/           # Config
~/.cache/<tool>/            # Cache
~/.local/share/<tool>/      # Data
~/.local/state/<tool>/logs/ # Logs

Final Fallback (tmp)

If XDG also fails, falls back to system temp:

/tmp/<tool>/
  ├── config/
  ├── cache/
  ├── data/
  └── logs/

Examples

Configuration File

import { appstash, resolve } from 'appstash';
import fs from 'fs';

const dirs = appstash('myapp', { ensure: true });
const configPath = resolve(dirs, 'config', 'settings.json');

// Write config
fs.writeFileSync(configPath, JSON.stringify({ theme: 'dark' }));

// Read config
const config = JSON.parse(fs.readFileSync(configPath, 'utf8'));

Cache Management

import { appstash, resolve } from 'appstash';
import fs from 'fs';

const dirs = appstash('myapp', { ensure: true });
const cacheFile = resolve(dirs, 'cache', 'data.json');

// Check if cached
if (fs.existsSync(cacheFile)) {
  const cached = JSON.parse(fs.readFileSync(cacheFile, 'utf8'));
  console.log('Using cached data:', cached);
} else {
  // Fetch and cache
  const data = await fetchData();
  fs.writeFileSync(cacheFile, JSON.stringify(data));
}

Logging

import { appstash, resolve } from 'appstash';
import fs from 'fs';

const dirs = appstash('myapp', { ensure: true });
const logFile = resolve(dirs, 'logs', 'app.log');

function log(message: string) {
  const timestamp = new Date().toISOString();
  fs.appendFileSync(logFile, `[${timestamp}] ${message}\n`);
}

log('Application started');

Custom Base Directory

import { appstash } from 'appstash';

// Use a custom base directory
const dirs = appstash('myapp', {
  baseDir: '/opt/myapp',
  ensure: true
});

console.log(dirs.config); // /opt/myapp/.myapp/config

Design Philosophy

  • Simple: One function, clear structure
  • Clean: No pollution of exports, minimal API surface
  • Graceful: Never throws, always returns valid paths
  • Fallback: XDG only as absolute fallback, not primary
  • Focused: Just directory resolution, no state management

Development

Setup

  • Clone the repository:
git clone https://github.com/hyperweb-io/dev-utils.git
  • Install dependencies:
cd dev-utils
pnpm install
pnpm build
  • Test the package of interest:
cd packages/<packagename>
pnpm test:watch

Credits

Built for developers, with developers.
👉 https://launchql.com | https://hyperweb.io

Disclaimer

AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.

No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.

Keywords

directories

FAQs

Package last updated on 28 Nov 2025

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts