From 0b21e445bd380cd7f5996e7576e8f422ed6f1acc Mon Sep 17 00:00:00 2001 From: Francisca Otero <48388881+FranciscaOtero@users.noreply.github.com> Date: Thu, 23 Apr 2026 16:19:47 -0400 Subject: [PATCH 1/5] feat: expose whoami and api_keys endpoints in SDK (#86) --- src/lib/core.ts | 6 ++++++ src/lib/managers/apiKeysManager.ts | 7 +++++++ src/lib/managers/index.ts | 2 ++ src/lib/managers/whoamiManager.ts | 7 +++++++ src/lib/resources/apiKey.ts | 4 ++++ src/lib/resources/whoami.ts | 4 ++++ src/spec/integration.spec.ts | 22 ++++++++++++++++++++++ 7 files changed, 52 insertions(+) create mode 100644 src/lib/managers/apiKeysManager.ts create mode 100644 src/lib/managers/whoamiManager.ts create mode 100644 src/lib/resources/apiKey.ts create mode 100644 src/lib/resources/whoami.ts diff --git a/src/lib/core.ts b/src/lib/core.ts index 4dce599..641322b 100644 --- a/src/lib/core.ts +++ b/src/lib/core.ts @@ -3,6 +3,7 @@ import { Client } from './client'; import { API_BASE_URL } from './constants'; import { AccountsManager, + ApiKeysManager, ChargesManager, CheckoutSessionsManager, InvoicesManager, @@ -15,6 +16,7 @@ import { SubscriptionsManager, TaxReturnsManager, WebhookEndpointsManager, + WhoamiManager, } from './managers'; import { AccountNumbersManager, @@ -81,6 +83,8 @@ export class Fintoc { subscriptionIntents: SubscriptionIntentsManager; taxReturns: TaxReturnsManager; webhookEndpoints: WebhookEndpointsManager; + apiKeys: ApiKeysManager; + whoami: WhoamiManager; v2: FintocV2; constructor(apiKey: string, jwsPrivateKey?: string) { @@ -103,6 +107,8 @@ export class Fintoc { this.subscriptionIntents = new SubscriptionIntentsManager('/v1/subscription_intents', this.#client); this.taxReturns = new TaxReturnsManager('/v1/tax_returns', this.#client); this.webhookEndpoints = new WebhookEndpointsManager('/v1/webhook_endpoints', this.#client); + this.apiKeys = new ApiKeysManager('/v1/api_keys', this.#client); + this.whoami = new WhoamiManager('/v1', this.#client); this.v2 = new FintocV2(this.#client); } diff --git a/src/lib/managers/apiKeysManager.ts b/src/lib/managers/apiKeysManager.ts new file mode 100644 index 0000000..092705b --- /dev/null +++ b/src/lib/managers/apiKeysManager.ts @@ -0,0 +1,7 @@ +import { ManagerMixin } from '../mixins'; +import { ApiKey } from '../resources/apiKey'; + +export class ApiKeysManager extends ManagerMixin { + static resource = 'api_key'; + static methods = ['list']; +} diff --git a/src/lib/managers/index.ts b/src/lib/managers/index.ts index a342e3e..58f84d1 100644 --- a/src/lib/managers/index.ts +++ b/src/lib/managers/index.ts @@ -12,3 +12,5 @@ export * from './subscriptionIntentsManager'; export * from './subscriptionsManager'; export * from './taxReturnsManager'; export * from './webhookEndpointsManager'; +export * from './apiKeysManager'; +export * from './whoamiManager'; diff --git a/src/lib/managers/whoamiManager.ts b/src/lib/managers/whoamiManager.ts new file mode 100644 index 0000000..b4281d4 --- /dev/null +++ b/src/lib/managers/whoamiManager.ts @@ -0,0 +1,7 @@ +import { ManagerMixin } from '../mixins'; +import { Whoami } from '../resources/whoami'; + +export class WhoamiManager extends ManagerMixin { + static resource = 'whoami'; + static methods = ['get']; +} diff --git a/src/lib/resources/apiKey.ts b/src/lib/resources/apiKey.ts new file mode 100644 index 0000000..8642ef1 --- /dev/null +++ b/src/lib/resources/apiKey.ts @@ -0,0 +1,4 @@ +import { ResourceMixin } from '../mixins/resourceMixin'; + +export class ApiKey extends ResourceMixin { +} diff --git a/src/lib/resources/whoami.ts b/src/lib/resources/whoami.ts new file mode 100644 index 0000000..186c034 --- /dev/null +++ b/src/lib/resources/whoami.ts @@ -0,0 +1,4 @@ +import { ResourceMixin } from '../mixins/resourceMixin'; + +export class Whoami extends ResourceMixin { +} diff --git a/src/spec/integration.spec.ts b/src/spec/integration.spec.ts index 654ce32..ccf4d59 100644 --- a/src/spec/integration.spec.ts +++ b/src/spec/integration.spec.ts @@ -1338,3 +1338,25 @@ test('fintoc.v2.products.create()', async (t) => { t.is(product.json.name, productData.name); t.is(product.json.currency, productData.currency); }); + +test('fintoc.apiKeys.list()', async (t) => { + const ctx: any = t.context; + const apiKeys = await ctx.fintoc.apiKeys.list(); + + let count = 0; + for await (const apiKey of apiKeys) { + count += 1; + t.is(apiKey.method, 'get'); + t.is(apiKey.url, 'v1/api_keys'); + } + + t.true(count > 0); +}); + +test('fintoc.whoami.get()', async (t) => { + const ctx: any = t.context; + const whoami = await ctx.fintoc.whoami.get('whoami'); + + t.is(whoami.method, 'get'); + t.is(whoami.url, 'v1/whoami'); +}); From 13e9945f1252ad5e9fc1f9cf144c8a67bf2df39a Mon Sep 17 00:00:00 2001 From: Francisca Otero <48388881+FranciscaOtero@users.noreply.github.com> Date: Thu, 23 Apr 2026 16:25:24 -0400 Subject: [PATCH 2/5] pre-release: prepare 1.18.0 release (#87) --- package.json | 2 +- src/lib/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f48aea0..6137a2a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fintoc", - "version": "1.17.0", + "version": "1.18.0", "description": "The official Node client for the Fintoc API.", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/src/lib/version.ts b/src/lib/version.ts index 8342077..ae72db1 100644 --- a/src/lib/version.ts +++ b/src/lib/version.ts @@ -1,3 +1,3 @@ -export const versionInfo = [1, 17, 0]; +export const versionInfo = [1, 18, 0]; export const version = versionInfo.join('.'); From ba6f0728cea24fa729d26a924ce82383d6994afe Mon Sep 17 00:00:00 2001 From: Francisca Otero <48388881+FranciscaOtero@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:43:14 -0400 Subject: [PATCH 3/5] feat: expose userAgent option in Fintoc constructor (#89) --- src/lib/core.ts | 4 ++-- src/spec/core.spec.ts | 14 ++++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/lib/core.ts b/src/lib/core.ts index 641322b..1c38482 100644 --- a/src/lib/core.ts +++ b/src/lib/core.ts @@ -87,10 +87,10 @@ export class Fintoc { whoami: WhoamiManager; v2: FintocV2; - constructor(apiKey: string, jwsPrivateKey?: string) { + constructor(apiKey: string, jwsPrivateKey?: string, options?: { userAgent?: string }) { this.#client = new Client({ baseUrl: `${API_BASE_URL}`, - userAgent: `fintoc-node/${version}`, + userAgent: options?.userAgent || `fintoc-node/${version}`, apiKey, jwsPrivateKey, }); diff --git a/src/spec/core.spec.ts b/src/spec/core.spec.ts index 71a8fb8..9624b20 100644 --- a/src/spec/core.spec.ts +++ b/src/spec/core.spec.ts @@ -9,3 +9,17 @@ test('"Fintoc" object creation', (t) => { t.assert(fintoc.links instanceof LinksManager); t.assert(fintoc.webhookEndpoints instanceof WebhookEndpointsManager); }); + +test('"Fintoc" object creation with custom userAgent', (t) => { + const apiKey = 'super_secret_api_key'; + const fintoc = new Fintoc(apiKey, undefined, { userAgent: 'fintoc-cli/0.1.0' }); + t.assert(fintoc.links instanceof LinksManager); + t.assert(fintoc.webhookEndpoints instanceof WebhookEndpointsManager); + t.is((fintoc.links as any)._client.userAgent, 'fintoc-cli/0.1.0'); +}); + +test('"Fintoc" object creation uses default userAgent when not provided', (t) => { + const apiKey = 'super_secret_api_key'; + const fintoc = new Fintoc(apiKey); + t.true((fintoc.links as any)._client.userAgent.startsWith('fintoc-node/')); +}); From 305eb1272fdd66c51c65d1a7d9d0210261c5a7bb Mon Sep 17 00:00:00 2001 From: Francisca Otero <48388881+FranciscaOtero@users.noreply.github.com> Date: Thu, 30 Apr 2026 14:49:27 -0400 Subject: [PATCH 4/5] fix: use strict ISO 8601 regex in isISODate to prevent plain strings being parsed as dates (#90) --- src/lib/utils.ts | 3 ++- src/spec/utils/getResourceClass.spec.ts | 6 ++++++ src/spec/utils/isISODate.spec.ts | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/lib/utils.ts b/src/lib/utils.ts index 75ff3e9..54eb328 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -44,7 +44,8 @@ export function singularize(rawString: string) { * @returns A boolean that represents if `rawDate` is parseable as a Date object */ export function isISODate(rawDate: string) { - return !Number.isNaN(Date.parse(rawDate)); + const isoDateRegex = /^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}:\d{2}(\.\d+)?(Z|[+-]\d{2}:?\d{2})?)?$/; + return isoDateRegex.test(rawDate); } /** diff --git a/src/spec/utils/getResourceClass.spec.ts b/src/spec/utils/getResourceClass.spec.ts index b86c771..d1057f4 100644 --- a/src/spec/utils/getResourceClass.spec.ts +++ b/src/spec/utils/getResourceClass.spec.ts @@ -28,6 +28,12 @@ test('"getResourceClass" string resource', async (t) => { t.is(klass, String); }); +test('"getResourceClass" ambiguous string that Date.parse accepts should remain String', async (t) => { + const resource = 'any_resource'; + t.is(await getResourceClass(resource, 'PS 2'), String); + t.is(await getResourceClass(resource, 'test 1'), String); +}); + test('"getResourceClass" number resource', async (t) => { const resource = 'any_resource'; const klass = await getResourceClass(resource, 15); diff --git a/src/spec/utils/isISODate.spec.ts b/src/spec/utils/isISODate.spec.ts index b73c3d7..fb6e379 100644 --- a/src/spec/utils/isISODate.spec.ts +++ b/src/spec/utils/isISODate.spec.ts @@ -7,7 +7,22 @@ test('"isISODate" valid ISO format', (t) => { t.assert(isISODate(validISODaTetimeString)); }); +test('"isISODate" valid ISO date without time', (t) => { + t.assert(isISODate('2021-08-13')); +}); + +test('"isISODate" valid ISO date with timezone offset', (t) => { + t.assert(isISODate('2021-08-13T13:40:40.811+05:00')); +}); + test('"isISODate" invalid ISO format', (t) => { const invalidISODaTetimeString = 'This is not a date'; t.assert(!isISODate(invalidISODaTetimeString)); }); + +test('"isISODate" should not parse ambiguous strings as dates', (t) => { + t.assert(!isISODate('PS 2')); + t.assert(!isISODate('test 1')); + t.assert(!isISODate('Mar 5')); + t.assert(!isISODate('Jan 2024')); +}); From f7e0664919a5ab2b17f26457c800474f88587eb3 Mon Sep 17 00:00:00 2001 From: Francisca Otero <48388881+FranciscaOtero@users.noreply.github.com> Date: Thu, 30 Apr 2026 15:21:39 -0400 Subject: [PATCH 5/5] pre-release: prepare 1.19.0 release (#91) --- package.json | 2 +- src/lib/version.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6137a2a..b0cc9a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "fintoc", - "version": "1.18.0", + "version": "1.19.0", "description": "The official Node client for the Fintoc API.", "main": "build/main/index.js", "typings": "build/main/index.d.ts", diff --git a/src/lib/version.ts b/src/lib/version.ts index ae72db1..ac21e6a 100644 --- a/src/lib/version.ts +++ b/src/lib/version.ts @@ -1,3 +1,3 @@ -export const versionInfo = [1, 18, 0]; +export const versionInfo = [1, 19, 0]; export const version = versionInfo.join('.');