@schmock/angular 1.5.1 → 1.6.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.
Files changed (2) hide show
  1. package/dist/index.js +1 -263
  2. package/package.json +2 -3
package/dist/index.js CHANGED
@@ -1,263 +1 @@
1
- var __legacyDecorateClassTS = function(decorators, target, key, desc) {
2
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
4
- r = Reflect.decorate(decorators, target, key, desc);
5
- else
6
- for (var i = decorators.length - 1;i >= 0; i--)
7
- if (d = decorators[i])
8
- r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
9
- return c > 3 && r && Object.defineProperty(target, key, r), r;
10
- };
11
-
12
- // src/index.ts
13
- import {
14
- HTTP_INTERCEPTORS,
15
- HttpErrorResponse,
16
- HttpHeaders,
17
- HttpResponse
18
- } from "@angular/common/http";
19
- import { Injectable } from "@angular/core";
20
- import { isHttpMethod, ROUTE_NOT_FOUND_CODE } from "@schmock/core";
21
- import { Observable } from "rxjs";
22
- function toHttpMethod(method) {
23
- const upper = method.toUpperCase();
24
- if (isHttpMethod(upper)) {
25
- return upper;
26
- }
27
- return "GET";
28
- }
29
- function getStatusText(status) {
30
- const statusTexts = {
31
- 200: "OK",
32
- 201: "Created",
33
- 204: "No Content",
34
- 400: "Bad Request",
35
- 401: "Unauthorized",
36
- 403: "Forbidden",
37
- 404: "Not Found",
38
- 500: "Internal Server Error"
39
- };
40
- return statusTexts[status] || "Unknown";
41
- }
42
- function extractQueryParams(request) {
43
- const result = {};
44
- request.params.keys().forEach((key) => {
45
- const value = request.params.get(key);
46
- if (value !== null) {
47
- result[key] = value;
48
- }
49
- });
50
- const url = request.url;
51
- const queryStart = url.indexOf("?");
52
- if (queryStart !== -1) {
53
- const urlParams = new URLSearchParams(url.slice(queryStart + 1));
54
- urlParams.forEach((value, key) => {
55
- if (!(key in result)) {
56
- result[key] = value;
57
- }
58
- });
59
- }
60
- return result;
61
- }
62
- function extractPathname(url) {
63
- const queryStart = url.indexOf("?");
64
- const urlWithoutQuery = queryStart === -1 ? url : url.slice(0, queryStart);
65
- if (urlWithoutQuery.includes("://")) {
66
- try {
67
- const parsed = new URL(urlWithoutQuery);
68
- return parsed.pathname;
69
- } catch {}
70
- }
71
- if (!urlWithoutQuery.startsWith("/")) {
72
- return `/${urlWithoutQuery}`;
73
- }
74
- return urlWithoutQuery;
75
- }
76
- function headersToObject(request) {
77
- const headers = {};
78
- request.headers.keys().forEach((key) => {
79
- const value = request.headers.get(key);
80
- if (value !== null) {
81
- headers[key] = value;
82
- }
83
- });
84
- return headers;
85
- }
86
- function createSchmockInterceptor(mock, options = {}) {
87
- const {
88
- baseUrl,
89
- passthrough = true,
90
- errorFormatter,
91
- transformRequest,
92
- transformResponse
93
- } = options;
94
-
95
- class SchmockInterceptor {
96
- intercept(req, next) {
97
- const path = extractPathname(req.url);
98
- if (baseUrl && !path.startsWith(baseUrl)) {
99
- return next.handle(req);
100
- }
101
- const query = extractQueryParams(req);
102
- let requestData = {
103
- method: toHttpMethod(req.method),
104
- path,
105
- headers: headersToObject(req),
106
- body: req.body,
107
- query
108
- };
109
- if (transformRequest) {
110
- const transformed = transformRequest(req);
111
- requestData = {
112
- ...requestData,
113
- ...transformed,
114
- method: toHttpMethod(transformed.method ?? req.method)
115
- };
116
- }
117
- return new Observable((observer) => {
118
- let innerSub;
119
- let aborted = false;
120
- mock.handle(requestData.method, requestData.path, {
121
- headers: requestData.headers,
122
- body: requestData.body,
123
- query: requestData.query
124
- }).then((schmockResponse) => {
125
- if (aborted)
126
- return;
127
- const body = schmockResponse.body;
128
- const isRouteNotFound = schmockResponse.status === 404 && body !== null && typeof body === "object" && "code" in body && body.code === ROUTE_NOT_FOUND_CODE;
129
- if (isRouteNotFound && passthrough) {
130
- innerSub = next.handle(req).subscribe(observer);
131
- } else if (isRouteNotFound) {
132
- observer.error(new HttpErrorResponse({
133
- error: { message: "No matching mock route found" },
134
- status: 404,
135
- statusText: "Not Found",
136
- url: req.url
137
- }));
138
- } else {
139
- let response = schmockResponse;
140
- if (transformResponse) {
141
- response = transformResponse(response, req);
142
- }
143
- const status = response.status || 200;
144
- if (status >= 400) {
145
- let errorBody = response.body;
146
- const respBody = response.body;
147
- if (status === 500 && errorFormatter && respBody !== null && typeof respBody === "object" && "error" in respBody && "code" in respBody) {
148
- const errMsg = typeof respBody.error === "string" ? respBody.error : "Unknown error";
149
- const error = new Error(errMsg);
150
- errorBody = errorFormatter(error, req);
151
- }
152
- observer.error(new HttpErrorResponse({
153
- error: errorBody,
154
- status,
155
- statusText: getStatusText(status),
156
- url: req.url,
157
- headers: new HttpHeaders(response.headers || {})
158
- }));
159
- } else {
160
- const httpResponse = new HttpResponse({
161
- body: response.body,
162
- status,
163
- statusText: getStatusText(status),
164
- url: req.url,
165
- headers: new HttpHeaders(response.headers || {})
166
- });
167
- observer.next(httpResponse);
168
- observer.complete();
169
- }
170
- }
171
- }).catch((error) => {
172
- if (aborted)
173
- return;
174
- let errorBody;
175
- if (errorFormatter) {
176
- errorBody = errorFormatter(error instanceof Error ? error : new Error(String(error)), req);
177
- } else {
178
- const hasCode = error !== null && typeof error === "object" && "code" in error && typeof error.code === "string";
179
- errorBody = {
180
- error: error instanceof Error ? error.message : "Internal Server Error",
181
- code: hasCode ? error.code : "INTERNAL_ERROR"
182
- };
183
- }
184
- observer.error(new HttpErrorResponse({
185
- error: errorBody,
186
- status: 500,
187
- statusText: "Internal Server Error",
188
- url: req.url
189
- }));
190
- });
191
- return () => {
192
- aborted = true;
193
- innerSub?.unsubscribe();
194
- };
195
- });
196
- }
197
- }
198
- SchmockInterceptor = __legacyDecorateClassTS([
199
- Injectable()
200
- ], SchmockInterceptor);
201
- return SchmockInterceptor;
202
- }
203
- function provideSchmockInterceptor(mock, options) {
204
- return {
205
- provide: HTTP_INTERCEPTORS,
206
- useClass: createSchmockInterceptor(mock, options),
207
- multi: true
208
- };
209
- }
210
- function notFound(message = "Not Found") {
211
- const body = typeof message === "string" ? { message } : message;
212
- return [404, body];
213
- }
214
- function badRequest(message = "Bad Request") {
215
- const body = typeof message === "string" ? { message } : message;
216
- return [400, body];
217
- }
218
- function unauthorized(message = "Unauthorized") {
219
- const body = typeof message === "string" ? { message } : message;
220
- return [401, body];
221
- }
222
- function forbidden(message = "Forbidden") {
223
- const body = typeof message === "string" ? { message } : message;
224
- return [403, body];
225
- }
226
- function serverError(message = "Internal Server Error") {
227
- const body = typeof message === "string" ? { message } : message;
228
- return [500, body];
229
- }
230
- function created(body) {
231
- return [201, body];
232
- }
233
- function noContent() {
234
- return [204, null];
235
- }
236
- function paginate(items, options = {}) {
237
- const page = options.page || 1;
238
- const pageSize = options.pageSize || 10;
239
- const total = items.length;
240
- const totalPages = Math.ceil(total / pageSize);
241
- const start = (page - 1) * pageSize;
242
- const end = start + pageSize;
243
- const data = items.slice(start, end);
244
- return {
245
- data,
246
- page,
247
- pageSize,
248
- total,
249
- totalPages
250
- };
251
- }
252
- export {
253
- unauthorized,
254
- serverError,
255
- provideSchmockInterceptor,
256
- paginate,
257
- notFound,
258
- noContent,
259
- forbidden,
260
- created,
261
- createSchmockInterceptor,
262
- badRequest
263
- };
1
+ var O=function(A,J,K,L){var Y=arguments.length,V=Y<3?J:L===null?L=Object.getOwnPropertyDescriptor(J,K):L,$;if(typeof Reflect==="object"&&typeof Reflect.decorate==="function")V=Reflect.decorate(A,J,K,L);else for(var w=A.length-1;w>=0;w--)if($=A[w])V=(Y<3?$(V):Y>3?$(J,K,V):$(J,K))||V;return Y>3&&V&&Object.defineProperty(J,K,V),V};import{HTTP_INTERCEPTORS as H,HttpErrorResponse as f,HttpHeaders as E,HttpResponse as v}from"@angular/common/http";import{Injectable as R}from"@angular/core";import{isHttpMethod as S,ROUTE_NOT_FOUND_CODE as b}from"@schmock/core";import{Observable as k}from"rxjs";function D(A){let J=A.toUpperCase();if(S(J))return J;return"GET"}function x(A){return{200:"OK",201:"Created",204:"No Content",400:"Bad Request",401:"Unauthorized",403:"Forbidden",404:"Not Found",500:"Internal Server Error"}[A]||"Unknown"}function l(A){let J={};A.params.keys().forEach((Y)=>{let V=A.params.get(Y);if(V!==null)J[Y]=V});let K=A.url,L=K.indexOf("?");if(L!==-1)new URLSearchParams(K.slice(L+1)).forEach((V,$)=>{if(!($ in J))J[$]=V});return J}function h(A){let J=A.indexOf("?"),K=J===-1?A:A.slice(0,J);if(K.includes("://"))try{return new URL(K).pathname}catch{}if(!K.startsWith("/"))return`/${K}`;return K}function i(A){let J={};return A.headers.keys().forEach((K)=>{let L=A.headers.get(K);if(L!==null)J[K]=L}),J}function d(A,J={}){let{baseUrl:K,passthrough:L=!0,errorFormatter:Y,transformRequest:V,transformResponse:$}=J;class w{intercept(X,z){let Q=h(X.url);if(K&&!Q.startsWith(K))return z.handle(X);let T=l(X),M={method:D(X.method),path:Q,headers:i(X),body:X.body,query:T};if(V){let G=V(X);M={...M,...G,method:D(G.method??X.method)}}return new k((G)=>{let F,W=!1;return A.handle(M.method,M.path,{headers:M.headers,body:M.body,query:M.query}).then((Z)=>{if(W)return;let j=Z.body,N=Z.status===404&&j!==null&&typeof j==="object"&&"code"in j&&j.code===b;if(N&&L)F=z.handle(X).subscribe(G);else if(N)G.error(new f({error:{message:"No matching mock route found"},status:404,statusText:"Not Found",url:X.url}));else{let C=Z;if($)C=$(C,X);let U=C.status||200;if(U>=400){let{body:P,body:_}=C;if(U===500&&Y&&_!==null&&typeof _==="object"&&"error"in _&&"code"in _){let B=typeof _.error==="string"?_.error:"Unknown error",I=Error(B);P=Y(I,X)}G.error(new f({error:P,status:U,statusText:x(U),url:X.url,headers:new E(C.headers||{})}))}else{let P=new v({body:C.body,status:U,statusText:x(U),url:X.url,headers:new E(C.headers||{})});G.next(P),G.complete()}}}).catch((Z)=>{if(W)return;let j;if(Y)j=Y(Z instanceof Error?Z:Error(String(Z)),X);else{let N=Z!==null&&typeof Z==="object"&&"code"in Z&&typeof Z.code==="string";j={error:Z instanceof Error?Z.message:"Internal Server Error",code:N?Z.code:"INTERNAL_ERROR"}}G.error(new f({error:j,status:500,statusText:"Internal Server Error",url:X.url}))}),()=>{W=!0,F?.unsubscribe()}})}}return w=O([R()],w),w}function m(A,J){return{provide:H,useClass:d(A,J),multi:!0}}function p(A="Not Found"){return[404,typeof A==="string"?{message:A}:A]}function u(A="Bad Request"){return[400,typeof A==="string"?{message:A}:A]}function a(A="Unauthorized"){return[401,typeof A==="string"?{message:A}:A]}function o(A="Forbidden"){return[403,typeof A==="string"?{message:A}:A]}function t(A="Internal Server Error"){return[500,typeof A==="string"?{message:A}:A]}function s(A){return[201,A]}function r(){return[204,null]}function e(A,J={}){let K=J.page||1,L=J.pageSize||10,Y=A.length,V=Math.ceil(Y/L),$=(K-1)*L,w=$+L;return{data:A.slice($,w),page:K,pageSize:L,total:Y,totalPages:V}}export{a as unauthorized,t as serverError,m as provideSchmockInterceptor,e as paginate,p as notFound,r as noContent,o as forbidden,s as created,d as createSchmockInterceptor,u as badRequest};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@schmock/angular",
3
- "version": "1.5.1",
3
+ "version": "1.6.0",
4
4
  "description": "Angular HTTP interceptor adapter for Schmock",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -18,7 +18,7 @@
18
18
  "dev": "bun build:lib --watch",
19
19
  "clean": "rm -rf dist",
20
20
  "build": "bun run clean && bun run build:lib && bun run build:types",
21
- "build:lib": "bun build src/index.ts --outdir dist --target node --format esm --external @angular/common --external @angular/core --external @schmock/core --external rxjs",
21
+ "build:lib": "bun build --minify src/index.ts --outdir dist --target node --format esm --external @angular/common --external @angular/core --external @schmock/core --external rxjs",
22
22
  "build:types": "rm -f tsconfig.tsbuildinfo && tsc --build",
23
23
  "test": "vitest run",
24
24
  "test:watch": "vitest",
@@ -40,7 +40,6 @@
40
40
  "@angular/platform-browser": "^21.1.3",
41
41
  "@angular/platform-browser-dynamic": "^21.1.3",
42
42
  "@types/node": "^25.2.1",
43
- "jsdom": "^27.4.0",
44
43
  "typescript": "^5.9.3",
45
44
  "vitest": "^4.0.18",
46
45
  "zone.js": "^0.16.0"