Обновить
32K+

TypeScript *

Cтрого типизированная надстройка для JavaScript

83,75
Рейтинг
Сначала показывать
Порог рейтинга

pear-crypt: клиентское шифрование

pear-crypt — небольшая TypeScript-библиотека, которая шифрует на клиенте и больше ничего не делает. На входе — пароль, PIN или Recovery Code, на выходе — ciphertext, который можно положить хоть в S3, хоть в Postgres. Пароль в этот blob не зашит.

Лицензия MIT. Из зависимостей только hash-wasm: нативного Argon2id в браузере нет. AES-256-GCM и HKDF-SHA256 берутся из Web Crypto, без велосипедостроения.

Почему бы не собирать самому?

Типичный сценарий: сгенерить мастер-ключ, обернуть его паролем, тем же ключом зашифровать файл и отдельно мету. Если каждый раз клеить это из crypto.subtle, через год уже не вспомнить, был ли AAD, какой длины nonce и куда делась salt.

Здесь wire-format зашит в спеке и в тестовых векторах. Поменять раскладку байтов «чуть-чуть» нельзя: старый ciphertext просто перестанет открываться.

Под капотом

Мастер-ключ — 32 случайных байта. В открытом виде наружу не светится: только внутри AES-GCM-обёртки. Ключ обёртки получается из секрета через Argon2id: 32 МиБ памяти, два прохода, без раскладки на несколько ядер. Параметры KDF лежат в JSON рядом с nonce и ciphertext, чтобы было видно, чем именно заворачивали.

Дальше HKDF с пустой солью режет мастер-ключ на домены. В info зашито, для чего ключ: файл или метаданные. Строка вида pear-keep-file:{uid} — это и есть domain separation. Файл и его имя одним ключом не вскрываются: это разные info.

Сам файл — кадр версия | nonce 12 байт | ciphertext и GCM-тег. AAD pear-keep-file:{uid}:{bindAt} привязывает blob к идентификатору и поколению содержимого. Подменили uid или bindAt — тег не сойдётся, расшифровки не будет.

Метаданные — тот же кадр, другой ключ и JSON внутри: подпись, комментарий, время, etc. Recovery Code — 25 символов из алфавита без сомнительных похожих, группами по пять. Им заворачивается тот же мастер-ключ, но отдельно от пароля: пароль забыл — ищи бумажку с кодом.

Как проверяется, что байты не разъехались

В репозитории лежат docs/crypto/SPEC.md и JSON с векторами. Тесты бьют не только в прямую «зашифровал и тут же расшифровал», но и в зафиксированный ciphertext. Покрытие держится выше 90%. Поменяли src/ — пересобрали векторы через npm run export:vectors и закоммитили вместе с кодом. Иначе спецификация и реализация тихо разъедутся.

Чего в комплекте нет

Библиотека не решает, куда класть ciphertext, как устроен логин и когда блокировать сессию. Длину PIN тоже не проверяет. И кофе не варит.

Ошибки — PearKeepCryptoError с машинным кодом: wrongPassword, cannotDecryptMetadata и дальше по списку. Человеческого текста ошибок нет и не будет. Как и i18n.

Итого

Обернуть мастер-ключ, зашифровать контент и мету и не таскать раскладку байтов в голове — вот и весь контракт. Спека, векторы и код смотрят в одну сторону: сдвинули кадр, тесты покраснеют раньше, чем это заметит пользователь. Куда класть готовый ciphertext и как пускать человека внутрь — уже забота приложения.

Теги:
+5
Комментарии0

Представлен открытый проект NextSteamGame, который помогает выдавать рекомендации по играм в Steam. В отличие от алгоритмов Valve, в этом проекте считываются не только пересечения предпочтений других игроков, а и метаданные каждого тайтла. Специальная нейросеть разбирает проект на набор механик и жанров, после чего ищет совпадения в других играх.

Теги:
+4
Комментарии0

🤔 Как не терять requestId в логах не пробрасывая его через параметры методов?

Классическая проблема NodeJS разработки: логи не читаемы. При дебаге когда пользователь один, разобрать что происходит ещё можно. Но после запуска в прод в логах сборная солянка из запросов и восстановить трейс вызова композиции методов нельзя

import { scoped } from "di-scoped";

export interface IRequestContext {
  userId: string;
  requestId: string;
  serviceName: "mobile" | "desktop";
  version: number;
}

export const RequestContextService = scoped(
  class {
    constructor(readonly context: IRequestContext) {}
  }
);

export type TRequestContextService = InstanceType<
  typeof RequestContextService
>;

export default RequestContextService;

Согласно MVC, делается два слоя: View и Controller. На уровне view кладем requestId в контекст исполнения через RequestContextService.runInContext

import { inject } from "di-kit";

export class SocketViewService {
  readonly loggerService = inject<LoggerService>(TYPES.loggerService);
  readonly socketControllerService = inject<SocketControllerService>(TYPES.socketControllerService);

  public sendNewOrder = async (
    request: TRequest<{ room: string; orderId: string }>,
  ): Promise<TResponse<SendNewOrder>> => {
    this.loggerService.log("socketViewService sendNewOrder", { request });
    try {
      const data = await RequestContextService.runInContext(
//                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        async () =>
          await this.socketControllerService.sendNewOrder(request.data),
        request,
      );
      return { status: "ok", serviceName: request.serviceName, version: request.version, userId: request.userId, requestId: request.requestId, data };
    } catch (error: any) {
      this.loggerService.log("socketViewService sendNewOrder error", { request, error: errorData(error) });
      return { status: "error", error: VerificationError.getErrorMessage(error), errorCode: VerificationError.getErrorCode(error), serviceName: request.serviceName, version: request.version, userId: request.userId, requestId: request.requestId };
    }
  };
}

Voila! Во всех вложенных сервисах к записи в лог будет приложен идентификатор requestId. Дополнительно, этот код позволяет сериализовать ошибки так, чтобы передавать их по шине gRPC

import { inject } from "di-kit";
import { createLogger } from 'pinolog';

const logger = createLogger("socket.log");

export class LoggerService {

  readonly requestContextService = inject<TRequestContextService>(TYPES.requestContextService);

  private get context() {
    if (RequestContextService.hasContext()) {
      // в лог - только конверт IRequestContext; scoped-контекст. но дебаггеру виден весь запрос
      const { serviceName, version, userId, requestId } = this.contextService.context;
      return { serviceName, version, userId, requestId };
    }
    return {};
  }

  public log = (topic: string, ...args: any[]) => {
    logger.log(topic, ...args, this.context);
  }

}
Теги:
+4
Комментарии0

🤡 Новый фреймворк на NodeJS

Это не draft, а работающий код из прода. Посмотрите код сервиса, код http контроллера и код декларации

Шутки шутками, а существующие реализации DI на ноде либо перегружены, либо используют декораторы, для которых нет единого стандарта у старого и нового кода.

import { provide, inject } from "di-kit";

export class WalkerLogicPublicService {

  private readonly loggerService = inject<LoggerService>("loggerService");

  ...

}

...

provide("loggerService", () => new LoggerService());

Вот почему нельзя просто вот так? Никаких минусов нет, выносите типы в enum, создавайте изолированные пространства имен.

import { createActivator } from "di-kit";

export const { init, inject, provide } = createActivator("separate-scope");
Теги:
+8
Комментарии0

Представлен открытый проект Spotify Portal AI Plugins. Это решение от инженеров Spotify, которое экономит до 90% ресурсов ИИ-агентов:

  • перенаправляет шаблонные задачи на более дешёвых агентов и оставляет Claude только приоритетные дела;

  • bulk‑reader разбирает многострочный код, Gemini 2.5 Flash внутри читает файлы на тысячи строк и отдаёт Claude саммари;

  • code‑writer генерит рутинный, проверенный и предсказуемый код, пишет тексты, конфиги, type stubs, boilerplate и другие переиспользуемые части;

  • Claude забирает себе только самые важные и реально сложные задачи, где нужен мощный ризонинг — фикс багов, проработка архитектуры и внесение сложных правок.

Теги:
+7
Комментарии0

Представлен открытый проект Phone Farm iOS - TikTok-ферма на устройствах с iOS. Подключаем iPhone к Mac, регистрируем в панели и управляем прямо из браузера: можно смотреть экран в реальном времени, тапать, свайпать и запускать автоматизацию TikTok. Встроенный планировщик публикует посты и слайд-шоу по расписанию, а очередь и история запусков хранятся в PostgreSQL. Проект работает без джейлбрейка и полностью локально.

Теги:
+1
Комментарии0

Анализаторы кода легко и быстро умеют находить множество ошибок, не очевидных с первого взгляда. Попробуйте посоревноваться с PVS-Studio в прозорливости!

Мы сделали новый квиз «Найдите ошибки в JS & TS коде»!

Вас ждут 10 фрагментов кода, в которых наш анализатор нашёл ошибки. Все они взяты из известных Open Source проектов. Ваша задача — успеть найти ошибку за 60 секунд (не переживайте, фрагменты небольшие).

Время посоревноваться с анализатором! А потом можно и его проверить 😉

Переходите по ссылке!

Теги:
Всего голосов 4: ↑3 и ↓1+4
Комментарии6

Представлен открытый проект ИИ‑учёного OmniScientist, который сам пишет статьи, составляет библиографию, таблицы и рисует схемы для любых исследователей:

  • анализирует любые файлы: изображения, видео, схемы, таблицы, документы, формулы и даже аудио.

  • выдвигает гипотезы как настоящая команда учёных.

  • проверяет информацию до последней запятой, чтобы не было ни одной выдумки или неточности;

  • строит графики, таблицы и схемы;

  • собирает результат в PDF и отдаёт в удобном формате;

  • знает русский язык и ориентируется в культурном контексте;

  • может подключаться к различным ИИ‑агентам;

  • работает на Windows, macOS и Linux.

Теги:
Всего голосов 9: ↑9 и ↓0+11
Комментарии4

Чуть лучше код

Короче, котаны, сейчас открою вам секрет, который бустанет вас нереально по качеству кода. Люди давние в профессии интуитивно чувствуют его, даже если никогда не слышали о нем. Самые признанные олды выступают на конференциях, как вы догадались, о мега секрете. Итак, барабанная дробь, хотя еще секунду, почему об этом хочется написать министатью, потому что иногда (а на деле слишком часто) стандартную задачу сходить за репортом и положить в базу нельзя переиспользовать и нельзя легко затестить. Речь пойдет о идемпотентности.

Что дано:

  1. поход в базу (начальные данные)

  2. поход по апи за списком (указателей или стримов)

  3. для каждого (репорта): поход по апи за данными и сохранение в базу

Легко пишем (неправильный) скрипт, кладем в крон и профит? Почти. Через пару лет в дев базе 2kk записей и селект ну очень долго ждать. Порядочные пацаны (и девушки) пишут тесты на sqlite, и неявно имплeмeнтируют идемпотентность, создавая и дропая базу данных на каждую пачку тестов. Sql insert не является идемпотентной операцией, но с пустой базой прокатывает.

В чем, собственно, проблема? Идемпотентность (от лат. idem — тот же самый и potens — сильный, буквально — равносильность) — свойство объекта или операции при повторном применении операции к объекту давать тот же результат, что и при первом. Так вот, sql insert и app_call(date_now) не обладают идемпотентностью.

Что делать? Как и в примере выше, создаем искусственную идемпотентность (да, этот термин повторится еще много раз), вынося в контекст доступ к базе, апи вызовы и т.д. (трансформация csv). Короче, контекст может быть пустой и код должен корректно работать. Или в контексте будет передан доступ к базе, но без апи вызовов или трансформации csv. И опять код должен работать корректно.

Чем заменить? Дефолтными значениями, как ни странно, дефолтные значения идемпотентны, если это, например, список и словарь. Удачного кодинга :)

P.S.: Хотел приложить примеры кода, но кол-во строк оказалось больше размера статьи :)

Теги:
Всего голосов 6: ↑1 и ↓5-2
Комментарии3

Делаем профессиональное ревью кода и не пропускаем ни одного бага — вышел открытый инструмент Rеjudge, который проверяет код с помощью трех ИИ-агентов, а затем ИИ-судья выносит вердикт в готовый отчёт:

  • каждая ИИ-модель проверяет один и тот же запрос, разбирая его в изолированном контексте. При этом ни одна модель не видит, что делают другие;

  • ИИ-судья затем проверяет все три ответа, задаёт уточняющие вопросы там, где расходятся независимые проверки;

  • затем судья выдает один готовый отчет, где указывает все риски, баги и уязвимости в коде.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии1

Представлен открытый проект torlink, который умеет искать и работать с торрентами из проверенных источников. Запускается командой npx torlnk. Одновременно проверяет FitGirl, YTS, The Pirate Bay, 1337x, Nyaa и другие источники, а результаты показывает вместе с размером и числом сидов. Выбранный файл скачивается в фоне, а после завершения автоматически встаёт на раздачу.

«Найти торрент в наши дни — сплошная головная боль. Один сайт — это минное поле из поддельных кнопок загрузки. Другой скрывает настоящую ссылку под всплывающим окном, которое открывает ещё две вкладки. И после всего этого половина результатов — это неработающие сайты с нулевым количеством раздающих. Torlink — это программа для поиска торрентов, которая работает в вашем терминале, не требует никакой настройки и конфигурации. Один поиск проверяет короткий, тщательно отобранный список надёжных источников, и всё, что вы выберете, загрузится прямо на ваш компьютер. Файлы ваши, сохранены в папке загрузок», — пояснил автор проекта.

Теги:
Всего голосов 7: ↑7 и ↓0+11
Комментарии1

Представлен открытый проект repowise — оптимизатор кодовых баз, который экономит токены в кодинге и работает с Claude Code, Cursor, Copilot:

  • не читает каждый файл, а сразу индексирует весь репозиторий;

  • создаёт документацию для каждого файла;

  • строит графы зависимости и анализирует историю Git с слабыми местами;

  • неиспользуемый код и устаревшие зависимости чистит сам;

  • результат: минимальная задокументированная экономия — 36%.

Теги:
Всего голосов 1: ↑1 и ↓0+3
Комментарии0

Ближайшие события

Представлен открытый проект skales — ИИ‑агент, который запустится даже на слабом ПК:

  • работает как обычное приложение в Windows, macOS и Linux;

  • агент получает доступ к файлам, браузеру, почте и календарю;

  • умеет выполнять сложные задачи в фоновом режиме;

  • можно запланировать любую таску по таймеру;

  • своя встроенная память для важного контекста;

  • при этом команды отправлять можно даже со смартфона — агент выполнит их на ПК;

  • можно тестировать на бесплатном пробном режиме, подключить API или локальную модель.

Теги:
Всего голосов 4: ↑3 и ↓1+6
Комментарии3

Открытый проект .MD this page позволяет преобразовать веб-страницу в чистый Markdown, готовый для ChatGPT, Claude, Gemini и других нейросетей. Решение очищает код сайта от рекламы, баннеров и другого мусора для отправки на обработку в ИИ. Есть предпросмотр, экспорт в .md и опция для мгновенного копирования сайта.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии1

Представлен открытый архитектурный инструмент Pascal Editor (3D building editor built with React Three Fiber and WebGPU), который работает прямо в браузере. Рисуем стены, перекрытия и крыши, ставим двери, окна и мебель, собираем несколько этажей и переключаемся между 2D‑планом и 3D. Готовый дом можно разобрать по этажам, пройтись по нему от первого лица и выгрузить в другие редакторы. Также к проекту можно подключить Codex и Claude Code и попросить ИИ создавать элементы здания.

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии0

Представлен открытый SSH‑менеджер Termix, который работает без подписок или рекламы. Проект включает в себя как стандартные функции, так и расширенные:

  • 2FA для защиты доступа к серверам;

  • удобный интерфейс, разработанный на React и Tailwind CSS;

  • терминал SSH с разделением экрана, управлением SSH‑туннелями;

  • удалённый редактор файлов с подсветкой синтаксиса;

  • мониторинг вообще всех ресурсов серверов;

  • менеджер Docker и Podman‑контейнеров.

Теги:
Всего голосов 2: ↑2 и ↓0+4
Комментарии0

Представлен открытый редактор презентаций Bento на замену PowerPoint. Презентация в Bento хранит внутри себя слайды, шрифты, картинки, анимации и весь редактор. Базовый файл весит около 560 КБ, открывается в браузере без установки и аккаунта, умеет сам себя сохранять, работает офлайн и даже поддерживает совместное редактирование с шифрованием.

Внутри Bento обычный JSON — поэтому презентацию могут напрямую редактировать ИИ-агенты. Есть графики, комментарии, режим докладчика, PDF-экспорт и анимации между слайдами.

Теги:
Всего голосов 4: ↑4 и ↓0+6
Комментарии1

Открытый проект PriceGhost позволяет искать самые дешёвые и качественные товары в сети Интернет с помощью ИИ:

  • внутри команда ИИ‑агентов, которая проверяет сотни площадок с нужным вам товаром;

  • агенты сравнивают цены, сроки доставки, качество, характеристики, скрытые доплаты и комиссии, наличие страховки груза и прочее;

  • выдаётся подробный отчёт с инфографикой. ИИ также выдаст рекомендации, если товара не будет в наличии;

  • результат — можно купить вещь выгоднее и не ждать долго доставку, а ещё не навяжут скрытые условия.

Теги:
Всего голосов 3: ↑3 и ↓0+6
Комментарии0

Фронтенд для души, бэкенд для людей!

Мастер по разводу холивар
Мастер по разводу холивар

Были приняты меры погрузиться под воду дабы показать серьезность моих намерений в данной щепетильной теме.

Фронтенд весь такой разносторонний, креативный, местами легкий, местами настолько сложный что ломаешь голову. Напрашивается клеймо "для любителей".

Бэкенд наоборот поддерживает порядок и структурность. Меньше экспериментов и больше проверенных решений, самое то для "сделал работу - пошел спокойно домой".

Теги:
Всего голосов 5: ↑3 и ↓2+3
Комментарии2