Commit Graph
11 Commits
Author SHA1 Message Date
DrSmoothl 056188d63d chore: resolve async SQLite merge conflicts
Integrate the current development branch, preserve the album comment fixes, and align the changes with repository formatting and dependency tooling.
2026-10-13 09:55:16 +08:00
手瓜一十雪 e699351f90 feat: adopt async SQLite and improve messaging and runtime diagnostics 2026-10-12 15:44:55 +08:00
DrSmoothl 7c0519f75f lint 2026-10-12 15:43:34 +08:00
DrSmoothl 613b2b1e68 fix(proton): decode extended uint32 field varints
Consume complete well-formed value varints before retaining their low 32 bits, matching QQ push behavior without relaxing tag or length parsing.

Add generator and end-to-end group reaction regressions, including truncated and malformed varint coverage. Refs #242.
2026-07-19 15:35:53 +08:00
DrSmoothl b53004ee23 fix(proton): accept sign-extended uint32 field values 2026-07-10 18:20:11 +08:00
DrSmoothl b7d648ea0f fix(proton): harden generated protobuf decoders
Reject malformed varints, out-of-bounds fields, and invalid groups before they escape their parent frame. Aggregate unknown-field metadata and decode signed int32 values while preserving SnowLuma's existing outbound encoding bytes.
2026-07-10 13:40:53 +08:00
DrSmoothl 90f26ca4f4 fix(proto): emit state=0 on whole-ban unmute via new pb_optional marker
set_group_whole_ban false (unmute) failed with `OIDB error 1007` while
enabling worked (issue #70). OIDB (0x89A, 0) is shared by several commands
(SetSearch / SetAddOption / mute-all) disambiguated by body shape. Unmute
sends muteState.state=0, but proton omits zero scalars (proto3), leaving an
empty `muteState` the server can't classify. Enable sends 0xFFFFFFFF, which
is non-zero and survives — hence the asymmetry.

Add a `pb_optional<N, T>` marker (proto3 explicit presence): a scalar so
marked serialises even at its zero/default value. It is opt-in per field via
a NEW `explicitPresence` flag set ONLY by this marker — never reused from the
TS-`?`-derived `isOptional` (true for nearly every field). The encoder routes
explicit-presence scalars to a dedicated block; every `pb<>` / `pb_repeated<>`
field takes the untouched branches, so existing wire output is byte-identical
(proton's 99 existing tests, incl. byte-level round-trips, stay green).

Mark OidbMuteAllState.state `pb_optional<17, uint_32>` so unmute now puts
field 17 (=0) on the wire. New tests: proton pb_optional encode/round-trip
(incl. that sibling pb<> fields still omit zero), and a byte-level assertion
that mute-all unmute carries the state field.

Note: proton ships as a built Vite plugin (dist, gitignored); rebuild it
(`pnpm --filter @snowluma/proton build`) for the change to reach consumers.
2026-05-30 17:55:23 +08:00
DrSmoothl 994633eafa feat(proton): resolve bare specifiers via TypeScript module resolution
`resolveModulePath` used to skip any specifier not starting with '.'
which meant proton's vite plugin only saw proto definitions that lived
in the same package as the call site. Trying to move definitions into
a sibling workspace package (e.g. `@snowluma/proto-defs`) caused those
imports to silently fail — the call-site type lookup found nothing
and the protobuf_encode<T> replacement never fired.

Add a bare-specifier branch that delegates to `ts.resolveModuleName`
with `moduleResolution: Bundler`. That covers monorepo workspaces,
npm packages, package.json `exports`, and tsconfig path aliases with
zero extra user configuration.

The relative-path branch is preserved byte-for-byte so existing
single-package consumers see identical behaviour. Resolution is
constrained to `.ts` source files (not `.d.ts`) because proton walks
interface AST to collect `pb<>` field tags, and generated declaration
files typically strip those generic arguments.

Per-process `ModuleResolutionCache` keeps the hot path (HMR rebuild)
from re-scanning node_modules every call.

Tests: new `cross-package.test.ts` builds a fake monorepo under
`os.tmpdir()` and exercises smoke / transform / round-trip / negative
paths. 99/99 proton tests pass; SnowLuma core regression unchanged
(587 baseline ⇄ 587 with change).
2026-05-20 21:22:48 +08:00
手瓜一十雪 36c3ed031b Apply formatting and fix web request utilities
Add consistent indent rule to ESLint and normalize formatting/indentation across multiple files. Refactor RequestUtil: improve cookie extraction, redirect handling, and HttpGetJson/HttpGetText request flow; fix cookie string builder formatting. Fix uploadGroupNoticeImage promise/error handling and network request flow. Also apply minor style/refactor tweaks in bridge web APIs, onebot handlers, message-store SQL alignment, and Proton AST collector utilities to improve readability and correctness.
2026-05-20 19:16:06 +08:00
手瓜一十雪 aea2676c31 Add TypeScript ESLint configs and lint scripts
Add a repository .editorconfig and a root eslint.config.ts to standardize formatting and linting. Migrate packages/webui ESLint config to TypeScript (eslint.config.ts) with project-specific rules and tsconfigRootDir handling, and remove the old JS config. Update package.json to run ESLint directly (add lint and lint:fix) and add required ESLint/dev dependencies; also add jiti to packages/webui/package.json. Include a small formatting tweak to tsconfig.base.json.
2026-05-20 19:08:45 +08:00
DrSmoothl 194165f49d feat(proton): add @snowluma/proton — compile-time protobuf DSL
Vendors SnowLuma/protobuf-dsl into the monorepo as @snowluma/proton, with
edge-case fixes applied on top of the upstream source. Reference copy of
the unmodified upstream is kept under dev/protobuf-dsl/.

Edge cases fixed (each with a regression test):
  - Aliased pb / pb_repeated marker imports (`import { pb as P }`)
    — collector now resolves the marker name through the import resolver
  - Concrete interface with a generic-instantiated message field
    (`wrapped: pb<5, Wrapper<uint_32>>`) — field typeName now resolves
    to the mangled form, and the inner instantiation is queued for
    monomorphization
  - Generic template with a generic-instantiated field
    (`interface Outer<U> { x: pb<5, Wrapper<U>> }`) — the inner
    instantiation is now re-substituted and re-monomorphized at outer
    instantiation time
  - Wrapper-binding synthetic SourceFile was empty-text — getText()
    returned garbage, breaking mangled name computation downstream
  - Cross-file forwarded wrappers (chain → imported base) were not
    detected — parseFileForDefinitions now resolves imports recursively
    (value imports only, with cycle protection)
  - matchForwardedKnownWrapper did not propagate typePattern — chain
    treated <X> as the encoded type instead of Wrapper<X>
  - Synthetic-SF WeakMap was private to analyzer.ts — replacer could
    not see it. Moved to utils.ts so typeNodeToMangledName picks it up
    automatically.

Defensive guard: any field whose typeName resolves to neither a primitive
nor a known message now throws at analyze() time, instead of silently
leaking the WireType.Varint placeholder into codegen.

95/95 tests pass; tsc --noEmit clean.
2026-05-19 08:19:13 +08:00