@skalpgg/sdk 1.4.0 → 1.5.0
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 +1 -1
- package/dist/cjs/index.d.ts +2 -2
- package/dist/cjs/index.js +22 -4
- package/dist/cjs/types.d.ts +37 -1
- package/dist/esm/index.d.ts +2 -2
- package/dist/esm/index.js +22 -4
- package/dist/esm/types.d.ts +37 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,7 +47,7 @@ Create the key on the API keys page of your dashboard. Each key is bound to one
|
|
|
47
47
|
| `orders.get(id)` | `orders:read` |
|
|
48
48
|
| `orders.cancel(id)` | `orders:write` |
|
|
49
49
|
| `orders.replace(id, { serialIds?, values?, reason? })` | `orders:write` |
|
|
50
|
-
| `products.list({ status? })` | `products:read` |
|
|
50
|
+
| `products.list({ status?, limit?, offset? })` | `products:read` |
|
|
51
51
|
| `products.get(idOrSlug)` | `products:read` |
|
|
52
52
|
| `products.create({ name, price, fulfillmentType?, submit?, ... })` | `products:write` |
|
|
53
53
|
| `products.update(idOrSlug, { price?, status?: 'DRAFT' \| 'ARCHIVED', ... })` | `products:write` |
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.5.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -42,7 +42,7 @@ export declare class Skalp {
|
|
|
42
42
|
replace: (id: string, { serialIds, values, reason }?: ReplaceOrderKeysParams) => Promise<OrderKeysReplaced>;
|
|
43
43
|
};
|
|
44
44
|
readonly products: {
|
|
45
|
-
list: ({ status }?: ListProductsParams) => Promise<Product
|
|
45
|
+
list: ({ status, limit, offset }?: ListProductsParams) => Promise<Array<Product>>;
|
|
46
46
|
get: (idOrSlug: string) => Promise<Product>;
|
|
47
47
|
create: (params: CreateProductParams) => Promise<Product>;
|
|
48
48
|
update: (idOrSlug: string, params: UpdateProductParams) => Promise<Product>;
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Skalp = exports.SkalpSignatureError = exports.SkalpConnectionError = exports.SkalpError = exports.VERSION = void 0;
|
|
4
|
-
exports.VERSION = '1.
|
|
4
|
+
exports.VERSION = '1.5.0';
|
|
5
5
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
6
6
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
7
|
+
const PRODUCT_PAGE = 100;
|
|
7
8
|
const USER_AGENT = `skalp-node/${exports.VERSION}`;
|
|
8
9
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
9
10
|
const MAX_RETRY_WAIT_SECONDS = 10;
|
|
@@ -128,7 +129,21 @@ class Skalp {
|
|
|
128
129
|
}),
|
|
129
130
|
};
|
|
130
131
|
products = {
|
|
131
|
-
list: ({ status } = {}) =>
|
|
132
|
+
list: async ({ status, limit, offset } = {}) => {
|
|
133
|
+
if (limit !== undefined || offset !== undefined) {
|
|
134
|
+
return (await this.#send('GET', '/v1/products', { query: { status, limit, offset } })).data;
|
|
135
|
+
}
|
|
136
|
+
const products = [];
|
|
137
|
+
for (;;) {
|
|
138
|
+
const page = await this.#send('GET', '/v1/products', {
|
|
139
|
+
query: { status, limit: PRODUCT_PAGE, offset: products.length },
|
|
140
|
+
});
|
|
141
|
+
products.push(...page.data);
|
|
142
|
+
const total = Number(page.headers.get('x-total-count'));
|
|
143
|
+
if (page.data.length < PRODUCT_PAGE || products.length >= total)
|
|
144
|
+
return products;
|
|
145
|
+
}
|
|
146
|
+
},
|
|
132
147
|
get: (idOrSlug) => this.#request('GET', `/v1/products/${segment(idOrSlug)}`),
|
|
133
148
|
create: (params) => this.#request('POST', '/v1/products', {
|
|
134
149
|
body: pick(params, [...PRODUCT_FIELDS, 'productType', 'submit']),
|
|
@@ -294,7 +309,10 @@ class Skalp {
|
|
|
294
309
|
const hmac = await crypto.subtle.importKey('raw', encoder.encode(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
295
310
|
return (await crypto.subtle.verify('HMAC', hmac, parsed.signature, signed)) ? undefined : 'invalid';
|
|
296
311
|
}
|
|
297
|
-
async #request(method, path,
|
|
312
|
+
async #request(method, path, options = {}) {
|
|
313
|
+
return (await this.#send(method, path, options)).data;
|
|
314
|
+
}
|
|
315
|
+
async #send(method, path, { body, query, auth = true } = {}) {
|
|
298
316
|
if (auth && !this.#apiKey) {
|
|
299
317
|
throw new Error('Skalp: missing API key. Pass it to new Skalp(apiKey) or set SKALP_API_KEY.');
|
|
300
318
|
}
|
|
@@ -339,7 +357,7 @@ class Skalp {
|
|
|
339
357
|
}
|
|
340
358
|
if (!res.ok)
|
|
341
359
|
throw toError(res.status, data);
|
|
342
|
-
return data;
|
|
360
|
+
return { data: data, headers: res.headers };
|
|
343
361
|
}
|
|
344
362
|
}
|
|
345
363
|
}
|
package/dist/cjs/types.d.ts
CHANGED
|
@@ -205,6 +205,13 @@ export interface Product {
|
|
|
205
205
|
deliveryType: DeliveryType | null;
|
|
206
206
|
/** Server stores: what the game server runs after payment. */
|
|
207
207
|
deliveryPayload: string | null;
|
|
208
|
+
revokePayload: string | null;
|
|
209
|
+
coinConfig: CoinConfig | null;
|
|
210
|
+
pendingChanges: {
|
|
211
|
+
submittedAt: string;
|
|
212
|
+
changes: Partial<Record<ReviewedProductField, unknown>>;
|
|
213
|
+
} | null;
|
|
214
|
+
pendingChangesRejection: string | null;
|
|
208
215
|
visibility: ProductVisibility;
|
|
209
216
|
/** Higher comes first on the store page. */
|
|
210
217
|
sortPriority: number;
|
|
@@ -232,8 +239,24 @@ export interface Product {
|
|
|
232
239
|
createdAt: string;
|
|
233
240
|
updatedAt: string;
|
|
234
241
|
}
|
|
242
|
+
export interface CoinBonusTier {
|
|
243
|
+
thresholdCoins: number;
|
|
244
|
+
bonusPercent: number;
|
|
245
|
+
}
|
|
246
|
+
export interface CoinConfig {
|
|
247
|
+
unitPriceCents: number;
|
|
248
|
+
minQty: number;
|
|
249
|
+
maxQty: number;
|
|
250
|
+
step: number;
|
|
251
|
+
currency: string;
|
|
252
|
+
bonusTiers: Array<CoinBonusTier>;
|
|
253
|
+
}
|
|
254
|
+
export type CoinConfigInput = Omit<CoinConfig, 'currency'>;
|
|
255
|
+
export type ReviewedProductField = 'name' | 'shortDescription' | 'description' | 'images' | 'videoUrl' | 'features' | 'requirements' | 'customFields' | 'deliveryNote' | 'termsOfService' | 'warrantyText' | 'deliveryType' | 'deliveryPayload' | 'revokePayload';
|
|
235
256
|
export interface ListProductsParams {
|
|
236
257
|
status?: ProductStatus | 'all';
|
|
258
|
+
limit?: number;
|
|
259
|
+
offset?: number;
|
|
237
260
|
}
|
|
238
261
|
interface ProductFields {
|
|
239
262
|
slug?: string;
|
|
@@ -255,6 +278,8 @@ interface ProductFields {
|
|
|
255
278
|
deliveryType?: DeliveryType;
|
|
256
279
|
/** Required for a server store; needs a placeholder such as {steamhex}. */
|
|
257
280
|
deliveryPayload?: string;
|
|
281
|
+
revokePayload?: string;
|
|
282
|
+
coinConfig?: CoinConfigInput;
|
|
258
283
|
visibility?: ProductVisibility;
|
|
259
284
|
sortPriority?: number;
|
|
260
285
|
/** null or an empty string clears it. */
|
|
@@ -279,7 +304,7 @@ export interface CreateProductParams extends ProductFields {
|
|
|
279
304
|
name: string;
|
|
280
305
|
price: number;
|
|
281
306
|
comparePrice?: number;
|
|
282
|
-
productType?: 'ONE_TIME' | 'RECURRING';
|
|
307
|
+
productType?: 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
283
308
|
submit?: boolean;
|
|
284
309
|
}
|
|
285
310
|
export interface UpdateProductParams extends ProductFields {
|
|
@@ -799,6 +824,16 @@ export interface OrderRefundedData {
|
|
|
799
824
|
granted?: boolean;
|
|
800
825
|
fullRefund: boolean;
|
|
801
826
|
licenses: Array<WebhookLicense>;
|
|
827
|
+
revocations: Array<Revocation>;
|
|
828
|
+
}
|
|
829
|
+
export interface Revocation {
|
|
830
|
+
productId: string;
|
|
831
|
+
productSlug: string;
|
|
832
|
+
productName: string;
|
|
833
|
+
deliveryKey: string;
|
|
834
|
+
delivered: boolean;
|
|
835
|
+
deliveryType: DeliveryType;
|
|
836
|
+
revokeCommand: string;
|
|
802
837
|
}
|
|
803
838
|
export interface OrderDisputedData {
|
|
804
839
|
orderId: string;
|
|
@@ -914,6 +949,7 @@ export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.can
|
|
|
914
949
|
}> | Envelope<'subscription.canceled', SubscriptionEventData & {
|
|
915
950
|
endedAt: string | null;
|
|
916
951
|
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe';
|
|
952
|
+
revokeCommand?: string;
|
|
917
953
|
}> | Envelope<'subscription.refunded', SubscriptionEventData & {
|
|
918
954
|
invoiceId: string;
|
|
919
955
|
amountRefunded: number;
|
package/dist/esm/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { AccessRule, AddAccessRuleParams, AddSerialsParams, AddSerialsResult, AppealFeedbackParams, ChangeSubscriptionPlanParams, CheckoutSession, CheckoutSessionStatus, CoinCheckout, CoinCheckoutStatus, Coupon, CreateCheckoutParams, CreateCoinCheckoutParams, CreateCouponParams, CreateCustomerParams, CreateProductGroupParams, CreateProductParams, CreateStoreCategoryParams, CreateSubscriptionCheckoutParams, CreateUsageChargeParams, Customer, CustomerDetails, CustomerList, Deleted, Feedback, FeedbackList, HeartbeatParams, Invoice, LicenseKeyInfo, LicenseValidation, LicenseVerification, ListAccessRulesParams, ListCustomersParams, ListFeedbackParams, ListOrdersParams, ListProductsParams, ListQueriesParams, ListSerialsParams, ListSubscriptionsParams, Order, OrderKeysReplaced, OrderList, Product, ProductGroup, ProductStock, ReplaceOrderKeysParams, ReplyParams, SerialList, SkalpEvent, StoreCategory, StoreCategoryWithCount, Subscription, SubscriptionCheckout, SubscriptionCheckoutStatus, SubscriptionList, SupportQueryDetails, SupportQueryList, ResetLicenseDevicesParams, UpdateCouponParams, UpdateCustomerParams, UpdateProductGroupParams, UpdateProductParams, UpdateStoreCategoryParams, UsageCharge, ValidateLicenseParams, VerifyLicenseParams } from './types.js';
|
|
2
2
|
export type * from './types.js';
|
|
3
|
-
export declare const VERSION = "1.
|
|
3
|
+
export declare const VERSION = "1.5.0";
|
|
4
4
|
export interface SkalpOptions {
|
|
5
5
|
apiKey?: string;
|
|
6
6
|
webhookSecret?: string;
|
|
@@ -42,7 +42,7 @@ export declare class Skalp {
|
|
|
42
42
|
replace: (id: string, { serialIds, values, reason }?: ReplaceOrderKeysParams) => Promise<OrderKeysReplaced>;
|
|
43
43
|
};
|
|
44
44
|
readonly products: {
|
|
45
|
-
list: ({ status }?: ListProductsParams) => Promise<Product
|
|
45
|
+
list: ({ status, limit, offset }?: ListProductsParams) => Promise<Array<Product>>;
|
|
46
46
|
get: (idOrSlug: string) => Promise<Product>;
|
|
47
47
|
create: (params: CreateProductParams) => Promise<Product>;
|
|
48
48
|
update: (idOrSlug: string, params: UpdateProductParams) => Promise<Product>;
|
package/dist/esm/index.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export const VERSION = '1.
|
|
1
|
+
export const VERSION = '1.5.0';
|
|
2
2
|
const SIGNATURE_HEADER = 'skalp-signature';
|
|
3
3
|
const SIGNATURE_TOLERANCE_SECONDS = 300;
|
|
4
|
+
const PRODUCT_PAGE = 100;
|
|
4
5
|
const USER_AGENT = `skalp-node/${VERSION}`;
|
|
5
6
|
const DEFAULT_TIMEOUT_MS = 30_000;
|
|
6
7
|
const MAX_RETRY_WAIT_SECONDS = 10;
|
|
@@ -122,7 +123,21 @@ export class Skalp {
|
|
|
122
123
|
}),
|
|
123
124
|
};
|
|
124
125
|
products = {
|
|
125
|
-
list: ({ status } = {}) =>
|
|
126
|
+
list: async ({ status, limit, offset } = {}) => {
|
|
127
|
+
if (limit !== undefined || offset !== undefined) {
|
|
128
|
+
return (await this.#send('GET', '/v1/products', { query: { status, limit, offset } })).data;
|
|
129
|
+
}
|
|
130
|
+
const products = [];
|
|
131
|
+
for (;;) {
|
|
132
|
+
const page = await this.#send('GET', '/v1/products', {
|
|
133
|
+
query: { status, limit: PRODUCT_PAGE, offset: products.length },
|
|
134
|
+
});
|
|
135
|
+
products.push(...page.data);
|
|
136
|
+
const total = Number(page.headers.get('x-total-count'));
|
|
137
|
+
if (page.data.length < PRODUCT_PAGE || products.length >= total)
|
|
138
|
+
return products;
|
|
139
|
+
}
|
|
140
|
+
},
|
|
126
141
|
get: (idOrSlug) => this.#request('GET', `/v1/products/${segment(idOrSlug)}`),
|
|
127
142
|
create: (params) => this.#request('POST', '/v1/products', {
|
|
128
143
|
body: pick(params, [...PRODUCT_FIELDS, 'productType', 'submit']),
|
|
@@ -288,7 +303,10 @@ export class Skalp {
|
|
|
288
303
|
const hmac = await crypto.subtle.importKey('raw', encoder.encode(key), { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
289
304
|
return (await crypto.subtle.verify('HMAC', hmac, parsed.signature, signed)) ? undefined : 'invalid';
|
|
290
305
|
}
|
|
291
|
-
async #request(method, path,
|
|
306
|
+
async #request(method, path, options = {}) {
|
|
307
|
+
return (await this.#send(method, path, options)).data;
|
|
308
|
+
}
|
|
309
|
+
async #send(method, path, { body, query, auth = true } = {}) {
|
|
292
310
|
if (auth && !this.#apiKey) {
|
|
293
311
|
throw new Error('Skalp: missing API key. Pass it to new Skalp(apiKey) or set SKALP_API_KEY.');
|
|
294
312
|
}
|
|
@@ -333,7 +351,7 @@ export class Skalp {
|
|
|
333
351
|
}
|
|
334
352
|
if (!res.ok)
|
|
335
353
|
throw toError(res.status, data);
|
|
336
|
-
return data;
|
|
354
|
+
return { data: data, headers: res.headers };
|
|
337
355
|
}
|
|
338
356
|
}
|
|
339
357
|
}
|
package/dist/esm/types.d.ts
CHANGED
|
@@ -205,6 +205,13 @@ export interface Product {
|
|
|
205
205
|
deliveryType: DeliveryType | null;
|
|
206
206
|
/** Server stores: what the game server runs after payment. */
|
|
207
207
|
deliveryPayload: string | null;
|
|
208
|
+
revokePayload: string | null;
|
|
209
|
+
coinConfig: CoinConfig | null;
|
|
210
|
+
pendingChanges: {
|
|
211
|
+
submittedAt: string;
|
|
212
|
+
changes: Partial<Record<ReviewedProductField, unknown>>;
|
|
213
|
+
} | null;
|
|
214
|
+
pendingChangesRejection: string | null;
|
|
208
215
|
visibility: ProductVisibility;
|
|
209
216
|
/** Higher comes first on the store page. */
|
|
210
217
|
sortPriority: number;
|
|
@@ -232,8 +239,24 @@ export interface Product {
|
|
|
232
239
|
createdAt: string;
|
|
233
240
|
updatedAt: string;
|
|
234
241
|
}
|
|
242
|
+
export interface CoinBonusTier {
|
|
243
|
+
thresholdCoins: number;
|
|
244
|
+
bonusPercent: number;
|
|
245
|
+
}
|
|
246
|
+
export interface CoinConfig {
|
|
247
|
+
unitPriceCents: number;
|
|
248
|
+
minQty: number;
|
|
249
|
+
maxQty: number;
|
|
250
|
+
step: number;
|
|
251
|
+
currency: string;
|
|
252
|
+
bonusTiers: Array<CoinBonusTier>;
|
|
253
|
+
}
|
|
254
|
+
export type CoinConfigInput = Omit<CoinConfig, 'currency'>;
|
|
255
|
+
export type ReviewedProductField = 'name' | 'shortDescription' | 'description' | 'images' | 'videoUrl' | 'features' | 'requirements' | 'customFields' | 'deliveryNote' | 'termsOfService' | 'warrantyText' | 'deliveryType' | 'deliveryPayload' | 'revokePayload';
|
|
235
256
|
export interface ListProductsParams {
|
|
236
257
|
status?: ProductStatus | 'all';
|
|
258
|
+
limit?: number;
|
|
259
|
+
offset?: number;
|
|
237
260
|
}
|
|
238
261
|
interface ProductFields {
|
|
239
262
|
slug?: string;
|
|
@@ -255,6 +278,8 @@ interface ProductFields {
|
|
|
255
278
|
deliveryType?: DeliveryType;
|
|
256
279
|
/** Required for a server store; needs a placeholder such as {steamhex}. */
|
|
257
280
|
deliveryPayload?: string;
|
|
281
|
+
revokePayload?: string;
|
|
282
|
+
coinConfig?: CoinConfigInput;
|
|
258
283
|
visibility?: ProductVisibility;
|
|
259
284
|
sortPriority?: number;
|
|
260
285
|
/** null or an empty string clears it. */
|
|
@@ -279,7 +304,7 @@ export interface CreateProductParams extends ProductFields {
|
|
|
279
304
|
name: string;
|
|
280
305
|
price: number;
|
|
281
306
|
comparePrice?: number;
|
|
282
|
-
productType?: 'ONE_TIME' | 'RECURRING';
|
|
307
|
+
productType?: 'ONE_TIME' | 'RECURRING' | 'COINS';
|
|
283
308
|
submit?: boolean;
|
|
284
309
|
}
|
|
285
310
|
export interface UpdateProductParams extends ProductFields {
|
|
@@ -799,6 +824,16 @@ export interface OrderRefundedData {
|
|
|
799
824
|
granted?: boolean;
|
|
800
825
|
fullRefund: boolean;
|
|
801
826
|
licenses: Array<WebhookLicense>;
|
|
827
|
+
revocations: Array<Revocation>;
|
|
828
|
+
}
|
|
829
|
+
export interface Revocation {
|
|
830
|
+
productId: string;
|
|
831
|
+
productSlug: string;
|
|
832
|
+
productName: string;
|
|
833
|
+
deliveryKey: string;
|
|
834
|
+
delivered: boolean;
|
|
835
|
+
deliveryType: DeliveryType;
|
|
836
|
+
revokeCommand: string;
|
|
802
837
|
}
|
|
803
838
|
export interface OrderDisputedData {
|
|
804
839
|
orderId: string;
|
|
@@ -914,6 +949,7 @@ export type SkalpEvent = Envelope<'order.created' | 'order.updated' | 'order.can
|
|
|
914
949
|
}> | Envelope<'subscription.canceled', SubscriptionEventData & {
|
|
915
950
|
endedAt: string | null;
|
|
916
951
|
cancelReason: 'requested' | 'payment_failure' | 'dispute' | 'stripe';
|
|
952
|
+
revokeCommand?: string;
|
|
917
953
|
}> | Envelope<'subscription.refunded', SubscriptionEventData & {
|
|
918
954
|
invoiceId: string;
|
|
919
955
|
amountRefunded: number;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skalpgg/sdk",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Official Skalp SDK for Node.js and edge runtimes: checkout, subscriptions, catalog and key stock, webhooks and license verification.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://skalp.gg/docs/sdk",
|