rotur-sdk 1.0.10 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -1200,4 +1200,34 @@ declare class AuthError extends Error {
1200
1200
  }
1201
1201
  declare function performAuth(options?: AuthOptions): Promise<AuthResult>;
1202
1202
 
1203
- export { type Activity, type ActivityApplication, type ActivityMedia, type AdminCosmeticCreate, type AdminCosmeticUpdate, ApiError, AuthError, type AuthOptions, type AuthResult, type Badge, type CheckAuthResponse, type CheckAuthResponseFull, type CheckBannedResponse, type CosmeticCatalogEntryPublic, type CosmeticItem, type CosmeticPurchaseResult, type EconomyStats, type ErrorResponse, type EscrowReleaseResult, type EscrowTransferResult, type ExistsResponse, type FileEntry, type FileUsageResponse, type FollowResponse, type FriendActionResponse, type GiftCancelResponse, type GiftClaimResponse, type GiftCreateResponse, type GiftNet, type GiftPublic, type GroupAnnouncement, type GroupEvent, type GroupMessageResponse, type GroupPublic, type GroupRepresentResponse, type GroupRole, type GroupTip, type ItemBuyResponse, type ItemDeleteResponse, type ItemSellResponse, type ItemSetPriceResponse, type ItemStopSellingResponse, type ItemTransferResponse, type JoinPolicy, type KeyBuyResponse, type KeyCancelSubscriptionResponse, type KeyCheckResponse, type KeyCreateResponse, type KeyPublic, type KeyStatusResponse, type KeySubscription, type KeyUserData, type LimitsResponse, type MeDeleteAccountResponse, type MeDeleteKeyResponse, type MeTransferResponse, type MeUpdateResponse, type MyCosmeticsResponse, type NetItem, type NetKey, type NetPost, type NetReply, type NetTransferHistory, type NotificationEntry, type NotifyAllowedSender, type NotifyEndpoint, type NotifyLogEntry, type PermissionGroup, type PostDeleteResponse, type PostPinResponse, type PostRateResponse, type Presence, type PushAllowSenderResponse, type PushCheckResponse, type PushDeleteDeviceResponse, type PushRegisterResponse, type PushSendManyResponse, type PushSendResponse, type RoomMember, Rotur, RoturSocket, type ShopResponse, type StandingHistoryEntry, type StandingInfo, type StandingLevel, type SubTokenCreate, type SubTokenPublic, type System, type SystemUpdateResponse, type TokenAbilities, type TokenActivityResponse, type TokenDeleteResponse, type TokenPermission, type TokenRenameResponse, type TokenRevokeResponse, type Transaction, type UserId, type UserProfile, type UserStats, type UserStatusResponse, type Username, type ValidatorGenerateResult, type ValidatorResult, type WSMessage$1 as WSMessage, performAuth };
1203
+ type IconResolver = (name: string) => string | undefined;
1204
+ interface IconToSvgOptions {
1205
+ /** Overall scale factor applied to all coordinates (default: 1). */
1206
+ size?: number;
1207
+ /**
1208
+ * Half-extent of the SVG viewBox — the icon is centred at 0,0.
1209
+ * Defaults to `size * 20`.
1210
+ */
1211
+ viewSize?: number;
1212
+ /** Initial stroke colour (default: "#ffffff"). */
1213
+ color?: string;
1214
+ /** Initial stroke width in unscaled icon units (default: 1). */
1215
+ strokeWidth?: number;
1216
+ /**
1217
+ * Boldness multiplier applied to every `w` command: `w_final = |w_arg × size| × (boldness + 1)`.
1218
+ * Matches the `p6` parameter from the original renderer (default: 0 → no extra boldness).
1219
+ */
1220
+ boldness?: number;
1221
+ /**
1222
+ * Overall rotation of the icon in degrees, measured clockwise from up (north).
1223
+ * Matches Scratch's direction convention: 90° = right (default: 90, i.e. no rotation).
1224
+ */
1225
+ direction?: number;
1226
+ /** Resolve named sub-icons for the `icn` command. */
1227
+ resolver?: IconResolver;
1228
+ /** Extra attributes written onto the root `<svg>` element. */
1229
+ svgAttrs?: Record<string, string>;
1230
+ }
1231
+ declare function iconToSvg(iconString: string, options?: IconToSvgOptions): string;
1232
+
1233
+ export { type Activity, type ActivityApplication, type ActivityMedia, type AdminCosmeticCreate, type AdminCosmeticUpdate, ApiError, AuthError, type AuthOptions, type AuthResult, type Badge, type CheckAuthResponse, type CheckAuthResponseFull, type CheckBannedResponse, type CosmeticCatalogEntryPublic, type CosmeticItem, type CosmeticPurchaseResult, type EconomyStats, type ErrorResponse, type EscrowReleaseResult, type EscrowTransferResult, type ExistsResponse, type FileEntry, type FileUsageResponse, type FollowResponse, type FriendActionResponse, type GiftCancelResponse, type GiftClaimResponse, type GiftCreateResponse, type GiftNet, type GiftPublic, type GroupAnnouncement, type GroupEvent, type GroupMessageResponse, type GroupPublic, type GroupRepresentResponse, type GroupRole, type GroupTip, type ItemBuyResponse, type ItemDeleteResponse, type ItemSellResponse, type ItemSetPriceResponse, type ItemStopSellingResponse, type ItemTransferResponse, type JoinPolicy, type KeyBuyResponse, type KeyCancelSubscriptionResponse, type KeyCheckResponse, type KeyCreateResponse, type KeyPublic, type KeyStatusResponse, type KeySubscription, type KeyUserData, type LimitsResponse, type MeDeleteAccountResponse, type MeDeleteKeyResponse, type MeTransferResponse, type MeUpdateResponse, type MyCosmeticsResponse, type NetItem, type NetKey, type NetPost, type NetReply, type NetTransferHistory, type NotificationEntry, type NotifyAllowedSender, type NotifyEndpoint, type NotifyLogEntry, type PermissionGroup, type PostDeleteResponse, type PostPinResponse, type PostRateResponse, type Presence, type PushAllowSenderResponse, type PushCheckResponse, type PushDeleteDeviceResponse, type PushRegisterResponse, type PushSendManyResponse, type PushSendResponse, type RoomMember, Rotur, RoturSocket, type ShopResponse, type StandingHistoryEntry, type StandingInfo, type StandingLevel, type SubTokenCreate, type SubTokenPublic, type System, type SystemUpdateResponse, type TokenAbilities, type TokenActivityResponse, type TokenDeleteResponse, type TokenPermission, type TokenRenameResponse, type TokenRevokeResponse, type Transaction, type UserId, type UserProfile, type UserStats, type UserStatusResponse, type Username, type ValidatorGenerateResult, type ValidatorResult, type WSMessage$1 as WSMessage, iconToSvg, performAuth };
package/dist/index.d.ts CHANGED
@@ -1200,4 +1200,34 @@ declare class AuthError extends Error {
1200
1200
  }
1201
1201
  declare function performAuth(options?: AuthOptions): Promise<AuthResult>;
1202
1202
 
1203
- export { type Activity, type ActivityApplication, type ActivityMedia, type AdminCosmeticCreate, type AdminCosmeticUpdate, ApiError, AuthError, type AuthOptions, type AuthResult, type Badge, type CheckAuthResponse, type CheckAuthResponseFull, type CheckBannedResponse, type CosmeticCatalogEntryPublic, type CosmeticItem, type CosmeticPurchaseResult, type EconomyStats, type ErrorResponse, type EscrowReleaseResult, type EscrowTransferResult, type ExistsResponse, type FileEntry, type FileUsageResponse, type FollowResponse, type FriendActionResponse, type GiftCancelResponse, type GiftClaimResponse, type GiftCreateResponse, type GiftNet, type GiftPublic, type GroupAnnouncement, type GroupEvent, type GroupMessageResponse, type GroupPublic, type GroupRepresentResponse, type GroupRole, type GroupTip, type ItemBuyResponse, type ItemDeleteResponse, type ItemSellResponse, type ItemSetPriceResponse, type ItemStopSellingResponse, type ItemTransferResponse, type JoinPolicy, type KeyBuyResponse, type KeyCancelSubscriptionResponse, type KeyCheckResponse, type KeyCreateResponse, type KeyPublic, type KeyStatusResponse, type KeySubscription, type KeyUserData, type LimitsResponse, type MeDeleteAccountResponse, type MeDeleteKeyResponse, type MeTransferResponse, type MeUpdateResponse, type MyCosmeticsResponse, type NetItem, type NetKey, type NetPost, type NetReply, type NetTransferHistory, type NotificationEntry, type NotifyAllowedSender, type NotifyEndpoint, type NotifyLogEntry, type PermissionGroup, type PostDeleteResponse, type PostPinResponse, type PostRateResponse, type Presence, type PushAllowSenderResponse, type PushCheckResponse, type PushDeleteDeviceResponse, type PushRegisterResponse, type PushSendManyResponse, type PushSendResponse, type RoomMember, Rotur, RoturSocket, type ShopResponse, type StandingHistoryEntry, type StandingInfo, type StandingLevel, type SubTokenCreate, type SubTokenPublic, type System, type SystemUpdateResponse, type TokenAbilities, type TokenActivityResponse, type TokenDeleteResponse, type TokenPermission, type TokenRenameResponse, type TokenRevokeResponse, type Transaction, type UserId, type UserProfile, type UserStats, type UserStatusResponse, type Username, type ValidatorGenerateResult, type ValidatorResult, type WSMessage$1 as WSMessage, performAuth };
1203
+ type IconResolver = (name: string) => string | undefined;
1204
+ interface IconToSvgOptions {
1205
+ /** Overall scale factor applied to all coordinates (default: 1). */
1206
+ size?: number;
1207
+ /**
1208
+ * Half-extent of the SVG viewBox — the icon is centred at 0,0.
1209
+ * Defaults to `size * 20`.
1210
+ */
1211
+ viewSize?: number;
1212
+ /** Initial stroke colour (default: "#ffffff"). */
1213
+ color?: string;
1214
+ /** Initial stroke width in unscaled icon units (default: 1). */
1215
+ strokeWidth?: number;
1216
+ /**
1217
+ * Boldness multiplier applied to every `w` command: `w_final = |w_arg × size| × (boldness + 1)`.
1218
+ * Matches the `p6` parameter from the original renderer (default: 0 → no extra boldness).
1219
+ */
1220
+ boldness?: number;
1221
+ /**
1222
+ * Overall rotation of the icon in degrees, measured clockwise from up (north).
1223
+ * Matches Scratch's direction convention: 90° = right (default: 90, i.e. no rotation).
1224
+ */
1225
+ direction?: number;
1226
+ /** Resolve named sub-icons for the `icn` command. */
1227
+ resolver?: IconResolver;
1228
+ /** Extra attributes written onto the root `<svg>` element. */
1229
+ svgAttrs?: Record<string, string>;
1230
+ }
1231
+ declare function iconToSvg(iconString: string, options?: IconToSvgOptions): string;
1232
+
1233
+ export { type Activity, type ActivityApplication, type ActivityMedia, type AdminCosmeticCreate, type AdminCosmeticUpdate, ApiError, AuthError, type AuthOptions, type AuthResult, type Badge, type CheckAuthResponse, type CheckAuthResponseFull, type CheckBannedResponse, type CosmeticCatalogEntryPublic, type CosmeticItem, type CosmeticPurchaseResult, type EconomyStats, type ErrorResponse, type EscrowReleaseResult, type EscrowTransferResult, type ExistsResponse, type FileEntry, type FileUsageResponse, type FollowResponse, type FriendActionResponse, type GiftCancelResponse, type GiftClaimResponse, type GiftCreateResponse, type GiftNet, type GiftPublic, type GroupAnnouncement, type GroupEvent, type GroupMessageResponse, type GroupPublic, type GroupRepresentResponse, type GroupRole, type GroupTip, type ItemBuyResponse, type ItemDeleteResponse, type ItemSellResponse, type ItemSetPriceResponse, type ItemStopSellingResponse, type ItemTransferResponse, type JoinPolicy, type KeyBuyResponse, type KeyCancelSubscriptionResponse, type KeyCheckResponse, type KeyCreateResponse, type KeyPublic, type KeyStatusResponse, type KeySubscription, type KeyUserData, type LimitsResponse, type MeDeleteAccountResponse, type MeDeleteKeyResponse, type MeTransferResponse, type MeUpdateResponse, type MyCosmeticsResponse, type NetItem, type NetKey, type NetPost, type NetReply, type NetTransferHistory, type NotificationEntry, type NotifyAllowedSender, type NotifyEndpoint, type NotifyLogEntry, type PermissionGroup, type PostDeleteResponse, type PostPinResponse, type PostRateResponse, type Presence, type PushAllowSenderResponse, type PushCheckResponse, type PushDeleteDeviceResponse, type PushRegisterResponse, type PushSendManyResponse, type PushSendResponse, type RoomMember, Rotur, RoturSocket, type ShopResponse, type StandingHistoryEntry, type StandingInfo, type StandingLevel, type SubTokenCreate, type SubTokenPublic, type System, type SystemUpdateResponse, type TokenAbilities, type TokenActivityResponse, type TokenDeleteResponse, type TokenPermission, type TokenRenameResponse, type TokenRevokeResponse, type Transaction, type UserId, type UserProfile, type UserStats, type UserStatusResponse, type Username, type ValidatorGenerateResult, type ValidatorResult, type WSMessage$1 as WSMessage, iconToSvg, performAuth };
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ __export(index_exports, {
24
24
  AuthError: () => AuthError,
25
25
  Rotur: () => Rotur,
26
26
  RoturSocket: () => RoturSocket,
27
+ iconToSvg: () => iconToSvg,
27
28
  performAuth: () => performAuth
28
29
  });
29
30
  module.exports = __toCommonJS(index_exports);
@@ -66,14 +67,8 @@ var Http = class {
66
67
  throw new ApiError(401, {
67
68
  error: "Not authenticated \u2014 call rotur.login() first"
68
69
  });
69
- const allParams = params;
70
- const opts = {
71
- method: "GET",
72
- headers: {
73
- ...token ? { Authorization: `Bearer ${token}` } : {}
74
- }
75
- };
76
- const res = await fetch(this.buildUrl(path, allParams), opts);
70
+ const allParams = auth && token ? { ...params, auth: token } : params;
71
+ const res = await fetch(this.buildUrl(path, allParams));
77
72
  return this.handle(res);
78
73
  }
79
74
  async post(path, body, auth = true) {
@@ -361,6 +356,11 @@ function performAuth(options) {
361
356
  const authUrl = new URL(AUTH_URL);
362
357
  if (options?.system) authUrl.searchParams.set("system", options.system);
363
358
  let iframe;
359
+ const w = window.open(
360
+ authUrl.toString(),
361
+ "rotur-auth",
362
+ "width=480,height=720"
363
+ );
364
364
  return new Promise((resolve, reject) => {
365
365
  const signal = options?.signal;
366
366
  const rejectWithError = (code, msg) => {
@@ -384,13 +384,12 @@ function performAuth(options) {
384
384
  window.removeEventListener("message", handler);
385
385
  signal?.removeEventListener("abort", onAbort);
386
386
  iframe?.remove();
387
+ try {
388
+ w?.close();
389
+ } catch {
390
+ }
387
391
  }
388
392
  window.addEventListener("message", handler);
389
- const w = window.open(
390
- authUrl.toString(),
391
- "rotur-auth",
392
- "width=480,height=720"
393
- );
394
393
  if (w) return;
395
394
  iframe = document.createElement("iframe");
396
395
  iframe.style.cssText = "position:fixed;inset:0;width:100%;height:100%;border:none;z-index:9999";
@@ -1144,11 +1143,279 @@ var CheckNamespace = class extends Namespace {
1144
1143
  return this.$post("/check/banned", usernames.join(","));
1145
1144
  }
1146
1145
  };
1146
+
1147
+ // src/icon.ts
1148
+ function dp(n2) {
1149
+ return (Math.round(n2 * 1e4) / 1e4).toString();
1150
+ }
1151
+ var n = (v) => +v || 0;
1152
+ function rotateVec(x, y, angleDeg) {
1153
+ const rad = angleDeg * Math.PI / 180;
1154
+ return [
1155
+ x * Math.cos(rad) - y * Math.sin(rad),
1156
+ x * Math.sin(rad) + y * Math.cos(rad)
1157
+ ];
1158
+ }
1159
+ function tokenise(src) {
1160
+ if (Array.isArray(src)) return src.map(String);
1161
+ return String(src).trim().split(/[ \n\t]+/g).filter(Boolean);
1162
+ }
1163
+ function renderTokens(tokens, ox, oy, boldness, state, resolver, out) {
1164
+ let i = 0;
1165
+ const next = () => tokens[++i] ?? "0";
1166
+ const toSVG = (lx, ly) => {
1167
+ const wx = state.offx + lx;
1168
+ const wy = state.offy + ly;
1169
+ return [ox + wx * state.size, oy - wy * state.size];
1170
+ };
1171
+ while (i < tokens.length) {
1172
+ const op = tokens[i];
1173
+ switch (op) {
1174
+ case "c":
1175
+ state.color = next();
1176
+ break;
1177
+ case "w": {
1178
+ const wArg = n(next());
1179
+ state.strokeWidth = Math.abs(wArg * state.size) * (boldness + 1);
1180
+ break;
1181
+ }
1182
+ case "line": {
1183
+ const [ax, ay] = toSVG(n(next()), n(next()));
1184
+ const [bx, by] = toSVG(n(next()), n(next()));
1185
+ out.push(
1186
+ `<line x1="${dp(ax)}" y1="${dp(ay)}" x2="${dp(bx)}" y2="${dp(by)}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linecap="round"/>`
1187
+ );
1188
+ state.penX = bx;
1189
+ state.penY = by;
1190
+ break;
1191
+ }
1192
+ case "cont": {
1193
+ const [bx, by] = toSVG(n(next()), n(next()));
1194
+ out.push(
1195
+ `<line x1="${dp(state.penX)}" y1="${dp(state.penY)}" x2="${dp(bx)}" y2="${dp(by)}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linecap="round"/>`
1196
+ );
1197
+ state.penX = bx;
1198
+ state.penY = by;
1199
+ break;
1200
+ }
1201
+ case "dot": {
1202
+ const [cx, cy] = toSVG(n(next()), n(next()));
1203
+ out.push(
1204
+ `<circle cx="${dp(cx)}" cy="${dp(cy)}" r="${dp(state.strokeWidth / 2)}" fill="${state.color}"/>`
1205
+ );
1206
+ break;
1207
+ }
1208
+ case "move":
1209
+ state.offx += n(next());
1210
+ state.offy += n(next());
1211
+ break;
1212
+ case "back":
1213
+ state.offx = 0;
1214
+ state.offy = 0;
1215
+ break;
1216
+ case "scale":
1217
+ state.size *= n(next());
1218
+ break;
1219
+ case "rect": {
1220
+ const cx = n(next()), cy = n(next());
1221
+ const hw = n(next()), hh = n(next());
1222
+ const [lx, ty] = toSVG(cx - hw, cy + hh);
1223
+ const [rx, by] = toSVG(cx + hw, cy - hh);
1224
+ const w = Math.abs(rx - lx), h = Math.abs(by - ty);
1225
+ const x = Math.min(lx, rx), y = Math.min(ty, by);
1226
+ out.push(`<rect x="${dp(x)}" y="${dp(y)}" width="${dp(w)}" height="${dp(h)}" fill="${state.color}"/>`);
1227
+ break;
1228
+ }
1229
+ case "square": {
1230
+ const cx = n(next()), cy = n(next());
1231
+ const hw = n(next()), hh = n(next());
1232
+ const corners = [
1233
+ toSVG(cx + hw, cy + hh),
1234
+ toSVG(cx - hw, cy + hh),
1235
+ toSVG(cx - hw, cy - hh),
1236
+ toSVG(cx + hw, cy - hh)
1237
+ ];
1238
+ const pts = [...corners, corners[0]].map((vals) => `${dp(vals[0])},${dp(vals[1])}`).join(" ");
1239
+ out.push(
1240
+ `<polyline points="${pts}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linejoin="round" stroke-linecap="round" fill="none"/>`
1241
+ );
1242
+ break;
1243
+ }
1244
+ case "tri": {
1245
+ const [x1, y1] = toSVG(n(next()), n(next()));
1246
+ const [x2, y2] = toSVG(n(next()), n(next()));
1247
+ const [x3, y3] = toSVG(n(next()), n(next()));
1248
+ out.push(
1249
+ `<polygon points="${dp(x1)},${dp(y1)} ${dp(x2)},${dp(y2)} ${dp(x3)},${dp(y3)}" fill="${state.color}"/>`
1250
+ );
1251
+ break;
1252
+ }
1253
+ case "cutcircle": {
1254
+ const cx = n(next()), cy = n(next());
1255
+ const radius = n(next());
1256
+ const dir = n(next());
1257
+ const arcDeg = n(next());
1258
+ let angleDeg = dir * 10 - arcDeg;
1259
+ const steps = Math.floor(arcDeg / 3);
1260
+ const pts = [];
1261
+ {
1262
+ const px = cx + Math.round(Math.sin(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1263
+ const py = cy + Math.round(Math.cos(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1264
+ const [sx, sy] = toSVG(px, py);
1265
+ pts.push(`M${dp(sx)},${dp(sy)}`);
1266
+ }
1267
+ for (let a = steps; a >= 0.5; a--) {
1268
+ angleDeg += 6;
1269
+ const px = cx + Math.round(Math.sin(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1270
+ const py = cy + Math.round(Math.cos(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1271
+ const [sx, sy] = toSVG(px, py);
1272
+ pts.push(`L${dp(sx)},${dp(sy)}`);
1273
+ }
1274
+ out.push(
1275
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`
1276
+ );
1277
+ break;
1278
+ }
1279
+ case "ellipse": {
1280
+ const elCx = n(next()), elCy = n(next());
1281
+ const rx = n(next());
1282
+ const mult = n(next());
1283
+ const rot = n(next());
1284
+ const ry = rx * mult;
1285
+ const [ccx, ccy] = toSVG(elCx, elCy);
1286
+ const ellipseRotDeg = 90 - rot;
1287
+ const pts = [];
1288
+ let eli = 0;
1289
+ {
1290
+ const lx = Math.round(Math.sin(Math.PI * eli / 180) * 1e10) / 1e10 * rx;
1291
+ const ly = Math.round(Math.cos(Math.PI * eli / 180) * 1e10) / 1e10 * rx * mult;
1292
+ const [rx2, ry2] = rotateVec(lx * state.size, ly * state.size, ellipseRotDeg);
1293
+ pts.push(`M${dp(ccx + rx2)},${dp(ccy - ry2)}`);
1294
+ }
1295
+ for (let a = 180; a >= 0.5; a--) {
1296
+ eli += 4;
1297
+ const lx = Math.round(Math.sin(Math.PI * eli / 180) * 1e10) / 1e10 * rx;
1298
+ const ly = Math.round(Math.cos(Math.PI * eli / 180) * 1e10) / 1e10 * rx * mult;
1299
+ const [drx, dry] = rotateVec(lx * state.size, ly * state.size, ellipseRotDeg);
1300
+ pts.push(`L${dp(ccx + drx)},${dp(ccy - dry)}`);
1301
+ }
1302
+ pts.push("Z");
1303
+ out.push(
1304
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none"/>`
1305
+ );
1306
+ break;
1307
+ }
1308
+ case "curve": {
1309
+ const rawX1 = next();
1310
+ if (rawX1 === "res") break;
1311
+ let x1 = n(rawX1), y1 = n(next());
1312
+ let x2 = n(next()), y2 = n(next());
1313
+ const cpx = n(next()), cpy = n(next());
1314
+ let cx1 = cpx - x1, cy1 = cpy - y1;
1315
+ let cx2 = cpx - x2, cy2 = cpy - y2;
1316
+ x2 = cpx;
1317
+ y2 = cpy;
1318
+ const res = Math.min(1e4, Math.round(state.size * 50));
1319
+ const [startX, startY] = toSVG(x1, y1);
1320
+ const pts = [`M${dp(startX)},${dp(startY)}`];
1321
+ for (let step = 1; step <= res; step++) {
1322
+ x1 += cx1 / res;
1323
+ y1 += cy1 / res;
1324
+ x2 -= cx2 / res;
1325
+ y2 -= cy2 / res;
1326
+ const per = step / res;
1327
+ const midX = (x2 - x1) * per + x1;
1328
+ const midY = (y2 - y1) * per + y1;
1329
+ const [sx, sy] = toSVG(midX, midY);
1330
+ pts.push(`L${dp(sx)},${dp(sy)}`);
1331
+ }
1332
+ out.push(
1333
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`
1334
+ );
1335
+ break;
1336
+ }
1337
+ case "icn": {
1338
+ if (!resolver) {
1339
+ next();
1340
+ next();
1341
+ next();
1342
+ next();
1343
+ break;
1344
+ }
1345
+ const name = next();
1346
+ const subScale = n(next()) * state.size;
1347
+ const subOx = n(next()), subOy = n(next());
1348
+ const resolved = resolver(name);
1349
+ if (resolved !== void 0) {
1350
+ const [sox, soy] = toSVG(subOx, subOy);
1351
+ renderTokens(
1352
+ tokenise(resolved),
1353
+ sox,
1354
+ soy,
1355
+ boldness,
1356
+ { ...state, size: subScale, offx: 0, offy: 0 },
1357
+ resolver,
1358
+ out
1359
+ );
1360
+ }
1361
+ break;
1362
+ }
1363
+ case "ricn": {
1364
+ const inlineStr = next();
1365
+ const subScale = n(next()) * state.size;
1366
+ const subOx = n(next()), subOy = n(next());
1367
+ const [sox, soy] = toSVG(subOx, subOy);
1368
+ renderTokens(
1369
+ tokenise(inlineStr),
1370
+ sox,
1371
+ soy,
1372
+ boldness,
1373
+ { ...state, size: subScale, offx: 0, offy: 0 },
1374
+ resolver,
1375
+ out
1376
+ );
1377
+ break;
1378
+ }
1379
+ }
1380
+ i++;
1381
+ }
1382
+ }
1383
+ function iconToSvg(iconString, options = {}) {
1384
+ const {
1385
+ size = 1,
1386
+ color = "#ffffff",
1387
+ strokeWidth = 1,
1388
+ boldness = 0,
1389
+ resolver,
1390
+ svgAttrs = {}
1391
+ } = options;
1392
+ const viewSize = options.viewSize ?? size * 20;
1393
+ const state = {
1394
+ penX: 0,
1395
+ penY: 0,
1396
+ penDown: false,
1397
+ color,
1398
+ strokeWidth,
1399
+ offx: 0,
1400
+ offy: 0,
1401
+ size
1402
+ };
1403
+ const elements = [];
1404
+ renderTokens(tokenise(iconString), 0, 0, boldness, state, resolver, elements);
1405
+ const vb = `${-viewSize} ${-viewSize} ${viewSize * 2} ${viewSize * 2}`;
1406
+ const attrs = Object.entries(svgAttrs).map(([k, v]) => ` ${k}="${v}"`).join("");
1407
+ return [
1408
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${vb}"${attrs}>`,
1409
+ ...elements,
1410
+ `</svg>`
1411
+ ].join("\n");
1412
+ }
1147
1413
  // Annotate the CommonJS export names for ESM import in node:
1148
1414
  0 && (module.exports = {
1149
1415
  ApiError,
1150
1416
  AuthError,
1151
1417
  Rotur,
1152
1418
  RoturSocket,
1419
+ iconToSvg,
1153
1420
  performAuth
1154
1421
  });
package/dist/index.mjs CHANGED
@@ -36,14 +36,8 @@ var Http = class {
36
36
  throw new ApiError(401, {
37
37
  error: "Not authenticated \u2014 call rotur.login() first"
38
38
  });
39
- const allParams = params;
40
- const opts = {
41
- method: "GET",
42
- headers: {
43
- ...token ? { Authorization: `Bearer ${token}` } : {}
44
- }
45
- };
46
- const res = await fetch(this.buildUrl(path, allParams), opts);
39
+ const allParams = auth && token ? { ...params, auth: token } : params;
40
+ const res = await fetch(this.buildUrl(path, allParams));
47
41
  return this.handle(res);
48
42
  }
49
43
  async post(path, body, auth = true) {
@@ -331,6 +325,11 @@ function performAuth(options) {
331
325
  const authUrl = new URL(AUTH_URL);
332
326
  if (options?.system) authUrl.searchParams.set("system", options.system);
333
327
  let iframe;
328
+ const w = window.open(
329
+ authUrl.toString(),
330
+ "rotur-auth",
331
+ "width=480,height=720"
332
+ );
334
333
  return new Promise((resolve, reject) => {
335
334
  const signal = options?.signal;
336
335
  const rejectWithError = (code, msg) => {
@@ -354,13 +353,12 @@ function performAuth(options) {
354
353
  window.removeEventListener("message", handler);
355
354
  signal?.removeEventListener("abort", onAbort);
356
355
  iframe?.remove();
356
+ try {
357
+ w?.close();
358
+ } catch {
359
+ }
357
360
  }
358
361
  window.addEventListener("message", handler);
359
- const w = window.open(
360
- authUrl.toString(),
361
- "rotur-auth",
362
- "width=480,height=720"
363
- );
364
362
  if (w) return;
365
363
  iframe = document.createElement("iframe");
366
364
  iframe.style.cssText = "position:fixed;inset:0;width:100%;height:100%;border:none;z-index:9999";
@@ -1114,10 +1112,278 @@ var CheckNamespace = class extends Namespace {
1114
1112
  return this.$post("/check/banned", usernames.join(","));
1115
1113
  }
1116
1114
  };
1115
+
1116
+ // src/icon.ts
1117
+ function dp(n2) {
1118
+ return (Math.round(n2 * 1e4) / 1e4).toString();
1119
+ }
1120
+ var n = (v) => +v || 0;
1121
+ function rotateVec(x, y, angleDeg) {
1122
+ const rad = angleDeg * Math.PI / 180;
1123
+ return [
1124
+ x * Math.cos(rad) - y * Math.sin(rad),
1125
+ x * Math.sin(rad) + y * Math.cos(rad)
1126
+ ];
1127
+ }
1128
+ function tokenise(src) {
1129
+ if (Array.isArray(src)) return src.map(String);
1130
+ return String(src).trim().split(/[ \n\t]+/g).filter(Boolean);
1131
+ }
1132
+ function renderTokens(tokens, ox, oy, boldness, state, resolver, out) {
1133
+ let i = 0;
1134
+ const next = () => tokens[++i] ?? "0";
1135
+ const toSVG = (lx, ly) => {
1136
+ const wx = state.offx + lx;
1137
+ const wy = state.offy + ly;
1138
+ return [ox + wx * state.size, oy - wy * state.size];
1139
+ };
1140
+ while (i < tokens.length) {
1141
+ const op = tokens[i];
1142
+ switch (op) {
1143
+ case "c":
1144
+ state.color = next();
1145
+ break;
1146
+ case "w": {
1147
+ const wArg = n(next());
1148
+ state.strokeWidth = Math.abs(wArg * state.size) * (boldness + 1);
1149
+ break;
1150
+ }
1151
+ case "line": {
1152
+ const [ax, ay] = toSVG(n(next()), n(next()));
1153
+ const [bx, by] = toSVG(n(next()), n(next()));
1154
+ out.push(
1155
+ `<line x1="${dp(ax)}" y1="${dp(ay)}" x2="${dp(bx)}" y2="${dp(by)}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linecap="round"/>`
1156
+ );
1157
+ state.penX = bx;
1158
+ state.penY = by;
1159
+ break;
1160
+ }
1161
+ case "cont": {
1162
+ const [bx, by] = toSVG(n(next()), n(next()));
1163
+ out.push(
1164
+ `<line x1="${dp(state.penX)}" y1="${dp(state.penY)}" x2="${dp(bx)}" y2="${dp(by)}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linecap="round"/>`
1165
+ );
1166
+ state.penX = bx;
1167
+ state.penY = by;
1168
+ break;
1169
+ }
1170
+ case "dot": {
1171
+ const [cx, cy] = toSVG(n(next()), n(next()));
1172
+ out.push(
1173
+ `<circle cx="${dp(cx)}" cy="${dp(cy)}" r="${dp(state.strokeWidth / 2)}" fill="${state.color}"/>`
1174
+ );
1175
+ break;
1176
+ }
1177
+ case "move":
1178
+ state.offx += n(next());
1179
+ state.offy += n(next());
1180
+ break;
1181
+ case "back":
1182
+ state.offx = 0;
1183
+ state.offy = 0;
1184
+ break;
1185
+ case "scale":
1186
+ state.size *= n(next());
1187
+ break;
1188
+ case "rect": {
1189
+ const cx = n(next()), cy = n(next());
1190
+ const hw = n(next()), hh = n(next());
1191
+ const [lx, ty] = toSVG(cx - hw, cy + hh);
1192
+ const [rx, by] = toSVG(cx + hw, cy - hh);
1193
+ const w = Math.abs(rx - lx), h = Math.abs(by - ty);
1194
+ const x = Math.min(lx, rx), y = Math.min(ty, by);
1195
+ out.push(`<rect x="${dp(x)}" y="${dp(y)}" width="${dp(w)}" height="${dp(h)}" fill="${state.color}"/>`);
1196
+ break;
1197
+ }
1198
+ case "square": {
1199
+ const cx = n(next()), cy = n(next());
1200
+ const hw = n(next()), hh = n(next());
1201
+ const corners = [
1202
+ toSVG(cx + hw, cy + hh),
1203
+ toSVG(cx - hw, cy + hh),
1204
+ toSVG(cx - hw, cy - hh),
1205
+ toSVG(cx + hw, cy - hh)
1206
+ ];
1207
+ const pts = [...corners, corners[0]].map((vals) => `${dp(vals[0])},${dp(vals[1])}`).join(" ");
1208
+ out.push(
1209
+ `<polyline points="${pts}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" stroke-linejoin="round" stroke-linecap="round" fill="none"/>`
1210
+ );
1211
+ break;
1212
+ }
1213
+ case "tri": {
1214
+ const [x1, y1] = toSVG(n(next()), n(next()));
1215
+ const [x2, y2] = toSVG(n(next()), n(next()));
1216
+ const [x3, y3] = toSVG(n(next()), n(next()));
1217
+ out.push(
1218
+ `<polygon points="${dp(x1)},${dp(y1)} ${dp(x2)},${dp(y2)} ${dp(x3)},${dp(y3)}" fill="${state.color}"/>`
1219
+ );
1220
+ break;
1221
+ }
1222
+ case "cutcircle": {
1223
+ const cx = n(next()), cy = n(next());
1224
+ const radius = n(next());
1225
+ const dir = n(next());
1226
+ const arcDeg = n(next());
1227
+ let angleDeg = dir * 10 - arcDeg;
1228
+ const steps = Math.floor(arcDeg / 3);
1229
+ const pts = [];
1230
+ {
1231
+ const px = cx + Math.round(Math.sin(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1232
+ const py = cy + Math.round(Math.cos(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1233
+ const [sx, sy] = toSVG(px, py);
1234
+ pts.push(`M${dp(sx)},${dp(sy)}`);
1235
+ }
1236
+ for (let a = steps; a >= 0.5; a--) {
1237
+ angleDeg += 6;
1238
+ const px = cx + Math.round(Math.sin(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1239
+ const py = cy + Math.round(Math.cos(Math.PI * angleDeg / 180) * 1e10) / 1e10 * radius;
1240
+ const [sx, sy] = toSVG(px, py);
1241
+ pts.push(`L${dp(sx)},${dp(sy)}`);
1242
+ }
1243
+ out.push(
1244
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`
1245
+ );
1246
+ break;
1247
+ }
1248
+ case "ellipse": {
1249
+ const elCx = n(next()), elCy = n(next());
1250
+ const rx = n(next());
1251
+ const mult = n(next());
1252
+ const rot = n(next());
1253
+ const ry = rx * mult;
1254
+ const [ccx, ccy] = toSVG(elCx, elCy);
1255
+ const ellipseRotDeg = 90 - rot;
1256
+ const pts = [];
1257
+ let eli = 0;
1258
+ {
1259
+ const lx = Math.round(Math.sin(Math.PI * eli / 180) * 1e10) / 1e10 * rx;
1260
+ const ly = Math.round(Math.cos(Math.PI * eli / 180) * 1e10) / 1e10 * rx * mult;
1261
+ const [rx2, ry2] = rotateVec(lx * state.size, ly * state.size, ellipseRotDeg);
1262
+ pts.push(`M${dp(ccx + rx2)},${dp(ccy - ry2)}`);
1263
+ }
1264
+ for (let a = 180; a >= 0.5; a--) {
1265
+ eli += 4;
1266
+ const lx = Math.round(Math.sin(Math.PI * eli / 180) * 1e10) / 1e10 * rx;
1267
+ const ly = Math.round(Math.cos(Math.PI * eli / 180) * 1e10) / 1e10 * rx * mult;
1268
+ const [drx, dry] = rotateVec(lx * state.size, ly * state.size, ellipseRotDeg);
1269
+ pts.push(`L${dp(ccx + drx)},${dp(ccy - dry)}`);
1270
+ }
1271
+ pts.push("Z");
1272
+ out.push(
1273
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none"/>`
1274
+ );
1275
+ break;
1276
+ }
1277
+ case "curve": {
1278
+ const rawX1 = next();
1279
+ if (rawX1 === "res") break;
1280
+ let x1 = n(rawX1), y1 = n(next());
1281
+ let x2 = n(next()), y2 = n(next());
1282
+ const cpx = n(next()), cpy = n(next());
1283
+ let cx1 = cpx - x1, cy1 = cpy - y1;
1284
+ let cx2 = cpx - x2, cy2 = cpy - y2;
1285
+ x2 = cpx;
1286
+ y2 = cpy;
1287
+ const res = Math.min(1e4, Math.round(state.size * 50));
1288
+ const [startX, startY] = toSVG(x1, y1);
1289
+ const pts = [`M${dp(startX)},${dp(startY)}`];
1290
+ for (let step = 1; step <= res; step++) {
1291
+ x1 += cx1 / res;
1292
+ y1 += cy1 / res;
1293
+ x2 -= cx2 / res;
1294
+ y2 -= cy2 / res;
1295
+ const per = step / res;
1296
+ const midX = (x2 - x1) * per + x1;
1297
+ const midY = (y2 - y1) * per + y1;
1298
+ const [sx, sy] = toSVG(midX, midY);
1299
+ pts.push(`L${dp(sx)},${dp(sy)}`);
1300
+ }
1301
+ out.push(
1302
+ `<path d="${pts.join("")}" stroke="${state.color}" stroke-width="${dp(state.strokeWidth)}" fill="none" stroke-linecap="round" stroke-linejoin="round"/>`
1303
+ );
1304
+ break;
1305
+ }
1306
+ case "icn": {
1307
+ if (!resolver) {
1308
+ next();
1309
+ next();
1310
+ next();
1311
+ next();
1312
+ break;
1313
+ }
1314
+ const name = next();
1315
+ const subScale = n(next()) * state.size;
1316
+ const subOx = n(next()), subOy = n(next());
1317
+ const resolved = resolver(name);
1318
+ if (resolved !== void 0) {
1319
+ const [sox, soy] = toSVG(subOx, subOy);
1320
+ renderTokens(
1321
+ tokenise(resolved),
1322
+ sox,
1323
+ soy,
1324
+ boldness,
1325
+ { ...state, size: subScale, offx: 0, offy: 0 },
1326
+ resolver,
1327
+ out
1328
+ );
1329
+ }
1330
+ break;
1331
+ }
1332
+ case "ricn": {
1333
+ const inlineStr = next();
1334
+ const subScale = n(next()) * state.size;
1335
+ const subOx = n(next()), subOy = n(next());
1336
+ const [sox, soy] = toSVG(subOx, subOy);
1337
+ renderTokens(
1338
+ tokenise(inlineStr),
1339
+ sox,
1340
+ soy,
1341
+ boldness,
1342
+ { ...state, size: subScale, offx: 0, offy: 0 },
1343
+ resolver,
1344
+ out
1345
+ );
1346
+ break;
1347
+ }
1348
+ }
1349
+ i++;
1350
+ }
1351
+ }
1352
+ function iconToSvg(iconString, options = {}) {
1353
+ const {
1354
+ size = 1,
1355
+ color = "#ffffff",
1356
+ strokeWidth = 1,
1357
+ boldness = 0,
1358
+ resolver,
1359
+ svgAttrs = {}
1360
+ } = options;
1361
+ const viewSize = options.viewSize ?? size * 20;
1362
+ const state = {
1363
+ penX: 0,
1364
+ penY: 0,
1365
+ penDown: false,
1366
+ color,
1367
+ strokeWidth,
1368
+ offx: 0,
1369
+ offy: 0,
1370
+ size
1371
+ };
1372
+ const elements = [];
1373
+ renderTokens(tokenise(iconString), 0, 0, boldness, state, resolver, elements);
1374
+ const vb = `${-viewSize} ${-viewSize} ${viewSize * 2} ${viewSize * 2}`;
1375
+ const attrs = Object.entries(svgAttrs).map(([k, v]) => ` ${k}="${v}"`).join("");
1376
+ return [
1377
+ `<svg xmlns="http://www.w3.org/2000/svg" viewBox="${vb}"${attrs}>`,
1378
+ ...elements,
1379
+ `</svg>`
1380
+ ].join("\n");
1381
+ }
1117
1382
  export {
1118
1383
  ApiError,
1119
1384
  AuthError,
1120
1385
  Rotur,
1121
1386
  RoturSocket,
1387
+ iconToSvg,
1122
1388
  performAuth
1123
1389
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rotur-sdk",
3
- "version": "1.0.10",
4
- "description": "The official SDK for the Rotur platform - auth, profiles, posts, credits, keys, groups, items, gifts, tokens, validators, status, files, cosmetics, push notifications, and more",
3
+ "version": "1.0.12",
4
+ "description": "The official SDK for the Rotur platform",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
7
7
  "types": "dist/index.d.ts",