@grandlinex/swagger-mate 1.3.2 → 1.3.4

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.
@@ -20,6 +20,16 @@ function isErrorType(x) {
20
20
  * @class
21
21
  */
22
22
  class BaseCon {
23
+ /**
24
+ * Initializes a new instance of the client.
25
+ *
26
+ * @param {Object} conf Configuration object.
27
+ * @param {ConHandle} conf.con - Connection handle.
28
+ * @param {string} conf.endpoint - API endpoint URL.
29
+ * @param {(arg: any) => void} [conf.logger] - Optional logger function; defaults to console.log.
30
+ * @param {Record<string, string>} [conf.permanentHeader] - Optional permanent headers to include in requests.
31
+ * @return {void}
32
+ */
23
33
  constructor(conf) {
24
34
  this.api = conf.endpoint;
25
35
  this.logger = conf.logger ?? console.log;
@@ -27,6 +37,7 @@ class BaseCon {
27
37
  this.noAuth = false;
28
38
  this.authorization = null;
29
39
  this.con = conf.con;
40
+ this.permanentHeader = conf.permanentHeader || {};
30
41
  this.reconnect = async () => {
31
42
  this.disconnected = true;
32
43
  return false;
@@ -64,12 +75,23 @@ class BaseCon {
64
75
  return (this.noAuth || this.authorization !== null) && !this.disconnected;
65
76
  }
66
77
  /**
67
- * Returns the current authorization token.
78
+ * Retrieves the current authorization token.
68
79
  *
69
- * @return {string} The authorization token or an empty string if none is set.
80
+ * @return {string|null} The token string used for authorization, or {@code null} if no token is set.
70
81
  */
71
82
  token() {
72
- return this.authorization || '';
83
+ return this.authorization;
84
+ }
85
+ /**
86
+ * Returns the bearer token string if an authorization value has been set.
87
+ *
88
+ * @return {string|null} The bearer token prefixed with "Bearer ", or {@code null} when no authorization is present.
89
+ */
90
+ getBearer() {
91
+ if (this.authorization) {
92
+ return `Bearer ${this.authorization}`;
93
+ }
94
+ return null;
73
95
  }
74
96
  p(path, config) {
75
97
  let pp = path;
@@ -108,6 +130,27 @@ class BaseCon {
108
130
  return false;
109
131
  }
110
132
  }
133
+ /**
134
+ * Builds the Authorization header for HTTP requests.
135
+ *
136
+ * If the instance has an authorization token, this method returns an object
137
+ * containing a single `Authorization` header with the Bearer token value.
138
+ * When no token is available, an empty header object is returned.
139
+ *
140
+ * @return {Record<string, string>} The headers object containing the
141
+ * `Authorization` header when applicable, otherwise an empty object.
142
+ */
143
+ tokenHeader() {
144
+ if (this.authorization) {
145
+ return {
146
+ Authorization: this.getBearer(),
147
+ };
148
+ }
149
+ return {};
150
+ }
151
+ setPermanentHeader(header) {
152
+ this.permanentHeader = header;
153
+ }
111
154
  /**
112
155
  * Validates the current authentication token by performing a ping and a test request
113
156
  * to the backend. The method first ensures connectivity via {@link ping}. If the ping
@@ -126,9 +169,7 @@ class BaseCon {
126
169
  if (ping) {
127
170
  try {
128
171
  const con = await this.con.get(this.p('/test/auth'), {
129
- headers: {
130
- Authorization: this.token(),
131
- },
172
+ headers: this.tokenHeader(),
132
173
  });
133
174
  return con.code === 200 || con.code === 201;
134
175
  }
@@ -163,18 +204,29 @@ class BaseCon {
163
204
  this.logger('cant connect to backend');
164
205
  this.authorization = null;
165
206
  this.disconnected = true;
207
+ this.noAuth = false;
166
208
  return false;
167
209
  }
168
210
  /**
169
211
  * Forces a connection using the provided bearer token.
170
212
  *
171
- * @param {string} token The token to be used for authentication.
213
+ * @param {string|null} token The token to be used for authentication.
172
214
  * @returns {void}
173
215
  */
174
- forceConnectWithToken(token) {
175
- this.authorization = `Bearer ${token}`;
216
+ forceConnect(token) {
217
+ if (token) {
218
+ this.authorization = token.replace('Bearer ', '').replace('bearer ', '');
219
+ }
220
+ else {
221
+ this.authorization = null;
222
+ }
176
223
  this.disconnected = false;
177
- this.noAuth = false;
224
+ this.noAuth = token === null;
225
+ }
226
+ coppyFrom(con) {
227
+ this.authorization = con.authorization;
228
+ this.disconnected = con.disconnected;
229
+ this.noAuth = con.noAuth;
178
230
  }
179
231
  /**
180
232
  * Establishes a connection to the backend using the supplied credentials.
@@ -202,7 +254,7 @@ class BaseCon {
202
254
  });
203
255
  if (token.code === 200 || token.code === 201) {
204
256
  if (!dry) {
205
- this.authorization = `Bearer ${token.data?.token}`;
257
+ this.authorization = token.data.token;
206
258
  this.disconnected = false;
207
259
  this.noAuth = false;
208
260
  this.reconnect = async () => {
@@ -267,7 +319,7 @@ class BaseCon {
267
319
  dat = await this.con.get(this.p(path, config), {
268
320
  ...config,
269
321
  headers: {
270
- Authorization: this.token(),
322
+ ...this.tokenHeader(),
271
323
  ...formHeader,
272
324
  ...config?.headers,
273
325
  ...this.permanentHeader,
@@ -278,7 +330,7 @@ class BaseCon {
278
330
  dat = await this.con.post(this.p(path, config), body, {
279
331
  ...config,
280
332
  headers: {
281
- Authorization: this.token(),
333
+ ...this.tokenHeader(),
282
334
  ...formHeader,
283
335
  ...config?.headers,
284
336
  ...this.permanentHeader,
@@ -289,7 +341,7 @@ class BaseCon {
289
341
  dat = await this.con.patch(this.p(path, config), body, {
290
342
  ...config,
291
343
  headers: {
292
- Authorization: this.token(),
344
+ ...this.tokenHeader(),
293
345
  ...formHeader,
294
346
  ...config?.headers,
295
347
  ...this.permanentHeader,
@@ -300,7 +352,7 @@ class BaseCon {
300
352
  dat = await this.con.delete(this.p(path, config), {
301
353
  ...config,
302
354
  headers: {
303
- Authorization: this.token(),
355
+ ...this.tokenHeader(),
304
356
  ...formHeader,
305
357
  ...config?.headers,
306
358
  ...this.permanentHeader,
@@ -1,6 +1,7 @@
1
1
  import SwaggerUtil from './Swagger/SwaggerUtil.js';
2
2
  import SPathUtil from './Swagger/Path/SPathUtil.js';
3
3
  import SwaggerClient from './Swagger/Client/SwaggerClient.js';
4
+ export * from './Swagger/Path/ESchemaEditor.js';
4
5
  export * from './Swagger/debug/index.js';
5
6
  export * from './Swagger/annotation/index.js';
6
7
  export * from './Swagger/Meta/Swagger.js';
package/dist/cjs/index.js CHANGED
@@ -24,6 +24,7 @@ const SPathUtil_js_1 = __importDefault(require("./Swagger/Path/SPathUtil.js"));
24
24
  exports.SPathUtil = SPathUtil_js_1.default;
25
25
  const SwaggerClient_js_1 = __importDefault(require("./Swagger/Client/SwaggerClient.js"));
26
26
  exports.SwaggerClient = SwaggerClient_js_1.default;
27
+ __exportStar(require("./Swagger/Path/ESchemaEditor.js"), exports);
27
28
  __exportStar(require("./Swagger/debug/index.js"), exports);
28
29
  __exportStar(require("./Swagger/annotation/index.js"), exports);
29
30
  __exportStar(require("./Swagger/Meta/Swagger.js"), exports);
@@ -56,7 +56,7 @@ export interface SwaggerRInfo {
56
56
  version: string;
57
57
  license?: SwaggerRInfoLicence;
58
58
  }
59
- export type SSchemaEl = {
59
+ export type SSchemaElObj = {
60
60
  type: SDataType;
61
61
  example?: string;
62
62
  format?: SDataFormat;
@@ -68,7 +68,8 @@ export type SSchemaEl = {
68
68
  required?: string[];
69
69
  enum?: string[];
70
70
  nullable?: boolean;
71
- } | SwaggerRRef;
71
+ };
72
+ export type SSchemaEl = SSchemaElObj | SwaggerRRef;
72
73
  export type SwaggerContent = {
73
74
  [K in SMediaType]?: {
74
75
  schema: SSchemaEl;
@@ -0,0 +1,51 @@
1
+ import { CoreEntity } from '@grandlinex/core';
2
+ import { SKey, SSchemaEl, SSchemaElObj } from '../Meta/SwaggerTypes.js';
3
+ export type ESchemaAddOption = {
4
+ key: string;
5
+ list?: boolean;
6
+ entity?: CoreEntity;
7
+ schema?: SSchemaEl;
8
+ required?: boolean;
9
+ nullable?: boolean;
10
+ };
11
+ export declare class ESchemaEditor<T extends CoreEntity> {
12
+ private data;
13
+ private name;
14
+ private constructor();
15
+ /**
16
+ * Removes the specified keys from the schema's properties and updates the required list.
17
+ *
18
+ * @param {...(keyof T)} keys - The keys of the properties to remove.
19
+ * @returns {ESchemaEditor<T>} The editor instance for method chaining.
20
+ */
21
+ remove(...keys: (keyof T)[]): ESchemaEditor<T>;
22
+ /**
23
+ * Adds properties to the schema based on the provided options.
24
+ *
25
+ * @param {...ESchemaAddOption} options The options describing the properties to add. Each option may specify a
26
+ * `key`, a `schema` or an `entity`, and optionally whether the property is a `list`, `nullable`, or `required`.
27
+ * @returns {ESchemaEditor<T>} The editor instance for chaining.
28
+ */
29
+ add(...options: ESchemaAddOption[]): ESchemaEditor<T>;
30
+ getSchema(): SSchemaElObj;
31
+ getSKeySchema(): SKey<SSchemaElObj>;
32
+ static fromEntity<J extends CoreEntity>(e: J): ESchemaEditor<J>;
33
+ /**
34
+ * Generates a JSON schema representation from a CoreEntity instance.
35
+ *
36
+ * This method inspects the entity's metadata to construct a schema object
37
+ * describing the entity's shape. The resulting schema contains:
38
+ * - `type`: always `"object"`.
39
+ * - `description`: a string indicating the entity name.
40
+ * - `required`: an array of property names that are defined on the entity.
41
+ * - `properties`: an object mapping each property name to an object that
42
+ * includes the resolved database type and its nullability.
43
+ *
44
+ * If no metadata is found for the provided entity, the method returns `undefined`.
45
+ *
46
+ * @param {T} entity - The entity instance for which to create a schema.
47
+ * @returns {SSchemaElObj | undefined} The generated schema object, or `undefined`
48
+ * if the entity's metadata could not be retrieved.
49
+ */
50
+ static schemaFromEntity<T extends CoreEntity>(entity: T): SSchemaElObj | undefined;
51
+ }
@@ -0,0 +1,147 @@
1
+ import { getColumnMeta, getEntityMeta, } from '@grandlinex/core';
2
+ function resolveDBType(dType) {
3
+ switch (dType) {
4
+ case 'int':
5
+ case 'long':
6
+ return 'integer';
7
+ case 'double':
8
+ case 'float':
9
+ return 'number';
10
+ case 'blob':
11
+ return 'string';
12
+ case 'string':
13
+ case 'text':
14
+ case 'uuid':
15
+ return 'string';
16
+ case 'boolean':
17
+ return 'boolean';
18
+ case 'date':
19
+ return 'string';
20
+ case 'json':
21
+ return 'object';
22
+ default:
23
+ throw Error('TypeNotSupported');
24
+ }
25
+ }
26
+ export class ESchemaEditor {
27
+ constructor(entity, name) {
28
+ this.data = ESchemaEditor.schemaFromEntity(entity);
29
+ this.name = name;
30
+ }
31
+ /**
32
+ * Removes the specified keys from the schema's properties and updates the required list.
33
+ *
34
+ * @param {...(keyof T)} keys - The keys of the properties to remove.
35
+ * @returns {ESchemaEditor<T>} The editor instance for method chaining.
36
+ */
37
+ remove(...keys) {
38
+ if (this.data.properties) {
39
+ for (const key of keys) {
40
+ this.data.properties = Object.fromEntries(Object.entries(this.data.properties).filter(([e]) => key !== e));
41
+ this.data.required = (this.data.required || []).filter((e) => key !== e);
42
+ }
43
+ }
44
+ return this;
45
+ }
46
+ /**
47
+ * Adds properties to the schema based on the provided options.
48
+ *
49
+ * @param {...ESchemaAddOption} options The options describing the properties to add. Each option may specify a
50
+ * `key`, a `schema` or an `entity`, and optionally whether the property is a `list`, `nullable`, or `required`.
51
+ * @returns {ESchemaEditor<T>} The editor instance for chaining.
52
+ */
53
+ add(...options) {
54
+ if (!this.data.properties) {
55
+ return this;
56
+ }
57
+ for (const option of options) {
58
+ if (option.schema) {
59
+ if (option.list) {
60
+ this.data.properties[option.key] = {
61
+ type: 'array',
62
+ items: option.schema,
63
+ nullable: option.nullable,
64
+ };
65
+ }
66
+ else {
67
+ this.data.properties[option.key] = option.schema;
68
+ }
69
+ }
70
+ else if (option.entity) {
71
+ const scheme = ESchemaEditor.fromEntity(option.entity).getSchema();
72
+ if (option.nullable) {
73
+ scheme.nullable = true;
74
+ }
75
+ if (option.list) {
76
+ this.data.properties[option.key] = {
77
+ type: 'array',
78
+ items: scheme,
79
+ };
80
+ }
81
+ else {
82
+ this.data.properties[option.key] = scheme;
83
+ }
84
+ }
85
+ if (option.required) {
86
+ this.data.required = [...(this.data.required || []), option.key];
87
+ }
88
+ }
89
+ return this;
90
+ }
91
+ getSchema() {
92
+ return this.data;
93
+ }
94
+ getSKeySchema() {
95
+ return {
96
+ [this.name]: this.data,
97
+ };
98
+ }
99
+ static fromEntity(e) {
100
+ const meta = getEntityMeta(e);
101
+ if (meta) {
102
+ return new ESchemaEditor(e, meta.name);
103
+ }
104
+ throw new Error('Entity metadata not found');
105
+ }
106
+ /**
107
+ * Generates a JSON schema representation from a CoreEntity instance.
108
+ *
109
+ * This method inspects the entity's metadata to construct a schema object
110
+ * describing the entity's shape. The resulting schema contains:
111
+ * - `type`: always `"object"`.
112
+ * - `description`: a string indicating the entity name.
113
+ * - `required`: an array of property names that are defined on the entity.
114
+ * - `properties`: an object mapping each property name to an object that
115
+ * includes the resolved database type and its nullability.
116
+ *
117
+ * If no metadata is found for the provided entity, the method returns `undefined`.
118
+ *
119
+ * @param {T} entity - The entity instance for which to create a schema.
120
+ * @returns {SSchemaElObj | undefined} The generated schema object, or `undefined`
121
+ * if the entity's metadata could not be retrieved.
122
+ */
123
+ static schemaFromEntity(entity) {
124
+ const schema = {
125
+ type: 'object',
126
+ properties: {},
127
+ };
128
+ const meta = getEntityMeta(entity);
129
+ if (!meta) {
130
+ return undefined;
131
+ }
132
+ schema.description = `Entity: ${meta.name}`;
133
+ schema.required = [];
134
+ const keys = Object.keys(entity);
135
+ keys.forEach((k) => {
136
+ const cMeta = getColumnMeta(entity, k);
137
+ if (cMeta && schema.properties) {
138
+ schema.required.push(k);
139
+ schema.properties[k] = {
140
+ type: resolveDBType(cMeta.dataType),
141
+ nullable: cMeta.canBeNull,
142
+ };
143
+ }
144
+ });
145
+ return schema;
146
+ }
147
+ }
@@ -1,6 +1,7 @@
1
1
  import { CoreEntity } from '@grandlinex/core';
2
2
  import { HttpStatusTypes } from '../Meta/SwaggerTypesStatic.js';
3
- import { SKey, SSchemaEl, SwaggerContent, SwaggerRPathConfResponse, SwaggerRPathReqBody } from '../Meta/SwaggerTypes.js';
3
+ import { SKey, SSchemaEl, SSchemaElObj, SwaggerContent, SwaggerRPathConfResponse, SwaggerRPathReqBody } from '../Meta/SwaggerTypes.js';
4
+ import { ESchemaEditor } from './ESchemaEditor.js';
4
5
  export default class SPathUtil {
5
6
  /**
6
7
  * Generates a default response mapping for the specified HTTP status types.
@@ -90,10 +91,11 @@ export default class SPathUtil {
90
91
  * If no metadata is found for the provided entity, the method returns `undefined`.
91
92
  *
92
93
  * @param {T} entity - The entity instance for which to create a schema.
93
- * @returns {SSchemaEl | undefined} The generated schema object, or `undefined`
94
+ * @returns {SSchemaElObj | undefined} The generated schema object, or `undefined`
94
95
  * if the entity's metadata could not be retrieved.
96
+ * @deprecated Use {@link ESchemaEditor.schemaFromEntity} instead.
95
97
  */
96
- static schemaFromEntity<T extends CoreEntity>(entity: T): SSchemaEl | undefined;
98
+ static schemaFromEntity<T extends CoreEntity>(entity: T): SSchemaElObj | undefined;
97
99
  /**
98
100
  * Generates a content schema object for the given entity. The schema contains a description derived from the entity metadata and a JSON content schema based on the entity's structure.
99
101
  *
@@ -114,7 +116,7 @@ export default class SPathUtil {
114
116
  * @param {CoreEntity[]} e The entities for which schema entries should be generated.
115
117
  * @return {SKey<SSchemaEl>} An object whose keys are entity names and values are the schemas derived from those entities.
116
118
  */
117
- static schemaEntryGen(...e: CoreEntity[]): SKey<SSchemaEl>;
119
+ static schemaEntryGen(...e: CoreEntity[]): SKey<SSchemaElObj>;
118
120
  /**
119
121
  * Builds a JSON schema representation for an entity view that includes both the
120
122
  * entity data and its related entity map.
@@ -124,76 +126,5 @@ export default class SPathUtil {
124
126
  * @returns A {@link SSchemaEl} object schema with properties `i`, `dat`, and `join_map`.
125
127
  */
126
128
  static schemaFromEntityView<A extends CoreEntity, B extends CoreEntity>(entity: A, entityMap: B): SSchemaEl;
127
- /**
128
- * Extends an entity schema object by merging additional schema options.
129
- *
130
- * @param {CoreEntity} entity
131
- * The entity for which the schema should be extended.
132
- *
133
- * @param {...Object} options
134
- * One or more objects defining schema extensions. Each object may contain:
135
- * - `key` (string): The property key to add or extend.
136
- * - `list` (boolean, optional): Indicates whether the property is a list.
137
- * - `entity` (CoreEntity, optional): The entity type for the property.
138
- * - `schema` (SSchemaEl, optional): A custom schema definition for the property.
139
- * - `required` (boolean, optional): Whether the property is required.
140
- *
141
- * @return {SSchemaEl}
142
- * The resulting schema element. If a single property is returned by
143
- * `extendEntitySchema`, its schema is returned directly; otherwise an
144
- * object schema with a type of `'object'` is returned.
145
- */
146
- static extendEntitySchemaObject(entity: CoreEntity, ...options: {
147
- key: string;
148
- list?: boolean;
149
- entity?: CoreEntity;
150
- schema?: SSchemaEl;
151
- required?: boolean;
152
- }[]): SSchemaEl;
153
- /**
154
- * Extends the schema of a given {@link CoreEntity} with additional properties.
155
- *
156
- * @param {CoreEntity} entity
157
- * The entity whose schema will be extended.
158
- *
159
- * @param {...{
160
- * key: string,
161
- * list?: boolean,
162
- * entity?: CoreEntity,
163
- * schema?: SSchemaEl,
164
- * required?: boolean
165
- * }} options
166
- * One or more option objects specifying the extensions to apply. Each option
167
- * may provide either a direct schema (`schema`) or an entity reference
168
- * (`entity`). The `list` flag indicates whether the property should be
169
- * represented as an array of the provided schema. The `required` flag
170
- * adds the property to the schema’s required list.
171
- *
172
- * @returns {SKey<SSchemaEl>}
173
- * An object containing the updated schema for the entity, keyed by the
174
- * entity’s name. If the entity metadata cannot be found, an empty
175
- * object is returned.
176
- */
177
- static extendEntitySchema(entity: CoreEntity, ...options: {
178
- key: string;
179
- list?: boolean;
180
- entity?: CoreEntity;
181
- schema?: SSchemaEl;
182
- required?: boolean;
183
- }[]): SKey<SSchemaEl>;
184
- /**
185
- * Reduces the entity schema to a single schema element or a generic object.
186
- *
187
- * @param entity The entity whose schema should be reduced.
188
- * @param keys Optional list of keys to include in the reduced schema. If omitted, all keys are considered.
189
- * @return Returns the schema element of the sole key if only one key is present; otherwise, returns a generic object schema with type `'object'`. */
190
- static reduceEntitySchemaObject<T extends CoreEntity>(entity: T, ...keys: (keyof T)[]): SSchemaEl;
191
- /**
192
- * Creates a reduced version of an entity's schema by excluding specified properties.
193
- *
194
- * @param {CoreEntity} entity - The entity whose schema is to be processed.
195
- * @param {...string} keys - Property names to remove from the schema's `properties` and `required` lists.
196
- *
197
- * @returns */
198
- static reduceEntitySchema<T extends CoreEntity>(entity: T, ...keys: (keyof T)[]): SKey<SSchemaEl>;
129
+ static editor<J extends CoreEntity>(e: J): ESchemaEditor<J>;
199
130
  }