@buildplease/webkit 1.0.0 → 1.0.2
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 +30 -0
- package/dist/src/index.cjs +1 -1
- package/dist/src/index.d.cts +182 -80
- package/dist/src/index.d.ts +182 -80
- package/dist/src/index.js +1 -1
- package/package.json +2 -3
package/README.md
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# @buildplease/webkit
|
|
2
|
+
|
|
3
|
+
WebKit is the BuildPlease application kit for browser applications. It builds on Core and provides shared web application architecture and runtime primitives without depending on a specific frontend framework.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pnpm add @buildplease/webkit
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { webkitAssembly } from '@buildplease/webkit';
|
|
15
|
+
|
|
16
|
+
const assemblies = webkitAssembly();
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Features
|
|
20
|
+
|
|
21
|
+
- browser application architecture and dependency injection
|
|
22
|
+
- asynchronous operations and remote resources
|
|
23
|
+
- transport-independent HTTP primitives
|
|
24
|
+
- request interception and error handling
|
|
25
|
+
- shared web models and utilities
|
|
26
|
+
- L10n integration
|
|
27
|
+
|
|
28
|
+
## License
|
|
29
|
+
|
|
30
|
+
MIT
|
package/dist/src/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`}),require("reflect-metadata");let e=require("@buildplease/core"),t=require("inversify");function n(){return[]}`${{name:`buildplease`,displayName:`BuildPlease`,scope:`@buildplease`}.name}`;const r={DI:{}},i=e.CoreL10nResource;var a=class{mode;pendingEntries=[];activeEntries=new Set;interruption;isSerialOperationRunning=!1;constructor(e=`parallel`){this.mode=e}execute(t){if(this.interruption)return Promise.reject(new e.CanceledError);let n=this.createEntry(t);return this.mode===`serial`?(this.pendingEntries.push(n),this.startNextSerialOperation()):this.startEntry(n),n.promise}cancelAll(e){let t=this.pendingEntries.splice(0);for(let n of t)this.cancelEntry(n,e);for(let t of this.activeEntries)this.cancelEntry(t,e)}async interrupt(e){if(!this.interruption){let t=Promise.resolve().then(e).finally(()=>{this.interruption===t&&(this.interruption=void 0,this.startNextSerialOperation())});this.interruption=t,this.cancelAll()}await this.interruption}createEntry(e){let t,n;return{operation:e,promise:new Promise((e,r)=>{t=e,n=r}),resolve:e=>t?.(e),reject:e=>n?.(e),canceled:!1,settled:!1}}startEntry(e){if(e.canceled||this.interruption){this.cancelEntry(e);return}this.activeEntries.add(e),this.mode===`serial`&&(this.isSerialOperationRunning=!0),Promise.resolve().then(e.operation).then(t=>{e.canceled||this.resolveEntry(e,t)},t=>{e.canceled||this.rejectEntry(e,t)}).finally(()=>{this.activeEntries.delete(e),this.mode===`serial`&&(this.isSerialOperationRunning=!1,this.startNextSerialOperation())})}startNextSerialOperation(){if(this.mode!==`serial`||this.isSerialOperationRunning||this.interruption)return;let e=this.pendingEntries.shift();e&&this.startEntry(e)}cancelEntry(t,n){t.canceled||(t.canceled=!0,t.settled||this.rejectEntry(t,new e.CanceledError({cause:n})))}resolveEntry(e,t){e.settled||(e.settled=!0,e.resolve(t))}rejectEntry(e,t){e.settled||(e.settled=!0,e.reject(t))}},o=class extends Error{statusCode;code;details;constructor(e){super(e.message),this.name=`HttpError`,this.statusCode=e.statusCode,this.code=e.code,this.details=e.details,e.cause!==void 0&&(this.cause=e.cause)}},s=class{interceptors;constructor(e=[],t){this.interceptors=this.resolveInterceptors(e,t)}async intercept(e){let t=e;for(let e of this.interceptors)t=await e.intercept(t);return t}resolveInterceptors(e,t){let n=new Set,r=[];for(let i of e){if(n.has(i.identity)){t?.(`Duplicate HTTP request interceptor ignored: ${String(i.identity)}`);continue}n.add(i.identity),r.push(i)}return Object.freeze(r)}};const c={credentials:!0,headers:{}};var l=class{requestOptions;interceptorPipeline;asyncQueue;unauthorized;constructor(e={}){this.requestOptions=e.requestOptions??{},this.interceptorPipeline=e.interceptorPipeline??new s,this.asyncQueue=e.asyncQueue??new a,this.unauthorized=e.unauthorized}execute(e,t){return this.asyncQueue.execute(async()=>{let n=await this.makeRequestOptions(e,t);try{let t=this.createClient(n);return await e.execute(t)}catch(e){throw this.handleError(e)}})}handleError(t){return t instanceof o||t instanceof e.NetworkError||t instanceof e.TimeoutError||t instanceof e.CanceledError||t instanceof e.UnknownError?t:new e.UnknownError({message:t instanceof Error?t.message:void 0,cause:t})}async makeRequestOptions(e,t){let n=this.mergeRequestOptions(c,this.requestOptions);return n=await this.interceptorPipeline.intercept(n),n=this.mergeRequestOptions(n,e.options),n=this.mergeRequestOptions(n,t),n}mergeRequestOptions(e,t){return t?{credentials:t.credentials??e.credentials,headers:{...e.headers,...t.headers}}:e}};function u(e,t){if(typeof Reflect==`object`&&typeof Reflect.metadata==`function`)return Reflect.metadata(e,t)}function d(e,t){return function(n,r){t(n,r,e)}}function f(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}let p=class{endpoint;httpClient;constructor(e,t){this.endpoint=e,this.httpClient=t}async execute(e,t){let n=await this.convertOrThrow(()=>this.endpoint.convertInput(e)),r=this.endpoint.makeRequest(n),i=await this.httpClient.execute(r,t);return await this.convertOrThrow(()=>this.endpoint.convertOutput(i))}async convertOrThrow(t){try{return await t()}catch(t){throw new e.ConversionError({cause:t})}}};p=f([(0,t.injectable)(),d(0,(0,t.unmanaged)()),d(1,(0,t.unmanaged)()),u(`design:paramtypes`,[Object,Object])],p);let m=class extends p{constructor(e,t){super(e,t)}};m=f([(0,t.injectable)(),u(`design:paramtypes`,[Object,Object])],m);let h=class extends p{constructor(e,t){super(e,t)}async execute(t,n){try{return await super.execute(t,n)}catch(t){if(!(t instanceof o))throw t;let n=this.httpClient.unauthorized;throw!n||!n.statusCodes.includes(t.statusCode)?t:n.cancelAll?(await this.httpClient.asyncQueue.interrupt(()=>n.handler.handle(t)),new e.CanceledError({cause:t})):(await n.handler.handle(t),t)}}};h=f([(0,t.injectable)(),u(`design:paramtypes`,[Object,Object])],h);function g(){let t=(0,e.coreAssembly)(),r=n();return[...t,...r]}exports.AsyncQueueImpl=a,exports.HttpClient=l,exports.HttpError=o,exports.HttpRequestInterceptorPipeline=s,Object.defineProperty(exports,"PublicRemoteResource",{enumerable:!0,get:function(){return m}}),Object.defineProperty(exports,"RemoteResource",{enumerable:!0,get:function(){return p}}),Object.defineProperty(exports,"SecuredRemoteResource",{enumerable:!0,get:function(){return h}}),exports.WebKitL10nResource=i,exports.WebKitSymbols=r,exports.webkitAssembly=g,Object.keys(e).forEach(function(t){t!=="default"&&!Object.prototype.hasOwnProperty.call(exports,t)&&Object.defineProperty(exports,t,{enumerable:!0,get:function(){return e[t]}})});
|
package/dist/src/index.d.cts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
|
-
import { Assembly, AsyncOperation,
|
|
3
|
-
import { AxiosRequestConfig } from "axios";
|
|
2
|
+
import { Assembly, AsyncOperation, Identity } from "@buildplease/core";
|
|
4
3
|
export * from "@buildplease/core";
|
|
5
4
|
//#region src/di/symbols.d.ts
|
|
6
5
|
declare const WebKitSymbols: {
|
|
@@ -308,62 +307,123 @@ interface TablePaginationModel {
|
|
|
308
307
|
pageSizeOptions?: number[];
|
|
309
308
|
}
|
|
310
309
|
//#endregion
|
|
311
|
-
//#region src/networking/
|
|
312
|
-
|
|
310
|
+
//#region src/networking/async-queue.d.ts
|
|
311
|
+
/**
|
|
312
|
+
* Defines how queued operations are processed.
|
|
313
|
+
*
|
|
314
|
+
* `parallel` starts each operation immediately without waiting for previous operations to finish.
|
|
315
|
+
* `serial` starts an operation only after the previous operation has finished.
|
|
316
|
+
*/
|
|
317
|
+
type AsyncQueueMode = 'parallel' | 'serial';
|
|
318
|
+
/**
|
|
319
|
+
* Executes and coordinates asynchronous operations.
|
|
320
|
+
*/
|
|
321
|
+
interface AsyncQueue {
|
|
322
|
+
/**
|
|
323
|
+
* Executes an operation according to the configured queue mode.
|
|
324
|
+
* Operations submitted during an interruption are canceled without running.
|
|
325
|
+
*/
|
|
326
|
+
execute<Output>(operation: () => Promise<Output>): Promise<Output>;
|
|
327
|
+
/**
|
|
328
|
+
* Cancels all unresolved operations. Pending serial operations are not started and results from
|
|
329
|
+
* already-running operations are ignored.
|
|
330
|
+
*
|
|
331
|
+
* @param cause Optional cancellation cause.
|
|
332
|
+
*/
|
|
333
|
+
cancelAll(cause?: unknown): void;
|
|
334
|
+
/**
|
|
335
|
+
* Cancels all unresolved operations and executes one interruption handler.
|
|
336
|
+
* Concurrent interruptions wait for the same handler to complete.
|
|
337
|
+
*/
|
|
338
|
+
interrupt(handler: () => Promise<void>): Promise<void>;
|
|
339
|
+
}
|
|
340
|
+
declare class AsyncQueueImpl implements AsyncQueue {
|
|
341
|
+
private readonly mode;
|
|
342
|
+
private readonly pendingEntries;
|
|
343
|
+
private readonly activeEntries;
|
|
344
|
+
private interruption?;
|
|
345
|
+
private isSerialOperationRunning;
|
|
346
|
+
constructor(mode?: AsyncQueueMode);
|
|
347
|
+
execute<Output>(operation: () => Promise<Output>): Promise<Output>;
|
|
348
|
+
cancelAll(cause?: unknown): void;
|
|
349
|
+
interrupt(handler: () => Promise<void>): Promise<void>;
|
|
350
|
+
private createEntry;
|
|
351
|
+
private startEntry;
|
|
352
|
+
private startNextSerialOperation;
|
|
353
|
+
private cancelEntry;
|
|
354
|
+
private resolveEntry;
|
|
355
|
+
private rejectEntry;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/networking/http-request-options.d.ts
|
|
359
|
+
interface HttpRequestOptions {
|
|
313
360
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
361
|
+
* Whether browser credentials such as cookies should be included with the request,
|
|
362
|
+
* including cross-origin requests.
|
|
363
|
+
*
|
|
364
|
+
* @default true
|
|
317
365
|
*/
|
|
318
|
-
|
|
366
|
+
readonly credentials?: boolean;
|
|
319
367
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* @
|
|
368
|
+
* Headers included with the request.
|
|
369
|
+
*
|
|
370
|
+
* @default {}
|
|
323
371
|
*/
|
|
324
|
-
|
|
372
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/networking/http-request.d.ts
|
|
376
|
+
interface HttpRequest<Client, Output> {
|
|
325
377
|
/**
|
|
326
|
-
*
|
|
327
|
-
* @example "Authentication required"
|
|
328
|
-
* @example "User profile not found"
|
|
378
|
+
* Executes the request using the configured client.
|
|
329
379
|
*/
|
|
330
|
-
|
|
380
|
+
readonly execute: (client: Client) => Promise<Output>;
|
|
331
381
|
/**
|
|
332
|
-
*
|
|
333
|
-
* Each key maps to an array of error messages for that field.
|
|
382
|
+
* Options applied specifically to this request.
|
|
334
383
|
*
|
|
335
|
-
* @
|
|
336
|
-
* {
|
|
337
|
-
* "email": ["must be a valid email address"],
|
|
338
|
-
* "password": ["required", "must be at least 8 characters"]
|
|
339
|
-
* }
|
|
384
|
+
* @default undefined
|
|
340
385
|
*/
|
|
341
|
-
|
|
386
|
+
readonly options?: HttpRequestOptions;
|
|
342
387
|
}
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/networking/http-request-interceptor.d.ts
|
|
343
390
|
/**
|
|
344
|
-
*
|
|
345
|
-
* human‐readable message, and optional debug details.
|
|
346
|
-
*
|
|
347
|
-
* @example
|
|
348
|
-
* // Basic usage
|
|
349
|
-
* throw new HttpError({
|
|
350
|
-
* statusCode: 404,
|
|
351
|
-
* code: "NOT_FOUND",
|
|
352
|
-
* message: "Resource not found"
|
|
353
|
-
* });
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* // With structured debug details
|
|
357
|
-
* throw new HttpError({
|
|
358
|
-
* statusCode: 422,
|
|
359
|
-
* code: "VALIDATION_ERROR",
|
|
360
|
-
* message: "One or more fields are invalid",
|
|
361
|
-
* details: {
|
|
362
|
-
* "email": ["must be a valid email address"],
|
|
363
|
-
* "password": ["required", "must be at least 8 characters"]
|
|
364
|
-
* }
|
|
365
|
-
* });
|
|
391
|
+
* Modifies HTTP request options before a request is executed.
|
|
366
392
|
*/
|
|
393
|
+
interface HttpRequestInterceptor {
|
|
394
|
+
/** Stable identity used to ignore duplicate interceptors. */
|
|
395
|
+
readonly identity: Identity;
|
|
396
|
+
/** Applies this interceptor to the current request options. */
|
|
397
|
+
intercept(options: HttpRequestOptions): HttpRequestOptions | Promise<HttpRequestOptions>;
|
|
398
|
+
}
|
|
399
|
+
declare class HttpRequestInterceptorPipeline {
|
|
400
|
+
private readonly interceptors;
|
|
401
|
+
constructor(interceptors?: readonly HttpRequestInterceptor[], onWarning?: (message: string) => void);
|
|
402
|
+
intercept(options: HttpRequestOptions): Promise<HttpRequestOptions>;
|
|
403
|
+
private resolveInterceptors;
|
|
404
|
+
}
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/networking/http-error.d.ts
|
|
407
|
+
interface HttpErrorOptions {
|
|
408
|
+
/** HTTP status code returned by the remote system. */
|
|
409
|
+
readonly statusCode: number;
|
|
410
|
+
/** Machine-readable error code for programmatic handling. */
|
|
411
|
+
readonly code: string;
|
|
412
|
+
/** Human-readable error description. */
|
|
413
|
+
readonly message: string;
|
|
414
|
+
/**
|
|
415
|
+
* Structured error details.
|
|
416
|
+
*
|
|
417
|
+
* @default undefined
|
|
418
|
+
*/
|
|
419
|
+
readonly details?: Readonly<Record<string, string[]>>;
|
|
420
|
+
/**
|
|
421
|
+
* Original transport error.
|
|
422
|
+
*
|
|
423
|
+
* @default undefined
|
|
424
|
+
*/
|
|
425
|
+
readonly cause?: unknown;
|
|
426
|
+
}
|
|
367
427
|
declare class HttpError extends Error {
|
|
368
428
|
readonly statusCode: HttpErrorOptions['statusCode'];
|
|
369
429
|
readonly code: HttpErrorOptions['code'];
|
|
@@ -371,53 +431,95 @@ declare class HttpError extends Error {
|
|
|
371
431
|
constructor(options: HttpErrorOptions);
|
|
372
432
|
}
|
|
373
433
|
//#endregion
|
|
374
|
-
//#region src/networking/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
434
|
+
//#region src/networking/unauthorized.d.ts
|
|
435
|
+
interface UnauthorizedHandler {
|
|
436
|
+
handle(error: HttpError): Promise<void>;
|
|
437
|
+
}
|
|
438
|
+
interface UnauthorizedOptions {
|
|
439
|
+
/** HTTP status codes that trigger unauthorized handling. */
|
|
440
|
+
readonly statusCodes: readonly number[];
|
|
441
|
+
/** Whether unauthorized handling cancels all unresolved requests sharing the same HTTP client. */
|
|
442
|
+
readonly cancelAll: boolean;
|
|
443
|
+
/** Application-specific unauthorized handler. */
|
|
444
|
+
readonly handler: UnauthorizedHandler;
|
|
445
|
+
}
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region src/networking/http-client.d.ts
|
|
448
|
+
interface HttpClientOptions {
|
|
449
|
+
/**
|
|
450
|
+
* Default options applied to every request before interceptors and request-specific options.
|
|
451
|
+
*
|
|
452
|
+
* @default {}
|
|
453
|
+
*/
|
|
454
|
+
readonly requestOptions?: HttpRequestOptions;
|
|
455
|
+
/**
|
|
456
|
+
* Interceptors applied to every request.
|
|
457
|
+
*
|
|
458
|
+
* @default Empty `HttpRequestInterceptorPipeline`
|
|
459
|
+
*/
|
|
460
|
+
readonly interceptorPipeline?: HttpRequestInterceptorPipeline;
|
|
461
|
+
/**
|
|
462
|
+
* Queue used to execute requests.
|
|
463
|
+
*
|
|
464
|
+
* @default `AsyncQueueImpl` in `parallel` mode
|
|
465
|
+
*/
|
|
466
|
+
readonly asyncQueue?: AsyncQueue;
|
|
467
|
+
/**
|
|
468
|
+
* Unauthorized handling for secured requests.
|
|
469
|
+
*
|
|
470
|
+
* @default undefined
|
|
471
|
+
*/
|
|
472
|
+
readonly unauthorized?: UnauthorizedOptions;
|
|
473
|
+
}
|
|
474
|
+
declare abstract class HttpClient<Client> {
|
|
475
|
+
private readonly requestOptions;
|
|
476
|
+
private readonly interceptorPipeline;
|
|
477
|
+
readonly asyncQueue: AsyncQueue;
|
|
478
|
+
readonly unauthorized?: UnauthorizedOptions;
|
|
479
|
+
constructor(options?: HttpClientOptions);
|
|
480
|
+
execute<Output>(request: HttpRequest<Client, Output>, options?: HttpRequestOptions): Promise<Output>;
|
|
481
|
+
/** Creates the concrete client for the resolved request options. */
|
|
482
|
+
protected abstract createClient(options: HttpRequestOptions): Client;
|
|
483
|
+
/** Maps a transport-specific failure to a BuildPlease error. */
|
|
484
|
+
protected handleError(error: unknown): Error;
|
|
485
|
+
private makeRequestOptions;
|
|
486
|
+
private mergeRequestOptions;
|
|
380
487
|
}
|
|
381
488
|
//#endregion
|
|
382
489
|
//#region src/networking/remote-endpoint.d.ts
|
|
383
|
-
|
|
384
|
-
|
|
490
|
+
/**
|
|
491
|
+
* Defines conversion and request creation for a remote operation.
|
|
492
|
+
*/
|
|
493
|
+
interface RemoteEndpoint<Input, InputDto, Output, OutputDto, Client> {
|
|
494
|
+
/** Converts operation input to the request DTO. */
|
|
385
495
|
convertInput(input: Input): Promise<InputDto>;
|
|
496
|
+
/** Creates the HTTP request for the converted input. */
|
|
497
|
+
makeRequest(input: InputDto): HttpRequest<Client, OutputDto>;
|
|
498
|
+
/** Converts the response DTO to the operation output. */
|
|
386
499
|
convertOutput(response: OutputDto): Promise<Output>;
|
|
387
500
|
}
|
|
388
501
|
//#endregion
|
|
389
502
|
//#region src/networking/remote-resource.d.ts
|
|
390
|
-
declare abstract class
|
|
391
|
-
protected readonly endpoint:
|
|
392
|
-
protected readonly
|
|
393
|
-
constructor(endpoint:
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
protected clearInterceptors(): this;
|
|
397
|
-
execute(input: Input, options?: RemoteRequestConfig): Promise<Output>;
|
|
398
|
-
protected parseError(error: unknown): Error;
|
|
399
|
-
protected convertOrThrow<T>(fn: () => Promise<T>): Promise<T>;
|
|
400
|
-
private isStringArrayRecord;
|
|
401
|
-
private buildHttpErrorOptions;
|
|
503
|
+
declare abstract class RemoteResource<Input, Output, Client> implements AsyncOperation<Input, Output, HttpRequestOptions> {
|
|
504
|
+
protected readonly endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>;
|
|
505
|
+
protected readonly httpClient: HttpClient<Client>;
|
|
506
|
+
protected constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
507
|
+
execute(input: Input, options?: HttpRequestOptions): Promise<Output>;
|
|
508
|
+
private convertOrThrow;
|
|
402
509
|
}
|
|
403
510
|
//#endregion
|
|
404
|
-
//#region src/networking/remote-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
//#region src/networking/remote-request-interceptor.d.ts
|
|
408
|
-
interface RemoteRequestInterceptor extends Equatable, Hashable {
|
|
409
|
-
order: number;
|
|
410
|
-
intercept(config: RemoteRequestConfig): RemoteRequestConfig;
|
|
511
|
+
//#region src/networking/public-remote-resource.d.ts
|
|
512
|
+
declare class PublicRemoteResource<Input, Output, Client> extends RemoteResource<Input, Output, Client> {
|
|
513
|
+
constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
411
514
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
list(): RemoteRequestInterceptor[];
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region src/networking/secured-remote-resource.d.ts
|
|
517
|
+
declare class SecuredRemoteResource<Input, Output, Client> extends RemoteResource<Input, Output, Client> {
|
|
518
|
+
constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
519
|
+
execute(input: Input, options?: HttpRequestOptions): Promise<Output>;
|
|
418
520
|
}
|
|
419
521
|
//#endregion
|
|
420
522
|
//#region src/index.d.ts
|
|
421
523
|
declare function webkitAssembly(): Assembly[];
|
|
422
524
|
//#endregion
|
|
423
|
-
export {
|
|
525
|
+
export { AsyncQueue, AsyncQueueImpl, AsyncQueueMode, HttpClient, HttpClientOptions, HttpError, HttpErrorOptions, HttpRequest, HttpRequestInterceptor, HttpRequestInterceptorPipeline, HttpRequestOptions, PublicRemoteResource, RemoteEndpoint, RemoteResource, SecuredRemoteResource, TableDataModel, TablePaginationModel, UnauthorizedHandler, UnauthorizedOptions, WebKitL10nResource, WebKitSymbols, webkitAssembly };
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import "reflect-metadata";
|
|
2
|
-
import { Assembly, AsyncOperation,
|
|
3
|
-
import { AxiosRequestConfig } from "axios";
|
|
2
|
+
import { Assembly, AsyncOperation, Identity } from "@buildplease/core";
|
|
4
3
|
export * from "@buildplease/core";
|
|
5
4
|
//#region src/di/symbols.d.ts
|
|
6
5
|
declare const WebKitSymbols: {
|
|
@@ -308,62 +307,123 @@ interface TablePaginationModel {
|
|
|
308
307
|
pageSizeOptions?: number[];
|
|
309
308
|
}
|
|
310
309
|
//#endregion
|
|
311
|
-
//#region src/networking/
|
|
312
|
-
|
|
310
|
+
//#region src/networking/async-queue.d.ts
|
|
311
|
+
/**
|
|
312
|
+
* Defines how queued operations are processed.
|
|
313
|
+
*
|
|
314
|
+
* `parallel` starts each operation immediately without waiting for previous operations to finish.
|
|
315
|
+
* `serial` starts an operation only after the previous operation has finished.
|
|
316
|
+
*/
|
|
317
|
+
type AsyncQueueMode = 'parallel' | 'serial';
|
|
318
|
+
/**
|
|
319
|
+
* Executes and coordinates asynchronous operations.
|
|
320
|
+
*/
|
|
321
|
+
interface AsyncQueue {
|
|
322
|
+
/**
|
|
323
|
+
* Executes an operation according to the configured queue mode.
|
|
324
|
+
* Operations submitted during an interruption are canceled without running.
|
|
325
|
+
*/
|
|
326
|
+
execute<Output>(operation: () => Promise<Output>): Promise<Output>;
|
|
327
|
+
/**
|
|
328
|
+
* Cancels all unresolved operations. Pending serial operations are not started and results from
|
|
329
|
+
* already-running operations are ignored.
|
|
330
|
+
*
|
|
331
|
+
* @param cause Optional cancellation cause.
|
|
332
|
+
*/
|
|
333
|
+
cancelAll(cause?: unknown): void;
|
|
334
|
+
/**
|
|
335
|
+
* Cancels all unresolved operations and executes one interruption handler.
|
|
336
|
+
* Concurrent interruptions wait for the same handler to complete.
|
|
337
|
+
*/
|
|
338
|
+
interrupt(handler: () => Promise<void>): Promise<void>;
|
|
339
|
+
}
|
|
340
|
+
declare class AsyncQueueImpl implements AsyncQueue {
|
|
341
|
+
private readonly mode;
|
|
342
|
+
private readonly pendingEntries;
|
|
343
|
+
private readonly activeEntries;
|
|
344
|
+
private interruption?;
|
|
345
|
+
private isSerialOperationRunning;
|
|
346
|
+
constructor(mode?: AsyncQueueMode);
|
|
347
|
+
execute<Output>(operation: () => Promise<Output>): Promise<Output>;
|
|
348
|
+
cancelAll(cause?: unknown): void;
|
|
349
|
+
interrupt(handler: () => Promise<void>): Promise<void>;
|
|
350
|
+
private createEntry;
|
|
351
|
+
private startEntry;
|
|
352
|
+
private startNextSerialOperation;
|
|
353
|
+
private cancelEntry;
|
|
354
|
+
private resolveEntry;
|
|
355
|
+
private rejectEntry;
|
|
356
|
+
}
|
|
357
|
+
//#endregion
|
|
358
|
+
//#region src/networking/http-request-options.d.ts
|
|
359
|
+
interface HttpRequestOptions {
|
|
313
360
|
/**
|
|
314
|
-
*
|
|
315
|
-
*
|
|
316
|
-
*
|
|
361
|
+
* Whether browser credentials such as cookies should be included with the request,
|
|
362
|
+
* including cross-origin requests.
|
|
363
|
+
*
|
|
364
|
+
* @default true
|
|
317
365
|
*/
|
|
318
|
-
|
|
366
|
+
readonly credentials?: boolean;
|
|
319
367
|
/**
|
|
320
|
-
*
|
|
321
|
-
*
|
|
322
|
-
* @
|
|
368
|
+
* Headers included with the request.
|
|
369
|
+
*
|
|
370
|
+
* @default {}
|
|
323
371
|
*/
|
|
324
|
-
|
|
372
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
373
|
+
}
|
|
374
|
+
//#endregion
|
|
375
|
+
//#region src/networking/http-request.d.ts
|
|
376
|
+
interface HttpRequest<Client, Output> {
|
|
325
377
|
/**
|
|
326
|
-
*
|
|
327
|
-
* @example "Authentication required"
|
|
328
|
-
* @example "User profile not found"
|
|
378
|
+
* Executes the request using the configured client.
|
|
329
379
|
*/
|
|
330
|
-
|
|
380
|
+
readonly execute: (client: Client) => Promise<Output>;
|
|
331
381
|
/**
|
|
332
|
-
*
|
|
333
|
-
* Each key maps to an array of error messages for that field.
|
|
382
|
+
* Options applied specifically to this request.
|
|
334
383
|
*
|
|
335
|
-
* @
|
|
336
|
-
* {
|
|
337
|
-
* "email": ["must be a valid email address"],
|
|
338
|
-
* "password": ["required", "must be at least 8 characters"]
|
|
339
|
-
* }
|
|
384
|
+
* @default undefined
|
|
340
385
|
*/
|
|
341
|
-
|
|
386
|
+
readonly options?: HttpRequestOptions;
|
|
342
387
|
}
|
|
388
|
+
//#endregion
|
|
389
|
+
//#region src/networking/http-request-interceptor.d.ts
|
|
343
390
|
/**
|
|
344
|
-
*
|
|
345
|
-
* human‐readable message, and optional debug details.
|
|
346
|
-
*
|
|
347
|
-
* @example
|
|
348
|
-
* // Basic usage
|
|
349
|
-
* throw new HttpError({
|
|
350
|
-
* statusCode: 404,
|
|
351
|
-
* code: "NOT_FOUND",
|
|
352
|
-
* message: "Resource not found"
|
|
353
|
-
* });
|
|
354
|
-
*
|
|
355
|
-
* @example
|
|
356
|
-
* // With structured debug details
|
|
357
|
-
* throw new HttpError({
|
|
358
|
-
* statusCode: 422,
|
|
359
|
-
* code: "VALIDATION_ERROR",
|
|
360
|
-
* message: "One or more fields are invalid",
|
|
361
|
-
* details: {
|
|
362
|
-
* "email": ["must be a valid email address"],
|
|
363
|
-
* "password": ["required", "must be at least 8 characters"]
|
|
364
|
-
* }
|
|
365
|
-
* });
|
|
391
|
+
* Modifies HTTP request options before a request is executed.
|
|
366
392
|
*/
|
|
393
|
+
interface HttpRequestInterceptor {
|
|
394
|
+
/** Stable identity used to ignore duplicate interceptors. */
|
|
395
|
+
readonly identity: Identity;
|
|
396
|
+
/** Applies this interceptor to the current request options. */
|
|
397
|
+
intercept(options: HttpRequestOptions): HttpRequestOptions | Promise<HttpRequestOptions>;
|
|
398
|
+
}
|
|
399
|
+
declare class HttpRequestInterceptorPipeline {
|
|
400
|
+
private readonly interceptors;
|
|
401
|
+
constructor(interceptors?: readonly HttpRequestInterceptor[], onWarning?: (message: string) => void);
|
|
402
|
+
intercept(options: HttpRequestOptions): Promise<HttpRequestOptions>;
|
|
403
|
+
private resolveInterceptors;
|
|
404
|
+
}
|
|
405
|
+
//#endregion
|
|
406
|
+
//#region src/networking/http-error.d.ts
|
|
407
|
+
interface HttpErrorOptions {
|
|
408
|
+
/** HTTP status code returned by the remote system. */
|
|
409
|
+
readonly statusCode: number;
|
|
410
|
+
/** Machine-readable error code for programmatic handling. */
|
|
411
|
+
readonly code: string;
|
|
412
|
+
/** Human-readable error description. */
|
|
413
|
+
readonly message: string;
|
|
414
|
+
/**
|
|
415
|
+
* Structured error details.
|
|
416
|
+
*
|
|
417
|
+
* @default undefined
|
|
418
|
+
*/
|
|
419
|
+
readonly details?: Readonly<Record<string, string[]>>;
|
|
420
|
+
/**
|
|
421
|
+
* Original transport error.
|
|
422
|
+
*
|
|
423
|
+
* @default undefined
|
|
424
|
+
*/
|
|
425
|
+
readonly cause?: unknown;
|
|
426
|
+
}
|
|
367
427
|
declare class HttpError extends Error {
|
|
368
428
|
readonly statusCode: HttpErrorOptions['statusCode'];
|
|
369
429
|
readonly code: HttpErrorOptions['code'];
|
|
@@ -371,53 +431,95 @@ declare class HttpError extends Error {
|
|
|
371
431
|
constructor(options: HttpErrorOptions);
|
|
372
432
|
}
|
|
373
433
|
//#endregion
|
|
374
|
-
//#region src/networking/
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
434
|
+
//#region src/networking/unauthorized.d.ts
|
|
435
|
+
interface UnauthorizedHandler {
|
|
436
|
+
handle(error: HttpError): Promise<void>;
|
|
437
|
+
}
|
|
438
|
+
interface UnauthorizedOptions {
|
|
439
|
+
/** HTTP status codes that trigger unauthorized handling. */
|
|
440
|
+
readonly statusCodes: readonly number[];
|
|
441
|
+
/** Whether unauthorized handling cancels all unresolved requests sharing the same HTTP client. */
|
|
442
|
+
readonly cancelAll: boolean;
|
|
443
|
+
/** Application-specific unauthorized handler. */
|
|
444
|
+
readonly handler: UnauthorizedHandler;
|
|
445
|
+
}
|
|
446
|
+
//#endregion
|
|
447
|
+
//#region src/networking/http-client.d.ts
|
|
448
|
+
interface HttpClientOptions {
|
|
449
|
+
/**
|
|
450
|
+
* Default options applied to every request before interceptors and request-specific options.
|
|
451
|
+
*
|
|
452
|
+
* @default {}
|
|
453
|
+
*/
|
|
454
|
+
readonly requestOptions?: HttpRequestOptions;
|
|
455
|
+
/**
|
|
456
|
+
* Interceptors applied to every request.
|
|
457
|
+
*
|
|
458
|
+
* @default Empty `HttpRequestInterceptorPipeline`
|
|
459
|
+
*/
|
|
460
|
+
readonly interceptorPipeline?: HttpRequestInterceptorPipeline;
|
|
461
|
+
/**
|
|
462
|
+
* Queue used to execute requests.
|
|
463
|
+
*
|
|
464
|
+
* @default `AsyncQueueImpl` in `parallel` mode
|
|
465
|
+
*/
|
|
466
|
+
readonly asyncQueue?: AsyncQueue;
|
|
467
|
+
/**
|
|
468
|
+
* Unauthorized handling for secured requests.
|
|
469
|
+
*
|
|
470
|
+
* @default undefined
|
|
471
|
+
*/
|
|
472
|
+
readonly unauthorized?: UnauthorizedOptions;
|
|
473
|
+
}
|
|
474
|
+
declare abstract class HttpClient<Client> {
|
|
475
|
+
private readonly requestOptions;
|
|
476
|
+
private readonly interceptorPipeline;
|
|
477
|
+
readonly asyncQueue: AsyncQueue;
|
|
478
|
+
readonly unauthorized?: UnauthorizedOptions;
|
|
479
|
+
constructor(options?: HttpClientOptions);
|
|
480
|
+
execute<Output>(request: HttpRequest<Client, Output>, options?: HttpRequestOptions): Promise<Output>;
|
|
481
|
+
/** Creates the concrete client for the resolved request options. */
|
|
482
|
+
protected abstract createClient(options: HttpRequestOptions): Client;
|
|
483
|
+
/** Maps a transport-specific failure to a BuildPlease error. */
|
|
484
|
+
protected handleError(error: unknown): Error;
|
|
485
|
+
private makeRequestOptions;
|
|
486
|
+
private mergeRequestOptions;
|
|
380
487
|
}
|
|
381
488
|
//#endregion
|
|
382
489
|
//#region src/networking/remote-endpoint.d.ts
|
|
383
|
-
|
|
384
|
-
|
|
490
|
+
/**
|
|
491
|
+
* Defines conversion and request creation for a remote operation.
|
|
492
|
+
*/
|
|
493
|
+
interface RemoteEndpoint<Input, InputDto, Output, OutputDto, Client> {
|
|
494
|
+
/** Converts operation input to the request DTO. */
|
|
385
495
|
convertInput(input: Input): Promise<InputDto>;
|
|
496
|
+
/** Creates the HTTP request for the converted input. */
|
|
497
|
+
makeRequest(input: InputDto): HttpRequest<Client, OutputDto>;
|
|
498
|
+
/** Converts the response DTO to the operation output. */
|
|
386
499
|
convertOutput(response: OutputDto): Promise<Output>;
|
|
387
500
|
}
|
|
388
501
|
//#endregion
|
|
389
502
|
//#region src/networking/remote-resource.d.ts
|
|
390
|
-
declare abstract class
|
|
391
|
-
protected readonly endpoint:
|
|
392
|
-
protected readonly
|
|
393
|
-
constructor(endpoint:
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
protected clearInterceptors(): this;
|
|
397
|
-
execute(input: Input, options?: RemoteRequestConfig): Promise<Output>;
|
|
398
|
-
protected parseError(error: unknown): Error;
|
|
399
|
-
protected convertOrThrow<T>(fn: () => Promise<T>): Promise<T>;
|
|
400
|
-
private isStringArrayRecord;
|
|
401
|
-
private buildHttpErrorOptions;
|
|
503
|
+
declare abstract class RemoteResource<Input, Output, Client> implements AsyncOperation<Input, Output, HttpRequestOptions> {
|
|
504
|
+
protected readonly endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>;
|
|
505
|
+
protected readonly httpClient: HttpClient<Client>;
|
|
506
|
+
protected constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
507
|
+
execute(input: Input, options?: HttpRequestOptions): Promise<Output>;
|
|
508
|
+
private convertOrThrow;
|
|
402
509
|
}
|
|
403
510
|
//#endregion
|
|
404
|
-
//#region src/networking/remote-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
//#region src/networking/remote-request-interceptor.d.ts
|
|
408
|
-
interface RemoteRequestInterceptor extends Equatable, Hashable {
|
|
409
|
-
order: number;
|
|
410
|
-
intercept(config: RemoteRequestConfig): RemoteRequestConfig;
|
|
511
|
+
//#region src/networking/public-remote-resource.d.ts
|
|
512
|
+
declare class PublicRemoteResource<Input, Output, Client> extends RemoteResource<Input, Output, Client> {
|
|
513
|
+
constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
411
514
|
}
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
list(): RemoteRequestInterceptor[];
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region src/networking/secured-remote-resource.d.ts
|
|
517
|
+
declare class SecuredRemoteResource<Input, Output, Client> extends RemoteResource<Input, Output, Client> {
|
|
518
|
+
constructor(endpoint: RemoteEndpoint<Input, unknown, Output, unknown, Client>, httpClient: HttpClient<Client>);
|
|
519
|
+
execute(input: Input, options?: HttpRequestOptions): Promise<Output>;
|
|
418
520
|
}
|
|
419
521
|
//#endregion
|
|
420
522
|
//#region src/index.d.ts
|
|
421
523
|
declare function webkitAssembly(): Assembly[];
|
|
422
524
|
//#endregion
|
|
423
|
-
export {
|
|
525
|
+
export { AsyncQueue, AsyncQueueImpl, AsyncQueueMode, HttpClient, HttpClientOptions, HttpError, HttpErrorOptions, HttpRequest, HttpRequestInterceptor, HttpRequestInterceptorPipeline, HttpRequestOptions, PublicRemoteResource, RemoteEndpoint, RemoteResource, SecuredRemoteResource, TableDataModel, TablePaginationModel, UnauthorizedHandler, UnauthorizedOptions, WebKitL10nResource, WebKitSymbols, webkitAssembly };
|
package/dist/src/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import"reflect-metadata";import{CanceledError as e,ConversionError as t,CoreL10nResource as n,NetworkError as r,TimeoutError as i,UnknownError as a,coreAssembly as o
|
|
1
|
+
import"reflect-metadata";import{CanceledError as e,ConversionError as t,CoreL10nResource as n,NetworkError as r,TimeoutError as i,UnknownError as a,coreAssembly as o}from"@buildplease/core";import{injectable as s,unmanaged as c}from"inversify";export*from"@buildplease/core";function l(){return[]}`${{name:`buildplease`,displayName:`BuildPlease`,scope:`@buildplease`}.name}`;const u={DI:{}},d=n;var f=class{mode;pendingEntries=[];activeEntries=new Set;interruption;isSerialOperationRunning=!1;constructor(e=`parallel`){this.mode=e}execute(t){if(this.interruption)return Promise.reject(new e);let n=this.createEntry(t);return this.mode===`serial`?(this.pendingEntries.push(n),this.startNextSerialOperation()):this.startEntry(n),n.promise}cancelAll(e){let t=this.pendingEntries.splice(0);for(let n of t)this.cancelEntry(n,e);for(let t of this.activeEntries)this.cancelEntry(t,e)}async interrupt(e){if(!this.interruption){let t=Promise.resolve().then(e).finally(()=>{this.interruption===t&&(this.interruption=void 0,this.startNextSerialOperation())});this.interruption=t,this.cancelAll()}await this.interruption}createEntry(e){let t,n;return{operation:e,promise:new Promise((e,r)=>{t=e,n=r}),resolve:e=>t?.(e),reject:e=>n?.(e),canceled:!1,settled:!1}}startEntry(e){if(e.canceled||this.interruption){this.cancelEntry(e);return}this.activeEntries.add(e),this.mode===`serial`&&(this.isSerialOperationRunning=!0),Promise.resolve().then(e.operation).then(t=>{e.canceled||this.resolveEntry(e,t)},t=>{e.canceled||this.rejectEntry(e,t)}).finally(()=>{this.activeEntries.delete(e),this.mode===`serial`&&(this.isSerialOperationRunning=!1,this.startNextSerialOperation())})}startNextSerialOperation(){if(this.mode!==`serial`||this.isSerialOperationRunning||this.interruption)return;let e=this.pendingEntries.shift();e&&this.startEntry(e)}cancelEntry(t,n){t.canceled||(t.canceled=!0,t.settled||this.rejectEntry(t,new e({cause:n})))}resolveEntry(e,t){e.settled||(e.settled=!0,e.resolve(t))}rejectEntry(e,t){e.settled||(e.settled=!0,e.reject(t))}},p=class extends Error{statusCode;code;details;constructor(e){super(e.message),this.name=`HttpError`,this.statusCode=e.statusCode,this.code=e.code,this.details=e.details,e.cause!==void 0&&(this.cause=e.cause)}},m=class{interceptors;constructor(e=[],t){this.interceptors=this.resolveInterceptors(e,t)}async intercept(e){let t=e;for(let e of this.interceptors)t=await e.intercept(t);return t}resolveInterceptors(e,t){let n=new Set,r=[];for(let i of e){if(n.has(i.identity)){t?.(`Duplicate HTTP request interceptor ignored: ${String(i.identity)}`);continue}n.add(i.identity),r.push(i)}return Object.freeze(r)}};const h={credentials:!0,headers:{}};var g=class{requestOptions;interceptorPipeline;asyncQueue;unauthorized;constructor(e={}){this.requestOptions=e.requestOptions??{},this.interceptorPipeline=e.interceptorPipeline??new m,this.asyncQueue=e.asyncQueue??new f,this.unauthorized=e.unauthorized}execute(e,t){return this.asyncQueue.execute(async()=>{let n=await this.makeRequestOptions(e,t);try{let t=this.createClient(n);return await e.execute(t)}catch(e){throw this.handleError(e)}})}handleError(t){return t instanceof p||t instanceof r||t instanceof i||t instanceof e||t instanceof a?t:new a({message:t instanceof Error?t.message:void 0,cause:t})}async makeRequestOptions(e,t){let n=this.mergeRequestOptions(h,this.requestOptions);return n=await this.interceptorPipeline.intercept(n),n=this.mergeRequestOptions(n,e.options),n=this.mergeRequestOptions(n,t),n}mergeRequestOptions(e,t){return t?{credentials:t.credentials??e.credentials,headers:{...e.headers,...t.headers}}:e}};function _(e,t){if(typeof Reflect==`object`&&typeof Reflect.metadata==`function`)return Reflect.metadata(e,t)}function v(e,t){return function(n,r){t(n,r,e)}}function y(e,t,n,r){var i=arguments.length,a=i<3?t:r===null?r=Object.getOwnPropertyDescriptor(t,n):r,o;if(typeof Reflect==`object`&&typeof Reflect.decorate==`function`)a=Reflect.decorate(e,t,n,r);else for(var s=e.length-1;s>=0;s--)(o=e[s])&&(a=(i<3?o(a):i>3?o(t,n,a):o(t,n))||a);return i>3&&a&&Object.defineProperty(t,n,a),a}let b=class{endpoint;httpClient;constructor(e,t){this.endpoint=e,this.httpClient=t}async execute(e,t){let n=await this.convertOrThrow(()=>this.endpoint.convertInput(e)),r=this.endpoint.makeRequest(n),i=await this.httpClient.execute(r,t);return await this.convertOrThrow(()=>this.endpoint.convertOutput(i))}async convertOrThrow(e){try{return await e()}catch(e){throw new t({cause:e})}}};b=y([s(),v(0,c()),v(1,c()),_(`design:paramtypes`,[Object,Object])],b);let x=class extends b{constructor(e,t){super(e,t)}};x=y([s(),_(`design:paramtypes`,[Object,Object])],x);let S=class extends b{constructor(e,t){super(e,t)}async execute(t,n){try{return await super.execute(t,n)}catch(t){if(!(t instanceof p))throw t;let n=this.httpClient.unauthorized;throw!n||!n.statusCodes.includes(t.statusCode)?t:n.cancelAll?(await this.httpClient.asyncQueue.interrupt(()=>n.handler.handle(t)),new e({cause:t})):(await n.handler.handle(t),t)}}};S=y([s(),_(`design:paramtypes`,[Object,Object])],S);function C(){let e=o(),t=l();return[...e,...t]}export{f as AsyncQueueImpl,g as HttpClient,p as HttpError,m as HttpRequestInterceptorPipeline,x as PublicRemoteResource,b as RemoteResource,S as SecuredRemoteResource,d as WebKitL10nResource,u as WebKitSymbols,C as webkitAssembly};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buildplease/webkit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.2",
|
|
4
4
|
"keywords": [],
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,8 +37,7 @@
|
|
|
37
37
|
"resources"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"
|
|
41
|
-
"@buildplease/core": "1.0.0"
|
|
40
|
+
"@buildplease/core": "1.0.2"
|
|
42
41
|
},
|
|
43
42
|
"devDependencies": {
|
|
44
43
|
"@buildplease/identity": "1.0.0"
|