feeef 0.8.5 → 0.8.10

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/README.md CHANGED
@@ -2,6 +2,14 @@
2
2
 
3
3
  `feeefjs` is a TypeScript library for managing feeef e-commerce platforms for self-hosted stores. It provides a wrapper for feeef rest api such like send order..., also have frontend srvices like the `CartService` class for managing cart items, shipping methods, and calculating totals. The library also includes a `NotifiableService` base class for handling listeners that react to changes in the service state.
4
4
 
5
+ ## Developer OAuth (third-party apps)
6
+
7
+ Use `OAuthRepository.buildAuthorizeUrl` (point `baseUrl` at the **accounts** host, e.g. `https://accounts.feeef.org`) and `FeeeF` client `oauth.exchangeAuthorizationCode` / `revokeToken` / `introspectToken` against the **API** base (`.../v1`). Full flow, scopes, and troubleshooting: Feeef backend **`docs/OAUTH2_DEVELOPER.md`** (in the Adonis API repo).
8
+
9
+ ## Realtime (AdonisJS Transmit)
10
+
11
+ Server-Sent Events use the same **API origin** as the REST client, but **without** the `/v1` or `/api/v1` prefix (e.g. `https://api.feeef.org/__transmit/events`). Use `createFeeefTransmit({ apiBaseUrl, getAccessToken })` so subscribe/unsubscribe POSTs get a proper `Authorization: Bearer …` header. The underlying client is the official [`@adonisjs/transmit-client`](https://www.npmjs.com/package/@adonisjs/transmit-client) (`Transmit`, `Subscription` are re-exported).
12
+
5
13
  ---
6
14
 
7
15
  # CartService & NotifiableService
package/build/index.js CHANGED
@@ -661,6 +661,27 @@ var UserRepository = class extends ModelRepository {
661
661
  const res = await this.client.get(`/${this.resource}/auth/tokens`);
662
662
  return res.data;
663
663
  }
664
+ /**
665
+ * Revokes an access token (session) by opaque identifier from {@link tokens}.
666
+ */
667
+ async revokeAccessToken(identifier) {
668
+ if (!identifier || identifier === "undefined") {
669
+ throw new Error("Missing access token identifier");
670
+ }
671
+ await this.client.delete(`/${this.resource}/auth/tokens/${encodeURIComponent(identifier)}`);
672
+ }
673
+ /** Revokes every access token for the current user (sign out everywhere). */
674
+ async revokeAllAccessTokens() {
675
+ const res = await this.client.post(`/${this.resource}/auth/tokens/revoke-all`);
676
+ return res.data;
677
+ }
678
+ /**
679
+ * Lists OAuth apps that have per-user stored data for the current user (`app_user` rows).
680
+ */
681
+ async connectedApps() {
682
+ const res = await this.client.get(`/${this.resource}/auth/connected-apps`);
683
+ return res.data;
684
+ }
664
685
  /**
665
686
  * Signs in with Google OAuth.
666
687
  * @param options - The OAuth code and optional FCM token.
@@ -848,6 +869,9 @@ var AppRepository = class extends ModelRepository {
848
869
  * Builds the OAuth authorize URL to which the user should be redirected.
849
870
  * This is the first step of the authorization-code flow (similar UX to Google OAuth).
850
871
  *
872
+ * Production: opening this URL on the **API** host (`api.*`) issues a redirect to the same path on
873
+ * **accounts.*** so the consent screen appears on the trusted accounts domain; query params are preserved.
874
+ *
851
875
  * If the user is not logged in yet, API `GET /oauth/authorize` returns:
852
876
  * - `401 login_required`
853
877
  * - `login_url` (accounts sign-in URL with `next=...`)
@@ -880,6 +904,47 @@ var AppRepository = class extends ModelRepository {
880
904
  }
881
905
  return url.toString();
882
906
  }
907
+ /**
908
+ * Public `apps.public_data` (no auth). Pass [config] to skip Authorization if your axios instance adds it globally.
909
+ */
910
+ async getPublicData(id, config) {
911
+ const res = await this.client.get(`/${this.resource}/${id}/public-data`, config);
912
+ return res.data;
913
+ }
914
+ async getPrivateData(id) {
915
+ const res = await this.client.get(`/${this.resource}/${id}/private-data`);
916
+ return res.data;
917
+ }
918
+ async putPublicData(id, publicNamespaces) {
919
+ const res = await this.client.put(`/${this.resource}/${id}/public-data`, {
920
+ public: publicNamespaces
921
+ });
922
+ return res.data;
923
+ }
924
+ async putPrivateData(id, privateNamespaces) {
925
+ const res = await this.client.put(`/${this.resource}/${id}/private-data`, {
926
+ private: privateNamespaces
927
+ });
928
+ return res.data;
929
+ }
930
+ async getUserDataMe(id) {
931
+ const res = await this.client.get(`/${this.resource}/${id}/user-data/me`);
932
+ return res.data;
933
+ }
934
+ async putUserDataMe(id, publicNamespaces) {
935
+ const res = await this.client.put(`/${this.resource}/${id}/user-data/me`, {
936
+ public: publicNamespaces
937
+ });
938
+ return res.data;
939
+ }
940
+ async getUserDataForUser(appId, userId) {
941
+ const res = await this.client.get(`/${this.resource}/${appId}/user-data/users/${userId}`);
942
+ return res.data;
943
+ }
944
+ async putUserDataForUser(appId, userId, body) {
945
+ const res = await this.client.put(`/${this.resource}/${appId}/user-data/users/${userId}`, body);
946
+ return res.data;
947
+ }
883
948
  };
884
949
 
885
950
  // src/feeef/repositories/oauth.ts
@@ -4056,6 +4121,77 @@ var EmbaddedContactType = /* @__PURE__ */ ((EmbaddedContactType2) => {
4056
4121
  return EmbaddedContactType2;
4057
4122
  })(EmbaddedContactType || {});
4058
4123
 
4124
+ // src/realtime/transmit.ts
4125
+ import { Transmit } from "@adonisjs/transmit-client";
4126
+ import { Subscription, Transmit as Transmit2 } from "@adonisjs/transmit-client";
4127
+ function transmitRootFromApiBaseUrl(apiBaseUrl) {
4128
+ let u = apiBaseUrl.trim().replace(/\/+$/, "");
4129
+ if (u.endsWith("/api/v1")) {
4130
+ u = u.slice(0, -"/api/v1".length);
4131
+ } else if (u.endsWith("/v1")) {
4132
+ u = u.slice(0, -"/v1".length);
4133
+ }
4134
+ return u;
4135
+ }
4136
+ function retrieveXsrfTokenFromCookie() {
4137
+ const cookie = globalThis.document?.cookie;
4138
+ if (!cookie) return null;
4139
+ const match = cookie.match(new RegExp("(^|;\\s*)(XSRF-TOKEN)=([^;]*)"));
4140
+ return match ? decodeURIComponent(match[3]) : null;
4141
+ }
4142
+ var FeeefTransmitHttpClient = class {
4143
+ constructor(options, getAuthorizationHeader) {
4144
+ this.options = options;
4145
+ this.getAuthorizationHeader = getAuthorizationHeader;
4146
+ }
4147
+ send(request) {
4148
+ return fetch(request);
4149
+ }
4150
+ createRequest(path, body) {
4151
+ const headers = {
4152
+ "Content-Type": "application/json",
4153
+ "X-XSRF-TOKEN": retrieveXsrfTokenFromCookie() ?? ""
4154
+ };
4155
+ const auth = this.getAuthorizationHeader();
4156
+ if (auth) {
4157
+ headers.Authorization = auth.startsWith("Bearer ") ? auth : `Bearer ${auth}`;
4158
+ }
4159
+ return new Request(`${this.options.baseUrl}${path}`, {
4160
+ method: "POST",
4161
+ headers,
4162
+ body: JSON.stringify({ uid: this.options.uid, ...body }),
4163
+ credentials: "include"
4164
+ });
4165
+ }
4166
+ };
4167
+ function createFeeefTransmit(options) {
4168
+ const baseUrl = transmitRootFromApiBaseUrl(options.apiBaseUrl);
4169
+ const getToken = options.getAccessToken ?? (() => void 0);
4170
+ return new Transmit({
4171
+ ...options.transmit,
4172
+ baseUrl,
4173
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Transmit’s HttpClient is not exported; FeeefTransmitHttpClient matches its shape.
4174
+ httpClientFactory: (url, uid) => new FeeefTransmitHttpClient({ baseUrl: url, uid }, () => {
4175
+ const t = getToken();
4176
+ if (t === null || t === void 0 || t === "") return void 0;
4177
+ const s = String(t).trim();
4178
+ return s.startsWith("Bearer ") ? s : `Bearer ${s}`;
4179
+ })
4180
+ });
4181
+ }
4182
+ function createFeeefTransmitFromAxios(client, options) {
4183
+ const apiBaseUrl = client.defaults.baseURL ?? "";
4184
+ return createFeeefTransmit({
4185
+ ...options,
4186
+ apiBaseUrl,
4187
+ getAccessToken: () => {
4188
+ const raw = client.defaults.headers.common?.Authorization;
4189
+ if (typeof raw !== "string") return void 0;
4190
+ return raw.replace(/^Bearer\s+/i, "").trim() || void 0;
4191
+ }
4192
+ });
4193
+ }
4194
+
4059
4195
  // src/utils.ts
4060
4196
  var convertDartColorToCssNumber = (dartColor) => {
4061
4197
  const alpha = dartColor >> 24 & 255;
@@ -4158,6 +4294,7 @@ export {
4158
4294
  FeedbackRepository,
4159
4295
  FeedbackStatus,
4160
4296
  FeeeF,
4297
+ FeeefTransmitHttpClient,
4161
4298
  GoogleSheetIntegrationApi,
4162
4299
  ImageGenerationsRepository,
4163
4300
  ImagePromptTemplatesRepository,
@@ -4192,8 +4329,10 @@ export {
4192
4329
  StoreRepository,
4193
4330
  StoreSubscriptionStatus,
4194
4331
  StoreSubscriptionType,
4332
+ Subscription,
4195
4333
  TiktokPixelEvent,
4196
4334
  TransferRepository,
4335
+ Transmit2 as Transmit,
4197
4336
  UserRepository,
4198
4337
  VariantOptionType,
4199
4338
  WebhookEvent,
@@ -4202,6 +4341,8 @@ export {
4202
4341
  ZimouDeliveryIntegrationApi,
4203
4342
  convertDartColorToCssNumber,
4204
4343
  convertOrderEntityToOrderTrackEntity,
4344
+ createFeeefTransmit,
4345
+ createFeeefTransmitFromAxios,
4205
4346
  createImageGenerationFormData,
4206
4347
  cssColorToHslString,
4207
4348
  dartColorToCssColor,
@@ -4237,6 +4378,7 @@ export {
4237
4378
  serializeAttachmentPayloads,
4238
4379
  serializeImagePromptTemplateCreate,
4239
4380
  serializeImagePromptTemplateUpdate,
4381
+ transmitRootFromApiBaseUrl,
4240
4382
  tryFixPhoneNumber,
4241
4383
  validatePhoneNumber
4242
4384
  };