@drawbridge/drawbridge-utils 0.0.69 → 0.0.71
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/billing.cjs +38 -4
- package/dist/billing.d.cts +71 -10
- package/dist/billing.d.ts +71 -10
- package/dist/billing.js +38 -4
- package/package.json +1 -1
package/dist/billing.cjs
CHANGED
|
@@ -253,26 +253,59 @@ var ai = {
|
|
|
253
253
|
};
|
|
254
254
|
var STANDARD_RATE_PER_GB = 8;
|
|
255
255
|
var PREMIUM_RATE_PER_GB = 11;
|
|
256
|
+
var STANDARD_CPM_CENTS = 0.15;
|
|
257
|
+
var PREMIUM_CPM_CENTS = 0.25;
|
|
256
258
|
var PREMIUM_HOSTS = /* @__PURE__ */ new Set();
|
|
257
259
|
var LOCAL_FLAT_CENTS = 1;
|
|
258
260
|
var REUSE_FLAT_CENTS = 1;
|
|
259
|
-
var
|
|
261
|
+
var isPremium = (url) => {
|
|
260
262
|
try {
|
|
261
|
-
return PREMIUM_HOSTS.has(new URL(url).hostname)
|
|
263
|
+
return PREMIUM_HOSTS.has(new URL(url).hostname);
|
|
262
264
|
} catch {
|
|
263
|
-
return
|
|
265
|
+
return false;
|
|
264
266
|
}
|
|
265
267
|
};
|
|
266
|
-
var
|
|
268
|
+
var ratePerGB = (url) => isPremium(url) ? PREMIUM_RATE_PER_GB : STANDARD_RATE_PER_GB;
|
|
269
|
+
var cpmCents = (url) => isPremium(url) ? PREMIUM_CPM_CENTS : STANDARD_CPM_CENTS;
|
|
270
|
+
var scrapeFee = ({ provider, bytes, requests, url, cold }) => {
|
|
267
271
|
if (!cold) return REUSE_FLAT_CENTS;
|
|
268
272
|
if (provider === "brightdata") {
|
|
269
273
|
return Math.ceil((bytes || 0) / 1e9 * ratePerGB(url) * 100 * MARKUP);
|
|
270
274
|
}
|
|
275
|
+
if (provider === "brightdata-unlocker") {
|
|
276
|
+
return Math.ceil((requests || 0) * cpmCents(url) * MARKUP);
|
|
277
|
+
}
|
|
271
278
|
return LOCAL_FLAT_CENTS;
|
|
272
279
|
};
|
|
280
|
+
var scrapeBreakdown = ({ provider, bytes, requests, url }) => {
|
|
281
|
+
if (provider === "brightdata") {
|
|
282
|
+
return {
|
|
283
|
+
provider,
|
|
284
|
+
basis: "bytes",
|
|
285
|
+
units: bytes || 0,
|
|
286
|
+
rate: ratePerGB(url),
|
|
287
|
+
rateUnit: "GB",
|
|
288
|
+
cents: scrapeFee({ provider, bytes, url, cold: true })
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
if (provider === "brightdata-unlocker") {
|
|
292
|
+
return {
|
|
293
|
+
provider,
|
|
294
|
+
basis: "requests",
|
|
295
|
+
units: requests || 0,
|
|
296
|
+
// cpmCents is cents-per-request; ×10 expresses it as dollars per 1,000.
|
|
297
|
+
rate: cpmCents(url) * 10,
|
|
298
|
+
rateUnit: "1K requests",
|
|
299
|
+
cents: scrapeFee({ provider, requests, url, cold: true })
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
return { provider: provider || "local", basis: "local", units: null, rate: null, rateUnit: null, cents: LOCAL_FLAT_CENTS };
|
|
303
|
+
};
|
|
273
304
|
var scrape = {
|
|
274
305
|
// Cents for a scrape given its provider/bytes/cold basis.
|
|
275
306
|
fee: scrapeFee,
|
|
307
|
+
// Itemized cold-fee breakdown (basis/units/rate/cents) for display + the scrape doc.
|
|
308
|
+
breakdown: scrapeBreakdown,
|
|
276
309
|
// Deferred bill(scrapeId) the scrape store's resolve() hands the generation
|
|
277
310
|
// flow. Atomically claims the cold (first-time) fee via the `charged` flag so
|
|
278
311
|
// a BrightData scrape's metered cost is recovered ONCE; later reuses pay the
|
|
@@ -290,6 +323,7 @@ var scrape = {
|
|
|
290
323
|
const cents = scrapeFee({
|
|
291
324
|
provider: (_a = page == null ? void 0 : page.provider) == null ? void 0 : _a.name,
|
|
292
325
|
bytes: page == null ? void 0 : page.bytes,
|
|
326
|
+
requests: page == null ? void 0 : page.requests,
|
|
293
327
|
url: (page == null ? void 0 : page.url) || url,
|
|
294
328
|
cold: Boolean(claim == null ? void 0 : claim.value)
|
|
295
329
|
});
|
package/dist/billing.d.cts
CHANGED
|
@@ -174,27 +174,39 @@ const ai = {
|
|
|
174
174
|
|
|
175
175
|
// ─── Scrape (credit rail) ──────────────────────────────────────────────────────
|
|
176
176
|
|
|
177
|
-
// BrightData
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
177
|
+
// BrightData has two unblocking tiers, billed on different bases:
|
|
178
|
+
// - Scraping Browser (the CDP fallback): bills by GB of traffic, so its fee is
|
|
179
|
+
// METERED to the bytes measured at scrape time.
|
|
180
|
+
// - Web Unlocker (the last-resort HTML tier): bills per successful request (CPM
|
|
181
|
+
// = per 1,000), so its fee is METERED to the request COUNT the tier made.
|
|
182
|
+
// Both carry the same 30% margin (MARKUP). A cold local render and a cache reuse
|
|
183
|
+
// have no external cost, so they're small flat fees (set to 0 to make either
|
|
184
|
+
// free). Tune the rates against real BrightData invoices.
|
|
181
185
|
const STANDARD_RATE_PER_GB = 8;
|
|
182
186
|
const PREMIUM_RATE_PER_GB = 11;
|
|
187
|
+
// Web Unlocker CPM in cents-per-request: $1.50/1,000 = 0.15¢, $2.50/1,000 = 0.25¢.
|
|
188
|
+
const STANDARD_CPM_CENTS = 0.15;
|
|
189
|
+
const PREMIUM_CPM_CENTS = 0.25;
|
|
190
|
+
// Premium-rate domains — shared by both tiers (empty = everything standard).
|
|
183
191
|
const PREMIUM_HOSTS = new Set();
|
|
184
192
|
const LOCAL_FLAT_CENTS = 1;
|
|
185
193
|
const REUSE_FLAT_CENTS = 1;
|
|
186
194
|
|
|
187
|
-
const
|
|
195
|
+
const isPremium = ( url ) => {
|
|
188
196
|
|
|
189
|
-
try { return PREMIUM_HOSTS.has( new URL( url ).hostname )
|
|
190
|
-
catch { return
|
|
197
|
+
try { return PREMIUM_HOSTS.has( new URL( url ).hostname ); }
|
|
198
|
+
catch { return false; }
|
|
191
199
|
|
|
192
200
|
};
|
|
193
201
|
|
|
202
|
+
const ratePerGB = ( url ) => isPremium( url ) ? PREMIUM_RATE_PER_GB : STANDARD_RATE_PER_GB;
|
|
203
|
+
const cpmCents = ( url ) => isPremium( url ) ? PREMIUM_CPM_CENTS : STANDARD_CPM_CENTS;
|
|
204
|
+
|
|
194
205
|
// Cents to charge. `cold` = the first generation off this scrape (charge the real
|
|
195
|
-
// cost: metered for BrightData, a flat for a local render); otherwise
|
|
196
|
-
// (flat). Rounded up so we never under-bill a fractional cent
|
|
197
|
-
|
|
206
|
+
// cost: metered for either BrightData tier, a flat for a local render); otherwise
|
|
207
|
+
// it's a reuse (flat). Rounded up so we never under-bill a fractional cent — so a
|
|
208
|
+
// typical 1–2 request unlock rounds up to the 1¢ floor.
|
|
209
|
+
const scrapeFee = ({ provider, bytes, requests, url, cold }) => {
|
|
198
210
|
|
|
199
211
|
if( ! cold ) return REUSE_FLAT_CENTS;
|
|
200
212
|
|
|
@@ -204,15 +216,63 @@ const scrapeFee = ({ provider, bytes, url, cold }) => {
|
|
|
204
216
|
|
|
205
217
|
}
|
|
206
218
|
|
|
219
|
+
if( provider === 'brightdata-unlocker' ){
|
|
220
|
+
|
|
221
|
+
return Math.ceil( ( requests || 0 ) * cpmCents( url ) * MARKUP );
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
207
225
|
return LOCAL_FLAT_CENTS;
|
|
208
226
|
|
|
209
227
|
};
|
|
210
228
|
|
|
229
|
+
// Itemized cold-fee breakdown for the scrape doc / admin dashboard: the same cents
|
|
230
|
+
// scrapeFee charges on a COLD scrape, plus the basis, the metered units, and the
|
|
231
|
+
// wholesale provider rate behind it. Reuse hits aren't represented here — the doc
|
|
232
|
+
// records its cold acquisition cost. `rate` is the wholesale rate in dollars per
|
|
233
|
+
// `rateUnit` (pre-markup, i.e. the BrightData list price); `cents` is the retail fee
|
|
234
|
+
// billed (incl MARKUP). Local renders have no external cost — flat, no rate.
|
|
235
|
+
const scrapeBreakdown = ({ provider, bytes, requests, url }) => {
|
|
236
|
+
|
|
237
|
+
if( provider === 'brightdata' ){
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
provider,
|
|
241
|
+
basis : 'bytes',
|
|
242
|
+
units : bytes || 0,
|
|
243
|
+
rate : ratePerGB( url ),
|
|
244
|
+
rateUnit : 'GB',
|
|
245
|
+
cents : scrapeFee({ provider, bytes, url, cold : true })
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if( provider === 'brightdata-unlocker' ){
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
provider,
|
|
254
|
+
basis : 'requests',
|
|
255
|
+
units : requests || 0,
|
|
256
|
+
// cpmCents is cents-per-request; ×10 expresses it as dollars per 1,000.
|
|
257
|
+
rate : cpmCents( url ) * 10,
|
|
258
|
+
rateUnit : '1K requests',
|
|
259
|
+
cents : scrapeFee({ provider, requests, url, cold : true })
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return { provider : provider || 'local', basis : 'local', units : null, rate : null, rateUnit : null, cents : LOCAL_FLAT_CENTS };
|
|
265
|
+
|
|
266
|
+
};
|
|
267
|
+
|
|
211
268
|
const scrape = {
|
|
212
269
|
|
|
213
270
|
// Cents for a scrape given its provider/bytes/cold basis.
|
|
214
271
|
fee : scrapeFee,
|
|
215
272
|
|
|
273
|
+
// Itemized cold-fee breakdown (basis/units/rate/cents) for display + the scrape doc.
|
|
274
|
+
breakdown : scrapeBreakdown,
|
|
275
|
+
|
|
216
276
|
// Deferred bill(scrapeId) the scrape store's resolve() hands the generation
|
|
217
277
|
// flow. Atomically claims the cold (first-time) fee via the `charged` flag so
|
|
218
278
|
// a BrightData scrape's metered cost is recovered ONCE; later reuses pay the
|
|
@@ -233,6 +293,7 @@ const scrape = {
|
|
|
233
293
|
const cents = scrapeFee({
|
|
234
294
|
provider : page?.provider?.name,
|
|
235
295
|
bytes : page?.bytes,
|
|
296
|
+
requests : page?.requests,
|
|
236
297
|
url : page?.url || url,
|
|
237
298
|
cold : Boolean( claim?.value )
|
|
238
299
|
});
|
package/dist/billing.d.ts
CHANGED
|
@@ -174,27 +174,39 @@ const ai = {
|
|
|
174
174
|
|
|
175
175
|
// ─── Scrape (credit rail) ──────────────────────────────────────────────────────
|
|
176
176
|
|
|
177
|
-
// BrightData
|
|
178
|
-
//
|
|
179
|
-
//
|
|
180
|
-
//
|
|
177
|
+
// BrightData has two unblocking tiers, billed on different bases:
|
|
178
|
+
// - Scraping Browser (the CDP fallback): bills by GB of traffic, so its fee is
|
|
179
|
+
// METERED to the bytes measured at scrape time.
|
|
180
|
+
// - Web Unlocker (the last-resort HTML tier): bills per successful request (CPM
|
|
181
|
+
// = per 1,000), so its fee is METERED to the request COUNT the tier made.
|
|
182
|
+
// Both carry the same 30% margin (MARKUP). A cold local render and a cache reuse
|
|
183
|
+
// have no external cost, so they're small flat fees (set to 0 to make either
|
|
184
|
+
// free). Tune the rates against real BrightData invoices.
|
|
181
185
|
const STANDARD_RATE_PER_GB = 8;
|
|
182
186
|
const PREMIUM_RATE_PER_GB = 11;
|
|
187
|
+
// Web Unlocker CPM in cents-per-request: $1.50/1,000 = 0.15¢, $2.50/1,000 = 0.25¢.
|
|
188
|
+
const STANDARD_CPM_CENTS = 0.15;
|
|
189
|
+
const PREMIUM_CPM_CENTS = 0.25;
|
|
190
|
+
// Premium-rate domains — shared by both tiers (empty = everything standard).
|
|
183
191
|
const PREMIUM_HOSTS = new Set();
|
|
184
192
|
const LOCAL_FLAT_CENTS = 1;
|
|
185
193
|
const REUSE_FLAT_CENTS = 1;
|
|
186
194
|
|
|
187
|
-
const
|
|
195
|
+
const isPremium = ( url ) => {
|
|
188
196
|
|
|
189
|
-
try { return PREMIUM_HOSTS.has( new URL( url ).hostname )
|
|
190
|
-
catch { return
|
|
197
|
+
try { return PREMIUM_HOSTS.has( new URL( url ).hostname ); }
|
|
198
|
+
catch { return false; }
|
|
191
199
|
|
|
192
200
|
};
|
|
193
201
|
|
|
202
|
+
const ratePerGB = ( url ) => isPremium( url ) ? PREMIUM_RATE_PER_GB : STANDARD_RATE_PER_GB;
|
|
203
|
+
const cpmCents = ( url ) => isPremium( url ) ? PREMIUM_CPM_CENTS : STANDARD_CPM_CENTS;
|
|
204
|
+
|
|
194
205
|
// Cents to charge. `cold` = the first generation off this scrape (charge the real
|
|
195
|
-
// cost: metered for BrightData, a flat for a local render); otherwise
|
|
196
|
-
// (flat). Rounded up so we never under-bill a fractional cent
|
|
197
|
-
|
|
206
|
+
// cost: metered for either BrightData tier, a flat for a local render); otherwise
|
|
207
|
+
// it's a reuse (flat). Rounded up so we never under-bill a fractional cent — so a
|
|
208
|
+
// typical 1–2 request unlock rounds up to the 1¢ floor.
|
|
209
|
+
const scrapeFee = ({ provider, bytes, requests, url, cold }) => {
|
|
198
210
|
|
|
199
211
|
if( ! cold ) return REUSE_FLAT_CENTS;
|
|
200
212
|
|
|
@@ -204,15 +216,63 @@ const scrapeFee = ({ provider, bytes, url, cold }) => {
|
|
|
204
216
|
|
|
205
217
|
}
|
|
206
218
|
|
|
219
|
+
if( provider === 'brightdata-unlocker' ){
|
|
220
|
+
|
|
221
|
+
return Math.ceil( ( requests || 0 ) * cpmCents( url ) * MARKUP );
|
|
222
|
+
|
|
223
|
+
}
|
|
224
|
+
|
|
207
225
|
return LOCAL_FLAT_CENTS;
|
|
208
226
|
|
|
209
227
|
};
|
|
210
228
|
|
|
229
|
+
// Itemized cold-fee breakdown for the scrape doc / admin dashboard: the same cents
|
|
230
|
+
// scrapeFee charges on a COLD scrape, plus the basis, the metered units, and the
|
|
231
|
+
// wholesale provider rate behind it. Reuse hits aren't represented here — the doc
|
|
232
|
+
// records its cold acquisition cost. `rate` is the wholesale rate in dollars per
|
|
233
|
+
// `rateUnit` (pre-markup, i.e. the BrightData list price); `cents` is the retail fee
|
|
234
|
+
// billed (incl MARKUP). Local renders have no external cost — flat, no rate.
|
|
235
|
+
const scrapeBreakdown = ({ provider, bytes, requests, url }) => {
|
|
236
|
+
|
|
237
|
+
if( provider === 'brightdata' ){
|
|
238
|
+
|
|
239
|
+
return {
|
|
240
|
+
provider,
|
|
241
|
+
basis : 'bytes',
|
|
242
|
+
units : bytes || 0,
|
|
243
|
+
rate : ratePerGB( url ),
|
|
244
|
+
rateUnit : 'GB',
|
|
245
|
+
cents : scrapeFee({ provider, bytes, url, cold : true })
|
|
246
|
+
};
|
|
247
|
+
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
if( provider === 'brightdata-unlocker' ){
|
|
251
|
+
|
|
252
|
+
return {
|
|
253
|
+
provider,
|
|
254
|
+
basis : 'requests',
|
|
255
|
+
units : requests || 0,
|
|
256
|
+
// cpmCents is cents-per-request; ×10 expresses it as dollars per 1,000.
|
|
257
|
+
rate : cpmCents( url ) * 10,
|
|
258
|
+
rateUnit : '1K requests',
|
|
259
|
+
cents : scrapeFee({ provider, requests, url, cold : true })
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return { provider : provider || 'local', basis : 'local', units : null, rate : null, rateUnit : null, cents : LOCAL_FLAT_CENTS };
|
|
265
|
+
|
|
266
|
+
};
|
|
267
|
+
|
|
211
268
|
const scrape = {
|
|
212
269
|
|
|
213
270
|
// Cents for a scrape given its provider/bytes/cold basis.
|
|
214
271
|
fee : scrapeFee,
|
|
215
272
|
|
|
273
|
+
// Itemized cold-fee breakdown (basis/units/rate/cents) for display + the scrape doc.
|
|
274
|
+
breakdown : scrapeBreakdown,
|
|
275
|
+
|
|
216
276
|
// Deferred bill(scrapeId) the scrape store's resolve() hands the generation
|
|
217
277
|
// flow. Atomically claims the cold (first-time) fee via the `charged` flag so
|
|
218
278
|
// a BrightData scrape's metered cost is recovered ONCE; later reuses pay the
|
|
@@ -233,6 +293,7 @@ const scrape = {
|
|
|
233
293
|
const cents = scrapeFee({
|
|
234
294
|
provider : page?.provider?.name,
|
|
235
295
|
bytes : page?.bytes,
|
|
296
|
+
requests : page?.requests,
|
|
236
297
|
url : page?.url || url,
|
|
237
298
|
cold : Boolean( claim?.value )
|
|
238
299
|
});
|
package/dist/billing.js
CHANGED
|
@@ -224,26 +224,59 @@ var ai = {
|
|
|
224
224
|
};
|
|
225
225
|
var STANDARD_RATE_PER_GB = 8;
|
|
226
226
|
var PREMIUM_RATE_PER_GB = 11;
|
|
227
|
+
var STANDARD_CPM_CENTS = 0.15;
|
|
228
|
+
var PREMIUM_CPM_CENTS = 0.25;
|
|
227
229
|
var PREMIUM_HOSTS = /* @__PURE__ */ new Set();
|
|
228
230
|
var LOCAL_FLAT_CENTS = 1;
|
|
229
231
|
var REUSE_FLAT_CENTS = 1;
|
|
230
|
-
var
|
|
232
|
+
var isPremium = (url) => {
|
|
231
233
|
try {
|
|
232
|
-
return PREMIUM_HOSTS.has(new URL(url).hostname)
|
|
234
|
+
return PREMIUM_HOSTS.has(new URL(url).hostname);
|
|
233
235
|
} catch {
|
|
234
|
-
return
|
|
236
|
+
return false;
|
|
235
237
|
}
|
|
236
238
|
};
|
|
237
|
-
var
|
|
239
|
+
var ratePerGB = (url) => isPremium(url) ? PREMIUM_RATE_PER_GB : STANDARD_RATE_PER_GB;
|
|
240
|
+
var cpmCents = (url) => isPremium(url) ? PREMIUM_CPM_CENTS : STANDARD_CPM_CENTS;
|
|
241
|
+
var scrapeFee = ({ provider, bytes, requests, url, cold }) => {
|
|
238
242
|
if (!cold) return REUSE_FLAT_CENTS;
|
|
239
243
|
if (provider === "brightdata") {
|
|
240
244
|
return Math.ceil((bytes || 0) / 1e9 * ratePerGB(url) * 100 * MARKUP);
|
|
241
245
|
}
|
|
246
|
+
if (provider === "brightdata-unlocker") {
|
|
247
|
+
return Math.ceil((requests || 0) * cpmCents(url) * MARKUP);
|
|
248
|
+
}
|
|
242
249
|
return LOCAL_FLAT_CENTS;
|
|
243
250
|
};
|
|
251
|
+
var scrapeBreakdown = ({ provider, bytes, requests, url }) => {
|
|
252
|
+
if (provider === "brightdata") {
|
|
253
|
+
return {
|
|
254
|
+
provider,
|
|
255
|
+
basis: "bytes",
|
|
256
|
+
units: bytes || 0,
|
|
257
|
+
rate: ratePerGB(url),
|
|
258
|
+
rateUnit: "GB",
|
|
259
|
+
cents: scrapeFee({ provider, bytes, url, cold: true })
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
if (provider === "brightdata-unlocker") {
|
|
263
|
+
return {
|
|
264
|
+
provider,
|
|
265
|
+
basis: "requests",
|
|
266
|
+
units: requests || 0,
|
|
267
|
+
// cpmCents is cents-per-request; ×10 expresses it as dollars per 1,000.
|
|
268
|
+
rate: cpmCents(url) * 10,
|
|
269
|
+
rateUnit: "1K requests",
|
|
270
|
+
cents: scrapeFee({ provider, requests, url, cold: true })
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
return { provider: provider || "local", basis: "local", units: null, rate: null, rateUnit: null, cents: LOCAL_FLAT_CENTS };
|
|
274
|
+
};
|
|
244
275
|
var scrape = {
|
|
245
276
|
// Cents for a scrape given its provider/bytes/cold basis.
|
|
246
277
|
fee: scrapeFee,
|
|
278
|
+
// Itemized cold-fee breakdown (basis/units/rate/cents) for display + the scrape doc.
|
|
279
|
+
breakdown: scrapeBreakdown,
|
|
247
280
|
// Deferred bill(scrapeId) the scrape store's resolve() hands the generation
|
|
248
281
|
// flow. Atomically claims the cold (first-time) fee via the `charged` flag so
|
|
249
282
|
// a BrightData scrape's metered cost is recovered ONCE; later reuses pay the
|
|
@@ -261,6 +294,7 @@ var scrape = {
|
|
|
261
294
|
const cents = scrapeFee({
|
|
262
295
|
provider: (_a = page == null ? void 0 : page.provider) == null ? void 0 : _a.name,
|
|
263
296
|
bytes: page == null ? void 0 : page.bytes,
|
|
297
|
+
requests: page == null ? void 0 : page.requests,
|
|
264
298
|
url: (page == null ? void 0 : page.url) || url,
|
|
265
299
|
cold: Boolean(claim == null ? void 0 : claim.value)
|
|
266
300
|
});
|
package/package.json
CHANGED