Files
zCode-CLI-X/~/.npm-cache/@growthbook/growthbook@1.6.5@@@1/dist/cjs/sticky-bucket-service.js
admin 875c7f9b91 feat: Complete zCode CLI X with Telegram bot integration
- Add full Telegram bot functionality with Z.AI API integration
- Implement 4 tools: Bash, FileEdit, WebSearch, Git
- Add 3 agents: Code Reviewer, Architect, DevOps Engineer
- Add 6 skills for common coding tasks
- Add systemd service file for 24/7 operation
- Add nginx configuration for HTTPS webhook
- Add comprehensive documentation
- Implement WebSocket server for real-time updates
- Add logging system with Winston
- Add environment validation

🤖 zCode CLI X - Agentic coder with Z.AI + Telegram integration
2026-05-05 09:01:26 +00:00

222 lines
7.4 KiB
JavaScript

"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.StickyBucketServiceSync = exports.StickyBucketService = exports.RedisStickyBucketService = exports.LocalStorageStickyBucketService = exports.ExpressCookieStickyBucketService = exports.BrowserCookieStickyBucketService = void 0;
var _util = require("./util");
var _core = require("./core");
/**
* Responsible for reading and writing documents which describe sticky bucket assignments.
*/
class StickyBucketService {
constructor(opts) {
opts = opts || {};
this.prefix = opts.prefix || "";
}
/**
* The SDK calls getAllAssignments to populate sticky buckets. This in turn will
* typically loop through individual getAssignments calls. However, some StickyBucketService
* instances (i.e. Redis) will instead perform a multi-query inside getAllAssignments instead.
*/
async getAllAssignments(attributes) {
const docs = {};
(await Promise.all(Object.entries(attributes).map(([attributeName, attributeValue]) => this.getAssignments(attributeName, attributeValue)))).forEach(doc => {
if (doc) {
const key = (0, _core.getStickyBucketAttributeKey)(doc.attributeName, doc.attributeValue);
docs[key] = doc;
}
});
return docs;
}
getKey(attributeName, attributeValue) {
return `${this.prefix}${attributeName}||${attributeValue}`;
}
}
exports.StickyBucketService = StickyBucketService;
class StickyBucketServiceSync extends StickyBucketService {
async getAssignments(attributeName, attributeValue) {
return this.getAssignmentsSync(attributeName, attributeValue);
}
async saveAssignments(doc) {
this.saveAssignmentsSync(doc);
}
getAllAssignmentsSync(attributes) {
const docs = {};
Object.entries(attributes).map(([attributeName, attributeValue]) => this.getAssignmentsSync(attributeName, attributeValue)).forEach(doc => {
if (doc) {
const key = (0, _core.getStickyBucketAttributeKey)(doc.attributeName, doc.attributeValue);
docs[key] = doc;
}
});
return docs;
}
}
exports.StickyBucketServiceSync = StickyBucketServiceSync;
class LocalStorageStickyBucketService extends StickyBucketService {
constructor(opts) {
opts = opts || {};
super();
this.prefix = opts.prefix || "gbStickyBuckets__";
try {
this.localStorage = opts.localStorage || globalThis.localStorage;
} catch (e) {
// Ignore localStorage errors
}
}
async getAssignments(attributeName, attributeValue) {
const key = this.getKey(attributeName, attributeValue);
let doc = null;
if (!this.localStorage) return doc;
try {
const raw = (await this.localStorage.getItem(key)) || "{}";
const data = JSON.parse(raw);
if (data.attributeName && data.attributeValue && data.assignments) {
doc = data;
}
} catch (e) {
// Ignore localStorage errors
}
return doc;
}
async saveAssignments(doc) {
const key = this.getKey(doc.attributeName, doc.attributeValue);
if (!this.localStorage) return;
try {
await this.localStorage.setItem(key, JSON.stringify(doc));
} catch (e) {
// Ignore localStorage errors
}
}
}
exports.LocalStorageStickyBucketService = LocalStorageStickyBucketService;
class ExpressCookieStickyBucketService extends StickyBucketServiceSync {
/**
* Intended to be used with cookieParser() middleware from npm: 'cookie-parser'.
* Assumes:
* - reading a cookie is automatically decoded via decodeURIComponent() or similar
* - writing a cookie name & value must be manually encoded via encodeURIComponent() or similar
* - all cookie bodies are JSON encoded strings and are manually encoded/decoded
*/
constructor({
prefix = "gbStickyBuckets__",
req,
res,
cookieAttributes = {
maxAge: 180 * 24 * 3600 * 1000
} // 180 days
}) {
super();
this.prefix = prefix;
this.req = req;
this.res = res;
this.cookieAttributes = cookieAttributes;
}
getAssignmentsSync(attributeName, attributeValue) {
const key = this.getKey(attributeName, attributeValue);
let doc = null;
if (!this.req) return doc;
try {
const raw = this.req.cookies[key] || "{}";
const data = JSON.parse(raw);
if (data.attributeName && data.attributeValue && data.assignments) {
doc = data;
}
} catch (e) {
// Ignore cookie errors
}
return doc;
}
saveAssignmentsSync(doc) {
const key = this.getKey(doc.attributeName, doc.attributeValue);
if (!this.res) return;
const str = JSON.stringify(doc);
this.res.cookie(encodeURIComponent(key), encodeURIComponent(str), this.cookieAttributes);
}
}
exports.ExpressCookieStickyBucketService = ExpressCookieStickyBucketService;
class BrowserCookieStickyBucketService extends StickyBucketServiceSync {
/**
* Intended to be used with npm: 'js-cookie'.
* Assumes:
* - reading a cookie is automatically decoded via decodeURIComponent() or similar
* - writing a cookie name & value is automatically encoded via encodeURIComponent() or similar
* - all cookie bodies are JSON encoded strings and are manually encoded/decoded
*/
constructor({
prefix = "gbStickyBuckets__",
jsCookie,
cookieAttributes = {
expires: 180
} // 180 days
}) {
super();
this.prefix = prefix;
this.jsCookie = jsCookie;
this.cookieAttributes = cookieAttributes;
}
getAssignmentsSync(attributeName, attributeValue) {
const key = this.getKey(attributeName, attributeValue);
let doc = null;
if (!this.jsCookie) return doc;
try {
const raw = this.jsCookie.get(key);
const data = JSON.parse(raw || "{}");
if (data.attributeName && data.attributeValue && data.assignments) {
doc = data;
}
} catch (e) {
// Ignore cookie errors
}
return doc;
}
async saveAssignmentsSync(doc) {
const key = this.getKey(doc.attributeName, doc.attributeValue);
if (!this.jsCookie) return;
const str = JSON.stringify(doc);
this.jsCookie.set(key, str, this.cookieAttributes);
}
}
exports.BrowserCookieStickyBucketService = BrowserCookieStickyBucketService;
class RedisStickyBucketService extends StickyBucketService {
/** Intended to be used with npm: 'ioredis'. **/
constructor({
redis
}) {
super();
this.redis = redis;
}
async getAllAssignments(attributes) {
const docs = {};
const keys = Object.entries(attributes).map(([attributeName, attributeValue]) => (0, _core.getStickyBucketAttributeKey)(attributeName, attributeValue));
if (!this.redis) return docs;
await this.redis.mget(...keys).then(values => {
values.forEach(raw => {
try {
const data = JSON.parse(raw || "{}");
if (data.attributeName && "attributeValue" in data && data.assignments) {
const key = (0, _core.getStickyBucketAttributeKey)(data.attributeName, (0, _util.toString)(data.attributeValue));
docs[key] = data;
}
} catch (e) {
// ignore redis doc parse errors
}
});
});
return docs;
}
async getAssignments(_attributeName, _attributeValue) {
// not implemented
return null;
}
async saveAssignments(doc) {
const key = this.getKey(doc.attributeName, doc.attributeValue);
if (!this.redis) return;
await this.redis.set(key, JSON.stringify(doc));
}
}
exports.RedisStickyBucketService = RedisStickyBucketService;
//# sourceMappingURL=sticky-bucket-service.js.map