@weclapp/sdk 1.8.0-dev.17 → 1.8.0-dev.19
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/cli.js +6 -94
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -146,7 +146,7 @@ const generateBlockStatements = (...statements) => `{\n${indent(generateStatemen
|
|
|
146
146
|
|
|
147
147
|
var root = "export type RequestPayloadMethod = 'GET' | 'HEAD' | 'POST' | 'PUT' | 'DELETE' | 'CONNECT' | 'OPTIONS' | 'TRACE' | 'PATCH';\n\nexport interface RequestPayload {\n method?: RequestPayloadMethod;\n query?: Record<string, any>;\n body?: any;\n unwrap?: boolean;\n forceBlob?: boolean;\n}\n\nexport interface ServiceConfig {\n\n // Your API-Key, this is optional in the sense of if you omit this, and you're in a browser, the\n // cookie-authentication (include-credentials) will be used.\n key?: string;\n\n // Your domain, if omitted location.host will be used.\n host?: string;\n\n // If you want to use https, defaults to true.\n secure?: boolean;\n\n // Optional request/response interceptors.\n interceptors?: {\n\n // Takes the generated request, you can either return a new request,\n // a response (which will be taken as \"the\" response) or nothing.\n // The payload contains the raw input generated by the SDK.\n request?: (request: Request, payload: RequestPayload) => Request | Response | void | Promise<Request | Response | void>;\n\n // Takes the response. This can either be the one from the server or an\n // artificially-crafted one by the request interceptor.\n response?: (response: Response) => Response | void | Promise<Response | void>;\n };\n}\n\nlet globalConfig: ServiceConfig | undefined;\nexport const getGlobalConfig = (): ServiceConfig | undefined => globalConfig;\nexport const setGlobalConfig = (cfg?: ServiceConfig) => globalConfig = cfg;\n\nexport const raw = async (\n cfg: ServiceConfig | undefined = globalConfig,\n endpoint: string,\n payload: RequestPayload = {}\n): Promise<any> => {\n if (!cfg) {\n throw new Error(`ServiceConfig missing.`);\n }\n\n cfg = {\n ...globalConfig, ...cfg,\n interceptors: {...globalConfig?.interceptors, ...cfg?.interceptors}\n };\n\n const isBinaryData = payload.body instanceof resolveBinaryObject();\n const params = new URLSearchParams(Object.entries(payload.query ?? {}).filter(v => v[1] !== undefined));\n const protocol = (cfg.secure ?? true) ? 'https' : 'http';\n\n const interceptRequest = cfg.interceptors?.request ?? (v => v);\n const interceptResponse = cfg.interceptors?.response ?? (v => v);\n\n let host = cfg.host?.replace(/^https?:\\/\\//, '');\n if (!host && typeof location !== 'undefined') {\n host = location.host;\n }\n\n if (!host) {\n throw new Error('Please specify a domain');\n }\n\n const request = new Request(`${protocol}://${host}/webapp/api/v1${endpoint}?${params}`, {\n ...(payload.body && {\n body: isBinaryData\n ? payload.body\n : JSON.stringify(payload.body, (key, value) => value === undefined ? null : value)\n }),\n ...(!cfg.key && {credentials: 'same-origin'}),\n method: payload.method ?? 'get',\n headers: {\n 'Accept': 'application/json',\n ...(cfg.key && {'AuthenticationToken': cfg.key}),\n ...(!isBinaryData && {'Content-Type': 'application/json'})\n }\n });\n\n let res = await interceptRequest(request, payload) ?? request;\n if (!(res instanceof Response)) {\n res = await fetch(res);\n }\n\n res = await interceptResponse(res) ?? res;\n const data = (!payload.forceBlob || !res.ok) && res.headers?.get('content-type')?.includes('application/json') ?\n await res.json() : await res.blob();\n\n // Check if response was successful\n if (!res.ok) {\n return Promise.reject(data);\n }\n\n return payload.unwrap ? data.result : data;\n};\n\nconst _count = (\n cfg: ServiceConfig | undefined,\n endpoint: string,\n query?: CountQuery<any> & {params?: Record<any, any>}\n) => wrapResponse(() => raw(cfg, endpoint, {\n unwrap: true,\n query: {\n ...flattenFilter(query?.filter),\n ...flattenOrFilter(query?.or),\n ...query?.params\n }\n}));\n\nconst _some = (\n cfg: ServiceConfig | undefined,\n endpoint: string,\n query?: SomeQuery<any, any, any, any> & {params?: Record<any, any>}\n) => wrapResponse(() => raw(cfg, endpoint, {\n query: {\n serializeNulls: query?.serializeNulls,\n properties: query?.select ? flattenSelect(query.select).join(',') : undefined,\n includeReferencedEntities: query?.include ? Object.keys(query.include).join(',') : undefined,\n ...flattenOrFilter(query?.or),\n ...flattenFilter(query?.filter),\n ...flattenSort(query?.sort),\n ...query?.params,\n ...query?.pagination\n }\n }).then(data => ({entities: data.result, references: data.referencedEntities ?? {}}))\n);\n\nconst _remove = (\n cfg: ServiceConfig | undefined,\n endpoint: string\n) => wrapResponse(() => raw(cfg, endpoint, {\n method: 'DELETE'\n}).then(() => undefined));\n\nconst _create = (\n cfg: ServiceConfig | undefined,\n endpoint: string,\n data: any\n) => wrapResponse(() => raw(cfg, endpoint, {\n method: 'POST',\n body: data\n}));\n\nconst _update = (\n cfg: ServiceConfig | undefined,\n endpoint: string,\n data: any,\n {ignoreMissingProperties = true}: UpdateQuery = {}\n) => wrapResponse(() => raw(cfg, endpoint, {\n method: 'PUT',\n body: data,\n query: {ignoreMissingProperties}\n}));\n\nconst _unique = (\n cfg: ServiceConfig | undefined,\n endpoint: string,\n query?: UniqueQuery\n) => wrapResponse(() => raw(cfg, endpoint, {query}));\n\nconst _generic = (\n cfg: ServiceConfig | undefined,\n method: RequestPayloadMethod,\n endpoint: string,\n payload?: GenericQuery<any, any>,\n forceBlob?: boolean\n) => wrapResponse(() => raw(cfg, endpoint, {\n method,\n forceBlob,\n body: payload?.body,\n query: payload?.params\n}));\n";
|
|
148
148
|
|
|
149
|
-
var types
|
|
149
|
+
var types = "export type DeepPartial<T> = T extends object ? {\n [P in keyof T]?: DeepPartial<T[P]>;\n} : T;\n\n// Filter properties\nexport type EqualityOperators = 'EQ' | 'NE';\nexport type ComparisonOperators = 'LT' | 'GT' | 'LE' | 'GE' | 'LIKE' | 'ILIKE' | 'NOT_LIKE' | 'NOT_ILIKE';\nexport type ArrayOperators = 'IN' | 'NOT_IN';\nexport type Operator = EqualityOperators | ComparisonOperators | ArrayOperators;\n\nexport type MapOperators<T> = { [K in EqualityOperators]?: T | null; } &\n { [K in ComparisonOperators]?: T; } &\n { [K in ArrayOperators]?: T[]; };\n\nexport type QueryFilter<T> = {\n [P in keyof T]?:\n T[P] extends Array<infer U> | undefined ?\n U extends Record<any, any> ? QueryFilter<U> : MapOperators<U> :\n T[P] extends Record<any, any> | undefined ? QueryFilter<T[P]> : MapOperators<T[P]>;\n};\n\nexport type Sort<T> = {\n [K in keyof T]?: {\n [V in keyof T]?:\n V extends K ?\n T[V] extends Array<infer U> | undefined ?\n U extends object ?\n Sort<U> : never :\n T[V] extends object | undefined ?\n Sort<T[V]> : 'asc' | 'desc' : never;\n };\n}[keyof T];\n\n// Select properties\nexport type CustomAttributeFilter = {\n [K in number]: string | number | boolean |\n {id: string;} |\n {entityName: string; entityId: string;};\n}\n\nexport type QuerySelect<T> = {\n [P in keyof T]?:\n T[P] extends Array<infer U> | undefined ? (QuerySelect<U> | boolean) :\n T[P] extends Record<any, any> | undefined ? (QuerySelect<T[P]> | boolean) : boolean;\n}\n\nexport type Select<T, Q extends (QuerySelect<T> | undefined)> = Q extends QuerySelect<T> ? {\n\n // Filter out excluded properties beforehand\n [P in keyof T as Q[P] extends boolean ? P : Q[P] extends object ? P : never]:\n\n // Property\n Q[P] extends true ? T[P] :\n\n // Array\n T[P] extends Array<infer U> ? Select<U, Q[P] & QuerySelect<any>>[] :\n\n // Object\n T[P] extends Record<any, any> ? Select<T[P], Q[P] & QuerySelect<any>> : never\n} : undefined;\n\nexport type MapKeys<T, S extends Record<keyof T, string>> = {\n [K in keyof T as S[K]]: T[K];\n};\n\n// Endpoint configurations\nexport type CountQuery<F> = {\n filter?: QueryFilter<F>;\n or?: (QueryFilter<F> & CustomAttributeFilter)[];\n};\n\nexport type Pagination = {\n page: number;\n pageSize: number;\n};\n\nexport type SomeQuery<\n E, // Entity\n F, // Entity filter\n I extends (QuerySelect<any> | undefined), // Select for referenced entities\n S extends (QuerySelect<any> | undefined) // Select for entity properties\n> = {\n serializeNulls?: boolean;\n include?: I;\n filter?: QueryFilter<F> & CustomAttributeFilter;\n select?: S;\n or?: (QueryFilter<F> & CustomAttributeFilter)[];\n sort?: Sort<E>[];\n pagination?: Pagination;\n};\n\nexport type UniqueQuery = {\n serializeNulls?: boolean;\n}\n\nexport type SomeQueryReturn<\n E, // Entity\n R, // Map of referenced-entity names to the type\n M, // Map of referenced-entity-id names to their entity name\n I extends (QuerySelect<any> | undefined), // Select for referenced entities\n S extends (QuerySelect<any> | undefined) // Select for entity properties\n> = {\n entities: (S extends QuerySelect<E> ? Select<E, S> : E)[];\n references: I extends QuerySelect<R> ? Partial<MapKeys<Select<R, I>, M & Record<any, any>>> : {};\n};\n\nexport type GenericQuery<P, B> = {\n params?: P;\n body?: B;\n};\n\nexport type UpdateQuery = {\n ignoreMissingProperties?: boolean;\n}\n\n// Entity meta types\nexport type WEntityPropertyMeta = (\n { type: 'string'; format?: 'decimal' | 'html'; entity?: WEntity; service?: WService; } |\n { type: 'integer'; format: 'int32' | 'int64' | 'duration' | 'date' | 'timestamp'; } |\n { type: 'array'; format: 'reference'; entity: WEntity; service?: WService; } |\n { type: 'array'; format: 'reference'; enum: WEnum; } |\n { type: 'array'; format: 'string'; } |\n { type: 'number'; format: 'double'; } |\n { type: 'reference'; entity: WEntity; } |\n { type: 'reference'; enum: WEnum; } |\n { type: 'boolean'; } |\n { type: 'object'; }\n);\n\n// Utils\nconst equality: string[] = ['EQ', 'NE'];\nconst simple: string[] = [...equality, 'LT', 'GT', 'LE', 'GE', 'LIKE', 'NOT_LIKE', 'ILIKE', 'NOT_ILIKE'];\nconst array: string[] = ['IN', 'NOT_IN'];\nconst filterMap: Record<Operator, string> = {\n EQ: 'eq',\n NE: 'ne',\n LT: 'lt',\n GT: 'gt',\n LE: 'le',\n GE: 'ge',\n LIKE: 'like',\n NOT_LIKE: 'notlike',\n ILIKE: 'ilike',\n NOT_ILIKE: 'notilike',\n IN: 'in',\n NOT_IN: 'notin'\n};\n\nconst flattenCustomAttributes = (obj: CustomAttributeFilter = {}): [string, string][] => {\n const entries: [string, string][] = [];\n\n for (const [id, filter] of Object.entries(obj)) {\n const key = `customAttribute${id}`;\n\n if (typeof filter === 'object') {\n for (const [prop, value] of Object.entries(filter)) {\n entries.push([`${key}.${prop}-eq`, String(value)]);\n }\n } else if (filter !== undefined) {\n entries.push([`${key}-eq`, String(filter)]);\n }\n }\n\n return entries;\n};\n\nconst flatten = (obj: QueryFilter<any> = {}): [string, string][] => {\n const entries: [string, string][] = [];\n\n for (const [prop, propValue] of Object.entries(obj)) {\n for (const [filter, value] of Object.entries(propValue as object)) {\n if (value === undefined) continue;\n\n if (simple.includes(filter)) {\n if (value === null && equality.includes(filter)) {\n entries.push([`${prop}-${filter === 'EQ' ? 'null' : 'notnull'}`, '']);\n } else {\n entries.push([`${prop}-${filterMap[filter as Operator]}`, value]);\n }\n } else if (array.includes(filter)) {\n entries.push([\n `${prop}-${filterMap[filter as Operator]}`,\n `[${value.map((v: string | number) => typeof v === 'string' ? `\"${v}\"` : v)}]`\n ]);\n } else {\n entries.push(\n ...flatten(propValue as QueryFilter<any>)\n .map(v => [`${prop}.${v[0]}`, v[1]]) as [string, string][]\n );\n break;\n }\n }\n }\n\n return entries;\n};\n\nconst flattenFilter = (obj: QueryFilter<any> = {}): Record<string, string> => {\n const filter: [string, any][] = [], customAttributes: [string, any][] = [];\n\n Object.entries(obj).forEach(value => {\n (value[0].match(/^\\d+$/) ? customAttributes : filter).push(value);\n });\n\n return Object.fromEntries([\n ...flatten(Object.fromEntries(filter)),\n ...flattenCustomAttributes(Object.fromEntries(customAttributes) as CustomAttributeFilter)\n ]);\n};\n\nconst flattenOrFilter = (obj: QueryFilter<any>[] = []): Record<string, string> => {\n const entries: [string, any][] = [];\n\n for (let i = 0; i < obj.length; i++) {\n entries.push(\n ...flatten(obj[i])\n .map(v => [`or${i || ''}-${v[0]}`, v[1]]) as [string, string][]\n );\n }\n\n return Object.fromEntries(entries);\n};\n\nconst flattenSelect = (obj: Select<any, any> = {}): string[] => {\n const entries: string[] = [];\n\n for (const [prop, value] of Object.entries(obj)) {\n if (typeof value === 'object' && value) {\n entries.push(...flattenSelect(value).map(v => `${prop}.${v}`));\n } else if (value) {\n entries.push(prop);\n }\n }\n\n return entries;\n};\n\nexport const flattenSort = (obj: Sort<any>[] = []): {sort?: string} => {\n const flatten = (obj: Sort<any>, base = ''): string | undefined => {\n const [key, value] = Object.entries(obj ?? {})[0] ?? [];\n\n if (key && value) {\n const path = base + key;\n\n if (typeof value === 'object') {\n return flatten(value, path ? `${path}.` : '');\n } else if (['asc', 'desc'].includes(value)) {\n return `${value === 'desc' ? '-' : ''}${path}`;\n }\n }\n\n return undefined;\n };\n\n const sorts = obj.map(v => flatten(v)).filter(Boolean);\n return sorts.length ? {sort: sorts.join(',')} : {};\n};\n";
|
|
150
150
|
|
|
151
151
|
const resolveImports = (target) => {
|
|
152
152
|
const imports = [];
|
|
@@ -158,7 +158,7 @@ const resolveImports = (target) => {
|
|
|
158
158
|
const resolveMappings = (target) => `const wrapResponse = ${isRXTarget(target) ? 'defer' : '(v: (...args: any[]) => any) => v()'};`;
|
|
159
159
|
const resolveBinaryClass = (target) => `const resolveBinaryObject = () => ${resolveBinaryType(target)};`;
|
|
160
160
|
const generateBase = (target) => {
|
|
161
|
-
return generateStatements(resolveImports(target), resolveMappings(target), resolveBinaryClass(target), types
|
|
161
|
+
return generateStatements(resolveImports(target), resolveMappings(target), resolveBinaryClass(target), types, root);
|
|
162
162
|
};
|
|
163
163
|
|
|
164
164
|
const transformKey = (s) => snakeCase(s).toUpperCase();
|
|
@@ -1165,98 +1165,9 @@ const hash = (content, algorithm = 'sha256') => {
|
|
|
1165
1165
|
return hash.digest('hex');
|
|
1166
1166
|
};
|
|
1167
1167
|
|
|
1168
|
-
var name = "@weclapp/sdk";
|
|
1169
|
-
var version = "^1.8.0";
|
|
1170
|
-
var description = "SDK generator based on a weclapp api swagger file";
|
|
1171
|
-
var author = "weclapp";
|
|
1172
|
-
var sideEffects = false;
|
|
1173
|
-
var bugs = "https://github.com/weclapp/sdk/issues";
|
|
1174
|
-
var homepage = "https://github.com/weclapp/sdk#readme";
|
|
1175
|
-
var repository = "git+https://github.com/weclapp/sdk.git";
|
|
1176
|
-
var bin = {
|
|
1177
|
-
"build-weclapp-sdk": "./bin/cli.js"
|
|
1178
|
-
};
|
|
1179
|
-
var files = [
|
|
1180
|
-
"bin",
|
|
1181
|
-
"dist",
|
|
1182
|
-
"tsconfig.lib.json"
|
|
1183
|
-
];
|
|
1184
|
-
var engines = {
|
|
1185
|
-
node: "^18 || ^20",
|
|
1186
|
-
npm: "^9 || ^8"
|
|
1187
|
-
};
|
|
1188
|
-
var types = "./sdk/dist/index.d.ts";
|
|
1189
|
-
var main = "./sdk/dist/index.cjs";
|
|
1190
|
-
var module = "./sdk/dist/index.js";
|
|
1191
|
-
var type = "module";
|
|
1192
|
-
var exports = {
|
|
1193
|
-
".": {
|
|
1194
|
-
types: "./sdk/dist/index.d.ts",
|
|
1195
|
-
"import": "./sdk/dist/index.js",
|
|
1196
|
-
require: "./sdk/dist/index.cjs"
|
|
1197
|
-
}
|
|
1198
|
-
};
|
|
1199
|
-
var scripts = {
|
|
1200
|
-
"cli:build": "cross-env NODE_ENV=production rollup -c rollup.config.js",
|
|
1201
|
-
"cli:watch": "cross-env NODE_ENV=development rollup -c rollup.config.js --watch",
|
|
1202
|
-
"sdk:build": "./bin/cli.js test/openapi.json --target node",
|
|
1203
|
-
lint: "eslint {src,test}/**/*.ts",
|
|
1204
|
-
"lint:fix": "npm run lint -- --fix",
|
|
1205
|
-
"ci:test": "npm run lint:fix && npm run cli:build && npm run sdk:build",
|
|
1206
|
-
release: "standard-version"
|
|
1207
|
-
};
|
|
1208
|
-
var devDependencies = {
|
|
1209
|
-
"@typescript-eslint/eslint-plugin": "^5.59.11",
|
|
1210
|
-
"@typescript-eslint/parser": "^5.59.11",
|
|
1211
|
-
eslint: "^8.42.0",
|
|
1212
|
-
"rollup-plugin-string": "^3.0.0",
|
|
1213
|
-
"standard-version": "^9.5.0"
|
|
1214
|
-
};
|
|
1215
|
-
var dependencies = {
|
|
1216
|
-
"@rollup/plugin-json": "^6.0.0",
|
|
1217
|
-
"@rollup/plugin-terser": "^0.4.3",
|
|
1218
|
-
"@types/fs-extra": "^11.0.1",
|
|
1219
|
-
"@types/yargs": "^17.0.24",
|
|
1220
|
-
chalk: "^5.2.0",
|
|
1221
|
-
"change-case": "^4.1.2",
|
|
1222
|
-
"cross-env": "^7.0.3",
|
|
1223
|
-
dotenv: "^16.1.4",
|
|
1224
|
-
"indent-string": "^5.0.0",
|
|
1225
|
-
"openapi-types": "^12.1.3",
|
|
1226
|
-
"pretty-ms": "^8.0.0",
|
|
1227
|
-
rollup: "^3.25.1",
|
|
1228
|
-
"rollup-plugin-ts": "^3.2.0",
|
|
1229
|
-
typescript: "^5.1.3",
|
|
1230
|
-
yargs: "^17.7.2"
|
|
1231
|
-
};
|
|
1232
|
-
var peerDependencies = {
|
|
1233
|
-
rxjs: "^7.5.5"
|
|
1234
|
-
};
|
|
1235
|
-
var pkg = {
|
|
1236
|
-
name: name,
|
|
1237
|
-
version: version,
|
|
1238
|
-
description: description,
|
|
1239
|
-
author: author,
|
|
1240
|
-
sideEffects: sideEffects,
|
|
1241
|
-
bugs: bugs,
|
|
1242
|
-
homepage: homepage,
|
|
1243
|
-
repository: repository,
|
|
1244
|
-
bin: bin,
|
|
1245
|
-
files: files,
|
|
1246
|
-
engines: engines,
|
|
1247
|
-
types: types,
|
|
1248
|
-
main: main,
|
|
1249
|
-
module: module,
|
|
1250
|
-
type: type,
|
|
1251
|
-
exports: exports,
|
|
1252
|
-
scripts: scripts,
|
|
1253
|
-
devDependencies: devDependencies,
|
|
1254
|
-
dependencies: dependencies,
|
|
1255
|
-
peerDependencies: peerDependencies
|
|
1256
|
-
};
|
|
1257
|
-
|
|
1258
1168
|
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
|
1259
1169
|
const cli = async () => {
|
|
1170
|
+
const { default: { version } } = await import('../package.json', { assert: { type: 'json' } });
|
|
1260
1171
|
const { argv } = yargs(hideBin(process.argv))
|
|
1261
1172
|
.scriptName('build-weclapp-sdk')
|
|
1262
1173
|
.usage('Usage: $0 <source> [flags]')
|
|
@@ -1325,7 +1236,7 @@ const cli = async () => {
|
|
|
1325
1236
|
return Promise.reject();
|
|
1326
1237
|
}
|
|
1327
1238
|
if (await stat(src).catch(() => false)) {
|
|
1328
|
-
logger.infoLn(`Source is a file
|
|
1239
|
+
logger.infoLn(`Source is a file.`);
|
|
1329
1240
|
const content = JSON.parse(await readFile(src, 'utf-8'));
|
|
1330
1241
|
return { cache, content, options };
|
|
1331
1242
|
}
|
|
@@ -1354,9 +1265,10 @@ const workingDirectory = resolve(currentDirname(), './sdk');
|
|
|
1354
1265
|
const folders = ['docs', 'main', 'node', 'raw', 'rx', 'utils'];
|
|
1355
1266
|
void (async () => {
|
|
1356
1267
|
const start = process.hrtime.bigint();
|
|
1268
|
+
const { default: { version } } = await import('../package.json', { assert: { type: 'json' } });
|
|
1357
1269
|
const { content: doc, cache: useCache, options } = await cli();
|
|
1358
1270
|
// Resolve cache dir and key
|
|
1359
|
-
const cacheKey = hash([
|
|
1271
|
+
const cacheKey = hash([version, JSON.stringify(doc), JSON.stringify(options)]).slice(-8);
|
|
1360
1272
|
const cacheDir = resolve(currentDirname(), '.tmp', cacheKey);
|
|
1361
1273
|
const dist = (...paths) => resolve(workingDirectory, ...paths);
|
|
1362
1274
|
const tmp = async (...paths) => {
|