Comparing version 0.21.3 to 0.22.0
@@ -54,3 +54,3 @@ "use strict"; | ||
var _b = createTemplateValues_1.default(tree, basePath, trailingSlash), api = _b.api, imports = _b.imports, pathes = _b.pathes; | ||
var text = ("/* eslint-disable */\nimport { AspidaClient" + (api.includes('BasicHeaders') ? ', BasicHeaders' : '') + (api.includes('dataToURLString') ? ', dataToURLString' : '') + " } from 'aspida'\n<% types %><% imports %>\n\n" + createDocComment_1.default('', (_a = tree.children.find(function (c) { return !c.isDir && c.name === 'index.ts'; })) === null || _a === void 0 ? void 0 : _a.doc) + "const api = <T>({ baseURL, fetch }: AspidaClient<T>) => {\n const prefix = (baseURL === undefined ? '<% baseURL %>' : baseURL).replace(/\\/$/, '')\n" + pathes.map(function (p, i) { return " const PATH" + i + " = " + p; }).join('\n') + "\n" + ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS'] | ||
var text = ("/* eslint-disable */\nimport { AspidaClient" + (api.includes('AspidaResponse') ? ', AspidaResponse' : '') + (api.includes('BasicHeaders') ? ', BasicHeaders' : '') + (api.includes('dataToURLString') ? ', dataToURLString' : '') + " } from 'aspida'\n<% types %><% imports %>\n\n" + createDocComment_1.default('', (_a = tree.children.find(function (c) { return !c.isDir && c.name === 'index.ts'; })) === null || _a === void 0 ? void 0 : _a.doc) + "const api = <T>({ baseURL, fetch }: AspidaClient<T>) => {\n const prefix = (baseURL === undefined ? '<% baseURL %>' : baseURL).replace(/\\/$/, '')\n" + pathes.map(function (p, i) { return " const PATH" + i + " = " + p; }).join('\n') + "\n" + ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'PATCH', 'OPTIONS'] | ||
.filter(function (m) { return api.includes(", " + m + ", option"); }) | ||
@@ -57,0 +57,0 @@ .map(function (m) { return " const " + m + " = '" + m + "'"; }) |
import { Doc } from './parseInterface'; | ||
declare const _default: (indent: string, doc?: Doc, props?: Partial<Record<"status" | "query" | "reqHeaders" | "reqFormat" | "reqBody" | "resHeaders" | "resBody", { | ||
declare const _default: (indent: string, doc?: Doc, props?: (Partial<Record<"status" | "query" | "reqHeaders" | "reqFormat" | "reqBody" | "resHeaders" | "resBody", { | ||
value: string; | ||
hasQuestion: boolean; | ||
doc?: Doc | undefined; | ||
}>> | undefined) => string; | ||
}>> & { | ||
polymorph?: Partial<Record<"status" | "query" | "reqHeaders" | "reqFormat" | "reqBody" | "resHeaders" | "resBody", { | ||
value: string; | ||
hasQuestion: boolean; | ||
doc?: Doc | undefined; | ||
}>>[] | undefined; | ||
}) | undefined) => string; | ||
export default _default; | ||
//# sourceMappingURL=createDocComment.d.ts.map |
"use strict"; | ||
var __assign = (this && this.__assign) || function () { | ||
__assign = Object.assign || function(t) { | ||
for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
s = arguments[i]; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
t[p] = s[p]; | ||
} | ||
return t; | ||
}; | ||
return __assign.apply(this, arguments); | ||
}; | ||
var __read = (this && this.__read) || function (o, n) { | ||
@@ -27,56 +38,117 @@ var m = typeof Symbol === "function" && o[Symbol.iterator]; | ||
var createDocComment_1 = __importDefault(require("./createDocComment")); | ||
var genReqBody = function (_a, importName, index) { | ||
var _b, _c, _d; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].reqBody) ? " body" + (((_d = (_c = props.polymorph) === null || _c === void 0 ? void 0 : _c[index].reqBody) === null || _d === void 0 ? void 0 : _d.hasQuestion) ? '?' : '') + ": " + importName + "['" + name + "']['polymorph'][" + index + "]['reqBody']," | ||
: props.reqBody | ||
? " body" + (props.reqBody.hasQuestion ? '?' : '') + ": " + importName + "['" + name + "']['reqBody']," | ||
: ''; | ||
}; | ||
var genQuery = function (_a, importName, index) { | ||
var _b, _c, _d; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].query) ? " query" + (((_d = (_c = props.polymorph) === null || _c === void 0 ? void 0 : _c[index].query) === null || _d === void 0 ? void 0 : _d.hasQuestion) ? '?' : '') + ": " + importName + "['" + name + "']['polymorph'][" + index + "]['query']," | ||
: props.query | ||
? " query" + (props.query.hasQuestion ? '?' : '') + ": " + importName + "['" + name + "']['query']," | ||
: ''; | ||
}; | ||
var genReqHeaders = function (_a, importName, index) { | ||
var _b, _c, _d; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].reqHeaders) ? " headers" + (((_d = (_c = props.polymorph) === null || _c === void 0 ? void 0 : _c[index].reqHeaders) === null || _d === void 0 ? void 0 : _d.hasQuestion) ? '?' : '') + ": " + importName + "['" + name + "']['polymorph'][" + index + "]['reqHeaders']," | ||
: props.reqHeaders | ||
? " headers" + (props.reqHeaders.hasQuestion ? '?' : '') + ": " + importName + "['" + name + "']['reqHeaders']," | ||
: ''; | ||
}; | ||
var genOption = function (method, importName, index) { | ||
var _a, _b, _c, _d, _e, _f, _g; | ||
if (index === void 0) { index = 0; } | ||
var poly = (_a = method.props.polymorph) === null || _a === void 0 ? void 0 : _a[index]; | ||
var isOptionRequired = ((_b = method.props.query) === null || _b === void 0 ? void 0 : _b.hasQuestion) === false || | ||
((_c = method.props.reqBody) === null || _c === void 0 ? void 0 : _c.hasQuestion) === false || | ||
((_d = method.props.reqHeaders) === null || _d === void 0 ? void 0 : _d.hasQuestion) === false || | ||
(poly && | ||
(((_e = poly.query) === null || _e === void 0 ? void 0 : _e.hasQuestion) === false || | ||
((_f = poly.reqBody) === null || _f === void 0 ? void 0 : _f.hasQuestion) === false || | ||
((_g = poly.reqHeaders) === null || _g === void 0 ? void 0 : _g.hasQuestion) === false)); | ||
return "(option" + (isOptionRequired ? '' : '?') + ": {" + genReqBody(method, importName, index) + genQuery(method, importName, index) + genReqHeaders(method, importName, index) + " config?: T })"; | ||
}; | ||
var genResBody = function (_a, importName) { | ||
var name = _a.name, props = _a.props; | ||
return props.resBody ? importName + "['" + name + "']['resBody']" : 'void'; | ||
}; | ||
var genPolyResBody = function (_a, importName, index) { | ||
var _b; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].resBody) ? importName + "['" + name + "']['polymorph'][" + index + "]['resBody']" | ||
: genResBody({ name: name, props: props }, importName); | ||
}; | ||
var genResHeaders = function (_a, importName) { | ||
var name = _a.name, props = _a.props; | ||
return props.resHeaders ? importName + "['" + name + "']['resHeaders']" : 'BasicHeaders'; | ||
}; | ||
var genPolyResHeaders = function (_a, importName, index) { | ||
var _b; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].resHeaders) ? importName + "['" + name + "']['polymorph'][" + index + "]['resHeaders']" | ||
: genResHeaders({ name: name, props: props }, importName); | ||
}; | ||
var genStatus = function (_a, importName) { | ||
var name = _a.name, props = _a.props; | ||
return props.status ? ", " + importName + "['" + name + "']['status']" : ''; | ||
}; | ||
var genPolyStatus = function (_a, importName, index) { | ||
var _b; | ||
var name = _a.name, props = _a.props; | ||
return ((_b = props.polymorph) === null || _b === void 0 ? void 0 : _b[index].status) ? ", " + importName + "['" + name + "']['polymorph'][" + index + "]['status']" | ||
: genStatus({ name: name, props: props }, importName); | ||
}; | ||
var genRequest = function (props) { | ||
return ", option" + (!props.reqBody | ||
? '' | ||
: props.reqFormat | ||
? ", '" + props.reqFormat.value + "'" | ||
: props.reqBody && /^(ArrayBuffer|Blob|string)$/.test(props.reqBody.value) | ||
? ", '" + props.reqBody.value + "'" | ||
: ''); | ||
}; | ||
var genResMethodName = function (props) { | ||
return !props.resBody | ||
? 'send' | ||
: { ArrayBuffer: 'arrayBuffer', Blob: 'blob', string: 'text', FormData: 'formData' }[props.resBody.value] || 'json'; | ||
}; | ||
var genReturnVal = function (method, importName, path) { | ||
return "fetch<" + genResBody(method, importName) + ", " + genResHeaders(method, importName) + genStatus(method, importName) + ">(prefix, " + path + ", " + method.name.toUpperCase() + genRequest(method.props) + ")." + genResMethodName(method.props) + "()"; | ||
}; | ||
var genPolyType = function (method, importName, index) { | ||
return "Promise<AspidaResponse<" + genPolyResBody(method, importName, index) + ", " + genPolyResHeaders(method, importName, index) + genPolyStatus(method, importName, index) + ">>"; | ||
}; | ||
var genPolymorphReturnVal = function (method, indent, path) { | ||
var _a, _b; | ||
return method.name + "Request(option: any) {\n" + indent + " return fetch(prefix, " + path + ", " + method.name.toUpperCase() + genRequest(__assign(__assign({}, method.props), (_a = method.props.polymorph) === null || _a === void 0 ? void 0 : _a.find(function (p) { return p.reqBody; }))) + ")." + genResMethodName(__assign(__assign({}, method.props), (_b = method.props.polymorph) === null || _b === void 0 ? void 0 : _b.find(function (p) { return p.reqBody; }))) + "()"; | ||
}; | ||
exports.default = (function (methods, indent, importName, path) { | ||
return __spread(methods.map(function (_a) { | ||
var name = _a.name, props = _a.props, doc = _a.doc; | ||
var isOptionRequired = (props.query && !props.query.hasQuestion) || | ||
(props.reqBody && !props.reqBody.hasQuestion) || | ||
(props.reqHeaders && !props.reqHeaders.hasQuestion); | ||
var reqBody = function (method) { | ||
return props.reqBody | ||
? " body" + (props.reqBody.hasQuestion ? '?' : '') + ": " + importName + "['" + method + "']['reqBody']," | ||
: ''; | ||
}; | ||
var query = function (method) { | ||
return props.query | ||
? " query" + (props.query.hasQuestion ? '?' : '') + ": " + importName + "['" + method + "']['query']," | ||
: ''; | ||
}; | ||
var reqHeaders = function (method) { | ||
return props.reqHeaders | ||
? " headers" + (props.reqHeaders.hasQuestion ? '?' : '') + ": " + importName + "['" + method + "']['reqHeaders']," | ||
: ''; | ||
}; | ||
var resHeaders = function (method) { | ||
return props.resHeaders | ||
? ", " + importName + "['" + method + "']['resHeaders']" | ||
: props.status | ||
? ', BasicHeaders' | ||
: ''; | ||
}; | ||
var status = function (method) { | ||
return "" + (props.status ? ", " + importName + "['" + method + "']['status']" : ''); | ||
}; | ||
var option = function (method) { | ||
return "option" + (isOptionRequired ? '' : '?') + ": {" + reqBody(method) + query(method) + reqHeaders(method) + " config?: T }"; | ||
}; | ||
var request = function () { | ||
return ", option" + (!props.reqBody | ||
? '' | ||
: props.reqFormat | ||
? ", '" + props.reqFormat.value + "'" | ||
: props.reqBody && /^(ArrayBuffer|Blob|string)$/.test(props.reqBody.value) | ||
? ", '" + props.reqBody.value + "'" | ||
: ''); | ||
}; | ||
var resBody = function (method) { | ||
return "" + (props.resBody ? importName + "['" + method + "']['resBody']" : 'void'); | ||
}; | ||
var resMethodName = function () { | ||
return !props.resBody | ||
? 'send' | ||
: { ArrayBuffer: 'arrayBuffer', Blob: 'blob', string: 'text', FormData: 'formData' }[props.resBody.value] || 'json'; | ||
}; | ||
return __spread(methods.map(function (method) { | ||
var _a; | ||
var name = method.name, props = method.props, doc = method.doc; | ||
if ((_a = props.polymorph) === null || _a === void 0 ? void 0 : _a.length) { | ||
var polys = props.polymorph.map(function (_, i) { return [ | ||
indent + " function " + name + "Request" + genOption(method, importName, i) + ": " + genPolyType(method, importName, i), | ||
indent + " function $" + name + "Request" + genOption(method, importName, i) + ": Promise<" + genPolyResBody(method, importName, i) + ">" | ||
]; }); | ||
return indent + " " + name + ": (() => {\n" + polys | ||
.map(function (_a) { | ||
var _b = __read(_a, 1), a = _b[0]; | ||
return a; | ||
}) | ||
.join('\n') + "\n" + indent + " function " + genPolymorphReturnVal(method, indent, path) + "\n" + indent + " }\n" + indent + " return " + name + "Request\n" + indent + " })(),\n" + indent + " $" + name + ": (() => {\n" + polys | ||
.map(function (_a) { | ||
var _b = __read(_a, 2), b = _b[1]; | ||
return b; | ||
}) | ||
.join('\n') + "\n" + indent + " function $" + genPolymorphReturnVal(method, indent, path) + ".then(r => r.body)\n" + indent + " }\n" + indent + " return $" + name + "Request\n" + indent + " })()"; | ||
} | ||
var tmpChanks = [ | ||
"(" + option(name) + ") =>", | ||
"fetch<" + resBody(name) + resHeaders(name) + status(name) + ">(prefix, " + path + ", " + name.toUpperCase() + request() + ")." + resMethodName() + "()" | ||
genOption(method, importName) + " =>", | ||
genReturnVal(method, importName, path) | ||
]; | ||
@@ -100,4 +172,7 @@ return "" + createDocComment_1.default(indent + " ", doc, props) + indent + " " + name + ": " + tmpChanks[0] + "\n" + indent + " " + tmpChanks[1] + ",\n" + createDocComment_1.default(indent + " ", doc, props) + indent + " $" + name + ": " + tmpChanks[0] + "\n" + indent + " " + tmpChanks[1] + ".then(r => r.body)"; | ||
: indent + " $path: () => `${prefix}${" + (path.startsWith('`') ? path.slice(3, -2) : path) + "}`" | ||
]).join(',\n'); | ||
]).join(',\n') | ||
.replace(/, BasicHeaders>/g, '>') | ||
.replace(/fetch<void>/g, 'fetch') | ||
.replace(/AspidaResponse<void>/g, 'AspidaResponse'); | ||
}); | ||
//# sourceMappingURL=createMethodsString.js.map |
@@ -13,3 +13,3 @@ export declare type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'PATCH' | 'OPTIONS'; | ||
}; | ||
export declare type AspidaResponse<T, U, V> = { | ||
export declare type AspidaResponse<T = void, U = BasicHeaders, V = HttpStatusOk> = { | ||
status: V; | ||
@@ -29,3 +29,3 @@ headers: U; | ||
fetch: <T, U = BasicHeaders, V = HttpStatusOk>(prefix: string, path: string, method: HttpMethod, params?: AspidaParams<Config>, type?: RequestType) => { | ||
send(): Promise<AspidaResponse<null, U, V>>; | ||
send(): Promise<AspidaResponse<void, U, V>>; | ||
json(): Promise<AspidaResponse<T, U, V>>; | ||
@@ -32,0 +32,0 @@ text(): Promise<AspidaResponse<string, U, V>>; |
@@ -9,5 +9,8 @@ import { LowerHttpMethod, AspidaMethodParams } from './'; | ||
}; | ||
declare type MethodProps = Partial<Record<MethodsProperties, Prop>>; | ||
export declare type Method = { | ||
name: LowerHttpMethod; | ||
props: Partial<Record<MethodsProperties, Prop>>; | ||
props: MethodProps & { | ||
polymorph?: MethodProps[]; | ||
}; | ||
doc?: Doc; | ||
@@ -14,0 +17,0 @@ }; |
@@ -151,2 +151,23 @@ "use strict"; | ||
}; | ||
var parseTaple = function (text) { | ||
var cursor = 1; // '[' | ||
var length = text.length; | ||
var propsList = []; | ||
while (text[cursor] !== ']' && cursor < length) { | ||
var props = {}; | ||
cursor += countIgnored(text.slice(cursor)) + 1; // '{' | ||
cursor += countIgnored(text.slice(cursor)); | ||
while (text[cursor] !== '}' && cursor < length) { | ||
var prop = parseProp(text.slice(cursor)); | ||
cursor += prop.length; | ||
props[prop.name] = prop.value; | ||
} | ||
cursor += 1; // '}' | ||
cursor += countIgnored(text.slice(cursor)); | ||
propsList.push(props); | ||
} | ||
cursor += countIgnored(text.slice(cursor)); | ||
cursor += 1; // ']' | ||
return { value: propsList, length: cursor + countIgnored(text.slice(cursor)) }; | ||
}; | ||
var parseProp = function (text) { | ||
@@ -160,4 +181,9 @@ var cursor = 0; | ||
var name = parseName(text.slice(cursor)); | ||
cursor += name.length; | ||
if (name.value === 'polymorph') { | ||
cursor += countIgnored(text.slice(cursor)); | ||
var val = parseTaple(text.slice(cursor)); | ||
return { name: 'polymorph', value: val.value, length: cursor + val.length }; | ||
} | ||
var prop = { value: '', hasQuestion: name.hasQuestion, doc: doc === null || doc === void 0 ? void 0 : doc.values }; | ||
cursor += name.length; | ||
while (cursor < length) { | ||
@@ -164,0 +190,0 @@ cursor += countIgnored(text.slice(cursor)); |
{ | ||
"name": "aspida", | ||
"version": "0.21.3", | ||
"version": "0.22.0", | ||
"description": "TypeScript friendly HTTP client wrapper for the browser and node.js", | ||
@@ -5,0 +5,0 @@ "author": "Solufa <solufa2020@gmail.com>", |
122
README.md
@@ -5,6 +5,4 @@ # aspida | ||
<br /> | ||
<div align="center"> | ||
<img src="https://aspida.github.io/aspida/logos/svg/black.svg" alt="aspida" title="aspida" width="600" /> | ||
</div> | ||
<br /> | ||
<img src="https://aspida.github.io/aspida/logos/svg/black.svg" alt="aspida" title="aspida" width="1000" height="120" /> | ||
<br /> | ||
@@ -38,20 +36,2 @@ <br /> | ||
## Breaking change (2020/06/16) :warning: | ||
Since aspida >= `0.18.0` , the property `data` of the request and response has been changed to `body`. | ||
```typescript | ||
const { body } = await client.v1.users.post({ body: { name: "taro" } }) | ||
const body = await client.v1.users.$post({ body: { name: "taro" } }) | ||
``` | ||
### The modules affected by this change | ||
- @aspida/axios >= `0.8.0` | ||
- @aspida/ky >= `0.6.0` | ||
- @aspida/fetch >= `0.6.0` | ||
- @aspida/node-fetch >= `0.5.0` | ||
- openapi2aspida >= `0.8.0` | ||
## Features | ||
@@ -124,2 +104,9 @@ | ||
resBody: User | ||
/** | ||
* reqHeaders(?): ... | ||
* reqFormat: ... | ||
* status: ... | ||
* resHeaders(?): ... | ||
* polymorph: [...] | ||
*/ | ||
} | ||
@@ -293,2 +280,10 @@ } | ||
## Ecosystem | ||
- [openapi2aspida](https://github.com/aspida/openapi2aspida) - Convert OpenAPI 3.0 and Swagger 2.0 definitions | ||
- [aspida-mock](https://github.com/aspida/aspida-mock) - TypeScript friendly RESTful API mock | ||
- [@aspida/swr](https://github.com/aspida/aspida/tree/master/packages/aspida-swr) - SWR (React Hooks) wrapper | ||
- [@aspida/swrv](https://github.com/aspida/aspida/tree/master/packages/aspida-swrv) - SWRV (Vue Composition API) wrapper | ||
- [eslint-plugin-aspida](https://github.com/ibuki2003/eslint-plugin-aspida) - Support writing aspida api definition | ||
## Tips | ||
@@ -301,3 +296,3 @@ | ||
1. [Receive response with ArrayBuffer](#tips5) | ||
1. [Convert from OpenAPI / Swagger](#tips6) | ||
1. [Define polymorphic request](#tips6) | ||
1. [Define endpoints that contain special characters](#tips7) | ||
@@ -307,5 +302,2 @@ 1. [Import only some endpoints](#tips8) | ||
1. [Reflect TSDoc comments](#tips10) | ||
1. [Use mock](#tips11) | ||
1. [Use with SWR (React Hooks)](#tips12) | ||
1. [Use with SWRV (Vue Composition API)](#tips13) | ||
@@ -485,15 +477,63 @@ <a id="tips1"></a> | ||
### Convert from OpenAPI / Swagger | ||
### Define polymorphic request | ||
Compatible with yaml/json of OpenAPI3.0/Swagger2.0 | ||
`api/users/index.ts` | ||
`tarminal` | ||
```ts | ||
type User = { | ||
id: number | ||
name: string | ||
} | ||
```sh | ||
$ npx openapi2aspida -i https://petstore.swagger.io/v2/swagger.json | ||
# api/$api.ts was built successfully. | ||
export interface Methods { | ||
post: { | ||
// common properties | ||
reqFormat: FormData | ||
/** | ||
* query(?): ... | ||
* reqHeaders(?): ... | ||
* reqBody(?): ... | ||
* status: ... | ||
* resHeaders(?): ... | ||
* resBody(?): ... | ||
*/ | ||
polymorph: [ | ||
// polymorphic types | ||
{ | ||
reqBody: Omit<User, 'id'> | ||
resBody: User | ||
/** | ||
* query(?): ... | ||
* reqHeaders(?): ... | ||
* status: ... | ||
* resHeaders(?): ... | ||
*/ | ||
}, | ||
{ | ||
reqBody: Omit<User, 'id'>[] | ||
resBody: User[] | ||
} | ||
] | ||
} | ||
} | ||
``` | ||
[Docs of openapi2aspida](https://github.com/aspida/openapi2aspida) | ||
`src/index.ts` | ||
```ts | ||
import aspida from "@aspida/axios" | ||
import api from "../api/$api" | ||
;(async () => { | ||
const client = api(aspida()) | ||
const user = await client.users.$post({ body: { name: "taro" } }) | ||
console.log(user) // { id: 0, name: "taro" } | ||
const users = await client.users.$post({ | ||
body: [{ name: "hanako" }, { name: "mario" }] | ||
}) | ||
console.log(users) // [{ id: 1, name: "hanako" }, { id: 2, name: "mario" }] | ||
})() | ||
``` | ||
<a id="tips7"></a> | ||
@@ -665,20 +705,2 @@ | ||
<a id="tips11"></a> | ||
### Use mock | ||
**[GitHub aspida-mock](https://github.com/aspida/aspida-mock)** | ||
<a id="tips12"></a> | ||
### Use with SWR (React Hooks) | ||
**[GitHub @aspida/swr](https://github.com/aspida/aspida/tree/master/packages/aspida-swr#readme)** | ||
<a id="tips13"></a> | ||
### Use with SWRV (Vue Composition API) | ||
**[GitHub @aspida/swrv](https://github.com/aspida/aspida/tree/master/packages/aspida-swrv#readme)** | ||
## Support | ||
@@ -685,0 +707,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
106334
1055
707