@promptbook/remote-server 0.89.0-6 → 0.89.0-7

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.
@@ -25,9 +25,10 @@ import { DEFAULT_BOOKS_DIRNAME } from '../config';
25
25
  import { DEFAULT_DOWNLOAD_CACHE_DIRNAME } from '../config';
26
26
  import { DEFAULT_EXECUTION_CACHE_DIRNAME } from '../config';
27
27
  import { DEFAULT_SCRAPE_CACHE_DIRNAME } from '../config';
28
+ import { CLI_APP_ID } from '../config';
29
+ import { PLAYGROUND_APP_ID } from '../config';
28
30
  import { DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME } from '../config';
29
- import { DEFAULT_REMOTE_URL } from '../config';
30
- import { DEFAULT_REMOTE_URL_PATH } from '../config';
31
+ import { DEFAULT_REMOTE_SERVER_URL } from '../config';
31
32
  import { DEFAULT_CSV_SETTINGS } from '../config';
32
33
  import { DEFAULT_IS_VERBOSE } from '../config';
33
34
  import { SET_IS_VERBOSE } from '../config';
@@ -46,6 +47,7 @@ import type { CallbackInterfaceToolsOptions } from '../dialogs/callback/Callback
46
47
  import { BoilerplateError } from '../errors/0-BoilerplateError';
47
48
  import { PROMPTBOOK_ERRORS } from '../errors/0-index';
48
49
  import { AbstractFormatError } from '../errors/AbstractFormatError';
50
+ import { AuthenticationError } from '../errors/AuthenticationError';
49
51
  import { CollectionError } from '../errors/CollectionError';
50
52
  import { EnvironmentMismatchError } from '../errors/EnvironmentMismatchError';
51
53
  import { ExpectError } from '../errors/ExpectError';
@@ -157,9 +159,10 @@ export { DEFAULT_BOOKS_DIRNAME };
157
159
  export { DEFAULT_DOWNLOAD_CACHE_DIRNAME };
158
160
  export { DEFAULT_EXECUTION_CACHE_DIRNAME };
159
161
  export { DEFAULT_SCRAPE_CACHE_DIRNAME };
162
+ export { CLI_APP_ID };
163
+ export { PLAYGROUND_APP_ID };
160
164
  export { DEFAULT_PIPELINE_COLLECTION_BASE_FILENAME };
161
- export { DEFAULT_REMOTE_URL };
162
- export { DEFAULT_REMOTE_URL_PATH };
165
+ export { DEFAULT_REMOTE_SERVER_URL };
163
166
  export { DEFAULT_CSV_SETTINGS };
164
167
  export { DEFAULT_IS_VERBOSE };
165
168
  export { SET_IS_VERBOSE };
@@ -178,6 +181,7 @@ export type { CallbackInterfaceToolsOptions };
178
181
  export { BoilerplateError };
179
182
  export { PROMPTBOOK_ERRORS };
180
183
  export { AbstractFormatError };
184
+ export { AuthenticationError };
181
185
  export { CollectionError };
182
186
  export { EnvironmentMismatchError };
183
187
  export { ExpectError };
@@ -6,7 +6,6 @@ import type { PromptbookServer_Identification } from '../remote-server/socket-ty
6
6
  import type { PromptbookServer_ApplicationIdentification } from '../remote-server/socket-types/_subtypes/PromptbookServer_Identification';
7
7
  import type { PromptbookServer_AnonymousIdentification } from '../remote-server/socket-types/_subtypes/PromptbookServer_Identification';
8
8
  import type { RemoteClientOptions } from '../remote-server/types/RemoteClientOptions';
9
- import type { RemoteServerOptions } from '../remote-server/types/RemoteServerOptions';
10
9
  export { BOOK_LANGUAGE_VERSION, PROMPTBOOK_ENGINE_VERSION };
11
10
  export { compilePipelineOnRemoteServer };
12
11
  export { RemoteLlmExecutionTools };
@@ -15,4 +14,3 @@ export type { PromptbookServer_Identification };
15
14
  export type { PromptbookServer_ApplicationIdentification };
16
15
  export type { PromptbookServer_AnonymousIdentification };
17
16
  export type { RemoteClientOptions };
18
- export type { RemoteServerOptions };
@@ -0,0 +1,7 @@
1
+ import { Command } from 'commander';
2
+ /**
3
+ * Note: `$` is used to indicate that this function is not a pure function - it registers an option in the CLI
4
+ *
5
+ * @private utility of CLI
6
+ */
7
+ export declare function $addGlobalOptionsToCommand(command: Command): void;
@@ -0,0 +1,15 @@
1
+ import type { CacheLlmToolsOptions } from '../../llm-providers/_common/utils/cache/CacheLlmToolsOptions';
2
+ import type { string_url } from '../../types/typeAliases';
3
+ type ProvideLlmToolsForCliOptions = Pick<CacheLlmToolsOptions, 'isCacheReloaded'> & {
4
+ cliOptions: {
5
+ verbose: boolean;
6
+ interactive: boolean;
7
+ provider: 'BYOK' | 'BRING_YOUR_OWN_KEYS' | 'REMOTE_SERVER' | 'RS' | string;
8
+ remoteServerUrl: string_url;
9
+ };
10
+ };
11
+ /**
12
+ * @private utility of CLI
13
+ */
14
+ export declare function $provideLlmToolsForCli(options: ProvideLlmToolsForCliOptions): Promise<import("../../_packages/types.index").LlmExecutionToolsWithTotalUsage>;
15
+ export {};
@@ -1,5 +1,6 @@
1
1
  import type { CsvSettings } from './formats/csv/CsvSettings';
2
2
  import type { IntermediateFilesStrategy } from './types/IntermediateFilesStrategy';
3
+ import type { string_app_id } from './types/typeAliases';
3
4
  import type { string_email } from './types/typeAliases';
4
5
  import type { string_name } from './types/typeAliases';
5
6
  import type { string_url_image } from './types/typeAliases';
@@ -208,6 +209,18 @@ export declare const DEFAULT_EXECUTION_CACHE_DIRNAME = "./.promptbook/execution-
208
209
  * @public exported from `@promptbook/core`
209
210
  */
210
211
  export declare const DEFAULT_SCRAPE_CACHE_DIRNAME = "./.promptbook/scrape-cache";
212
+ /**
213
+ * Id of application for the CLI when using remote server
214
+ *
215
+ * @public exported from `@promptbook/core`
216
+ */
217
+ export declare const CLI_APP_ID: string_app_id;
218
+ /**
219
+ * Id of application for the playground
220
+ *
221
+ * @public exported from `@promptbook/core`
222
+ */
223
+ export declare const PLAYGROUND_APP_ID: string_app_id;
211
224
  /**
212
225
  * The name of the builded pipeline collection made by CLI `ptbk make` and for lookup in `createCollectionFromDirectory`
213
226
  *
@@ -228,13 +241,7 @@ export declare const MOMENT_ARG_THRESHOLDS: {
228
241
  *
229
242
  * @public exported from `@promptbook/core`
230
243
  */
231
- export declare const DEFAULT_REMOTE_URL = "https://api.pavolhejny.com/";
232
- /**
233
- * @@@
234
- *
235
- * @public exported from `@promptbook/core`
236
- */
237
- export declare const DEFAULT_REMOTE_URL_PATH = "/promptbook/socket.io";
244
+ export declare const DEFAULT_REMOTE_SERVER_URL = "https://api.pavolhejny.com/promptbook";
238
245
  /**
239
246
  * @@@
240
247
  *
@@ -281,5 +288,5 @@ export declare const IS_PIPELINE_LOGIC_VALIDATED: boolean;
281
288
  export declare const IS_COST_PREVENTED: boolean;
282
289
  /**
283
290
  * Note: [💞] Ignore a discrepancy between file name and entity name
284
- * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
291
+ * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value
285
292
  */
@@ -1,5 +1,6 @@
1
1
  import { CsvFormatError } from '../formats/csv/CsvFormatError';
2
2
  import { AbstractFormatError } from './AbstractFormatError';
3
+ import { AuthenticationError } from './AuthenticationError';
3
4
  import { CollectionError } from './CollectionError';
4
5
  import { EnvironmentMismatchError } from './EnvironmentMismatchError';
5
6
  import { ExpectError } from './ExpectError';
@@ -49,6 +50,7 @@ export declare const COMMON_JAVASCRIPT_ERRORS: {
49
50
  readonly TypeError: TypeErrorConstructor;
50
51
  readonly URIError: URIErrorConstructor;
51
52
  readonly AggregateError: AggregateErrorConstructor;
53
+ readonly AuthenticationError: typeof AuthenticationError;
52
54
  };
53
55
  /**
54
56
  * Index of all errors
@@ -64,6 +66,7 @@ export declare const ALL_ERRORS: {
64
66
  readonly TypeError: TypeErrorConstructor;
65
67
  readonly URIError: URIErrorConstructor;
66
68
  readonly AggregateError: AggregateErrorConstructor;
69
+ readonly AuthenticationError: typeof AuthenticationError;
67
70
  readonly AbstractFormatError: typeof AbstractFormatError;
68
71
  readonly CsvFormatError: typeof CsvFormatError;
69
72
  readonly CollectionError: typeof CollectionError;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * AuthenticationError is thrown from login function which is dependency of remote server
3
+ *
4
+ * @public exported from `@promptbook/core`
5
+ */
6
+ export declare class AuthenticationError extends Error {
7
+ readonly name = "AuthenticationError";
8
+ constructor(message: string);
9
+ }
@@ -1,11 +1,44 @@
1
+ import { Promisable } from 'type-fest';
2
+ import type { PromptbookServer_Identification } from '../../../remote-server/socket-types/_subtypes/PromptbookServer_Identification';
3
+ import type { really_any } from '../../../utils/organization/really_any';
4
+ import type { string_app_id } from '../../../types/typeAliases';
5
+ import type { string_url } from '../../../types/typeAliases';
1
6
  import type { CacheLlmToolsOptions } from '../utils/cache/CacheLlmToolsOptions';
2
7
  import type { LlmExecutionToolsWithTotalUsage } from '../utils/count-total-usage/LlmExecutionToolsWithTotalUsage';
8
+ type ProvideLlmToolsForWizzardOrCliOptions = Pick<CacheLlmToolsOptions, 'isCacheReloaded'> & ({
9
+ /**
10
+ * Use local keys and execute LLMs directly
11
+ */
12
+ readonly strategy: 'BRING_YOUR_OWN_KEYS';
13
+ } | {
14
+ /**
15
+ * Do not use local keys but login to Promptbook server and execute LLMs there
16
+ */
17
+ readonly strategy: 'REMOTE_SERVER';
18
+ /**
19
+ * URL of the remote server
20
+ *
21
+ * @default `DEFAULT_REMOTE_SERVER_URL`
22
+ */
23
+ readonly remoteServerUrl?: string_url;
24
+ /**
25
+ * Identifier of the application which will be passed to the remote server identification
26
+ *
27
+ * Note: This can be some id or some semantic name like "email-agent"
28
+ */
29
+ readonly appId: string_app_id;
30
+ /**
31
+ *
32
+ */
33
+ loginPrompt(): Promisable<PromptbookServer_Identification<really_any>>;
34
+ });
3
35
  /**
4
36
  * Returns LLM tools for CLI
5
37
  *
6
38
  * @private within the repository - for CLI utils
7
39
  */
8
- export declare function $provideLlmToolsForWizzardOrCli(options?: Pick<CacheLlmToolsOptions, 'isCacheReloaded'>): Promise<LlmExecutionToolsWithTotalUsage>;
40
+ export declare function $provideLlmToolsForWizzardOrCli(options?: ProvideLlmToolsForWizzardOrCliOptions): Promise<LlmExecutionToolsWithTotalUsage>;
41
+ export {};
9
42
  /**
10
43
  * Note: [🟢] Code in this file should never be never released in packages that could be imported into browser environment
11
44
  * TODO: [👷‍♂️] @@@ Manual about construction of llmTools
@@ -25,7 +25,7 @@ export type AnthropicClaudeExecutionToolsDirectOptions = CommonToolsOptions & Cl
25
25
  */
26
26
  export type AnthropicClaudeExecutionToolsProxiedOptions = CommonToolsOptions & ClientOptions & {
27
27
  isProxied: true;
28
- } & Pick<RemoteClientOptions<undefined>, 'remoteUrl' | 'path'>;
28
+ } & Pick<RemoteClientOptions<undefined>, 'remoteServerUrl'>;
29
29
  /**
30
30
  * TODO: [🧠][🤺] Pass `userId`
31
31
  */
@@ -11,4 +11,4 @@ import type { Registration } from '../../utils/$Register';
11
11
  export declare const _AnthropicClaudeMetadataRegistration: Registration;
12
12
  /**
13
13
  * Note: [💞] Ignore a discrepancy between file name and entity name
14
- */
14
+ */
@@ -1,6 +1,5 @@
1
1
  import type { CommonToolsOptions } from '../../execution/CommonToolsOptions';
2
2
  import type { string_base_url } from '../../types/typeAliases';
3
- import type { string_uri } from '../../types/typeAliases';
4
3
  import type { PromptbookServer_Identification } from '../socket-types/_subtypes/PromptbookServer_Identification';
5
4
  /**
6
5
  * Options for `RemoteLlmExecutionTools`
@@ -12,14 +11,7 @@ export type RemoteClientOptions<TCustomOptions> = CommonToolsOptions & {
12
11
  * URL of the remote server
13
12
  * On this server will be connected to the socket.io server
14
13
  */
15
- readonly remoteUrl: string_base_url;
16
- /**
17
- * Path for the Socket.io server to listen
18
- *
19
- * @default '/socket.io'
20
- * @example '/promptbook/socket.io'
21
- */
22
- readonly path: string_uri;
14
+ readonly remoteServerUrl: string_base_url;
23
15
  /**
24
16
  * Identification of client for Socket.io remote server
25
17
  */
@@ -28,5 +20,5 @@ export type RemoteClientOptions<TCustomOptions> = CommonToolsOptions & {
28
20
  /**
29
21
  * TODO: Pass more options from Socket.io to `RemoteClientOptions` (like `transports`)
30
22
  * TODO: [🧠][🛍] Maybe not `isAnonymous: boolean` BUT `mode: 'ANONYMOUS'|'COLLECTION'`
31
- * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
23
+ * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value
32
24
  */
@@ -3,8 +3,11 @@ import type { PipelineCollection } from '../../collection/PipelineCollection';
3
3
  import type { CommonToolsOptions } from '../../execution/CommonToolsOptions';
4
4
  import type { LlmExecutionTools } from '../../execution/LlmExecutionTools';
5
5
  import type { string_app_id } from '../../types/typeAliases';
6
+ import type { string_email } from '../../types/typeAliases';
7
+ import type { string_password } from '../../types/typeAliases';
6
8
  import type { string_uri } from '../../types/typeAliases';
7
9
  import type { string_user_id } from '../../types/typeAliases';
10
+ import type { PromptbookServer_Identification } from '../socket-types/_subtypes/PromptbookServer_Identification';
8
11
  /**
9
12
  * @@@
10
13
  *
@@ -16,7 +19,6 @@ import type { string_user_id } from '../../types/typeAliases';
16
19
  *
17
20
  * You can enable both modes at the same time.
18
21
  *
19
- * @public exported from `@promptbook/remote-client`
20
22
  * @public exported from `@promptbook/remote-server`
21
23
  */
22
24
  export type RemoteServerOptions<TCustomOptions> = CommonToolsOptions & {
@@ -32,7 +34,7 @@ export type RemoteServerOptions<TCustomOptions> = CommonToolsOptions & {
32
34
  * @default '/'
33
35
  * @example '/api/promptbook/'
34
36
  */
35
- readonly rootPath: string_uri;
37
+ readonly rootPath?: string_uri;
36
38
  } & (AnonymousRemoteServerOptions | ApplicationRemoteServerOptions<TCustomOptions> | (AnonymousRemoteServerOptions & ApplicationRemoteServerOptions<TCustomOptions>));
37
39
  export type AnonymousRemoteServerOptions = {
38
40
  /**
@@ -51,6 +53,32 @@ export type ApplicationRemoteServerOptions<TCustomOptions> = {
51
53
  * This is used to check validity of the prompt to prevent misuse
52
54
  */
53
55
  readonly collection: PipelineCollection;
56
+ /**
57
+ * User tries to login to the server, this function will be called verify the user and return the identification or throw an error
58
+ *
59
+ *
60
+ * Note: In most cases, you will return `PromptbookServer_ApplicationIdentification`
61
+ * `PromptbookServer_AnonymousIdentification` is useful only in scenarios when user stores its own api keys on the application server and
62
+ * server acts only as a api key provider
63
+ *
64
+ * @throws `AuthenticationError` if the user is not allowed to login for example because of invalid credentials
65
+ */
66
+ login(credentials: {
67
+ /**
68
+ * Identifier of the application you are using
69
+ *
70
+ * Note: This is usefull when you use Promptbook remote server for multiple apps/frontends, if its used just for single app, use here just "app" or "your-app-name"
71
+ */
72
+ readonly appId: string_app_id | null;
73
+ /**
74
+ * Username (for example email) of the user
75
+ */
76
+ readonly username: string_email | string;
77
+ /**
78
+ * Password of the user
79
+ */
80
+ readonly password: string_password;
81
+ }): Promise<PromptbookServer_Identification<TCustomOptions>>;
54
82
  /**
55
83
  * Creates llm execution tools for each client
56
84
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptbook/remote-server",
3
- "version": "0.89.0-6",
3
+ "version": "0.89.0-7",
4
4
  "description": "It's time for a paradigm shift. The future of software in plain English, French or Latin",
5
5
  "private": false,
6
6
  "sideEffects": false,
@@ -47,7 +47,7 @@
47
47
  "module": "./esm/index.es.js",
48
48
  "typings": "./esm/typings/src/_packages/remote-server.index.d.ts",
49
49
  "peerDependencies": {
50
- "@promptbook/core": "0.89.0-6"
50
+ "@promptbook/core": "0.89.0-7"
51
51
  },
52
52
  "dependencies": {
53
53
  "colors": "1.4.0",
package/umd/index.umd.js CHANGED
@@ -30,7 +30,7 @@
30
30
  * @generated
31
31
  * @see https://github.com/webgptorg/promptbook
32
32
  */
33
- const PROMPTBOOK_ENGINE_VERSION = '0.89.0-6';
33
+ const PROMPTBOOK_ENGINE_VERSION = '0.89.0-7';
34
34
  /**
35
35
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
36
36
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -155,6 +155,7 @@
155
155
  */
156
156
  const DEFAULT_MAX_EXECUTION_ATTEMPTS = 10; // <- TODO: [🤹‍♂️]
157
157
  // <- TODO: [🕝] Make also `BOOKS_DIRNAME_ALTERNATIVES`
158
+ // TODO: !!!!!! Just .promptbook dir, hardocode others
158
159
  /**
159
160
  * Where to store the temporary downloads
160
161
  *
@@ -206,9 +207,22 @@
206
207
  true);
207
208
  /**
208
209
  * Note: [💞] Ignore a discrepancy between file name and entity name
209
- * TODO: [🧠][🧜‍♂️] Maybe join remoteUrl and path into single value
210
+ * TODO: [🧠][🧜‍♂️] Maybe join remoteServerUrl and path into single value
210
211
  */
211
212
 
213
+ /**
214
+ * AuthenticationError is thrown from login function which is dependency of remote server
215
+ *
216
+ * @public exported from `@promptbook/core`
217
+ */
218
+ class AuthenticationError extends Error {
219
+ constructor(message) {
220
+ super(message);
221
+ this.name = 'AuthenticationError';
222
+ Object.setPrototypeOf(this, AuthenticationError.prototype);
223
+ }
224
+ }
225
+
212
226
  /**
213
227
  * Generates random token
214
228
  *
@@ -542,6 +556,7 @@
542
556
  TypeError,
543
557
  URIError,
544
558
  AggregateError,
559
+ AuthenticationError,
545
560
  /*
546
561
  Note: Not widely supported
547
562
  > InternalError,
@@ -577,6 +592,10 @@
577
592
 
578
593
  Cannot serialize error with name "${name}"
579
594
 
595
+ Authors of Promptbook probably forgot to add this error into the list of errors:
596
+ https://github.com/webgptorg/promptbook/blob/main/src/errors/0-index.ts
597
+
598
+
580
599
  ${block(stack || message)}
581
600
 
582
601
  `));
@@ -6710,11 +6729,12 @@
6710
6729
  * @public exported from `@promptbook/remote-server`
6711
6730
  */
6712
6731
  function startRemoteServer(options) {
6713
- const { port, collection, createLlmExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, } = {
6732
+ const { port, collection, createLlmExecutionTools, isAnonymousModeAllowed, isApplicationModeAllowed, isVerbose = DEFAULT_IS_VERBOSE, login, } = {
6714
6733
  isAnonymousModeAllowed: false,
6715
6734
  isApplicationModeAllowed: false,
6716
6735
  collection: null,
6717
6736
  createLlmExecutionTools: null,
6737
+ login: null,
6718
6738
  ...options,
6719
6739
  };
6720
6740
  // <- TODO: [🦪] Some helper type to be able to use discriminant union types with destructuring
@@ -6792,13 +6812,14 @@
6792
6812
  servers: [
6793
6813
  {
6794
6814
  url: `http://localhost:${port}${rootPath}`,
6815
+ // <- TODO: !!!!! Probbably: Pass `remoteServerUrl` instead of `port` and `rootPath`
6795
6816
  },
6796
6817
  ],
6797
6818
  },
6798
6819
  apis: ['./src/remote-server/**/*.ts'], // Adjust path as needed
6799
6820
  };
6800
6821
  const swaggerSpec = swaggerJsdoc__default["default"](swaggerOptions);
6801
- app.use(`${rootPath}/api-docs`, swaggerUi__default["default"].serve, swaggerUi__default["default"].setup(swaggerSpec));
6822
+ app.use([`/api-docs`, `${rootPath}/api-docs`], swaggerUi__default["default"].serve, swaggerUi__default["default"].setup(swaggerSpec));
6802
6823
  const runningExecutionTasks = [];
6803
6824
  // <- TODO: [🤬] Identify the users
6804
6825
  // TODO: [🧠] Do here some garbage collection of finished tasks
@@ -6848,9 +6869,12 @@
6848
6869
 
6849
6870
  ## Paths
6850
6871
 
6851
- ${block(app._router.stack
6852
- .map(({ route }) => (route === null || route === void 0 ? void 0 : route.path) || null)
6853
- .filter((path) => path !== null)
6872
+ ${block([
6873
+ ...app._router.stack
6874
+ .map(({ route }) => (route === null || route === void 0 ? void 0 : route.path) || null)
6875
+ .filter((path) => path !== null),
6876
+ '/api-docs',
6877
+ ]
6854
6878
  .map((path) => `- ${path}`)
6855
6879
  .join('\n'))}
6856
6880
 
@@ -6868,7 +6892,64 @@
6868
6892
  https://github.com/webgptorg/promptbook
6869
6893
  `));
6870
6894
  });
6871
- // TODO: !!!!!! Add login route
6895
+ /**
6896
+ * @swagger
6897
+ *
6898
+ * /login:
6899
+ * post:
6900
+ * summary: Login to the server
6901
+ * description: Login to the server and get identification.
6902
+ * requestBody:
6903
+ * required: true
6904
+ * content:
6905
+ * application/json:
6906
+ * schema:
6907
+ * type: object
6908
+ * properties:
6909
+ * username:
6910
+ * type: string
6911
+ * password:
6912
+ * type: string
6913
+ * appId:
6914
+ * type: string
6915
+ * responses:
6916
+ * 200:
6917
+ * description: Successful login
6918
+ * content:
6919
+ * application/json:
6920
+ * schema:
6921
+ * type: object
6922
+ * properties:
6923
+ * identification:
6924
+ * type: object
6925
+ */
6926
+ app.post([`/login`, `${rootPath}/login`], async (request, response) => {
6927
+ if (!isApplicationModeAllowed || login === null) {
6928
+ response.status(400).send('Application mode is not allowed');
6929
+ return;
6930
+ }
6931
+ try {
6932
+ const username = request.body.username;
6933
+ const password = request.body.password;
6934
+ const appId = request.body.appId;
6935
+ const identification = await login({ username, password, appId });
6936
+ response.status(201).send({ identification });
6937
+ return;
6938
+ }
6939
+ catch (error) {
6940
+ if (!(error instanceof Error)) {
6941
+ throw error;
6942
+ }
6943
+ if (error instanceof AuthenticationError) {
6944
+ response.status(401).send({ error: serializeError(error) });
6945
+ }
6946
+ console.warn(`Login function thrown different error than AuthenticationError`, {
6947
+ error,
6948
+ serializedError: serializeError(error),
6949
+ });
6950
+ response.status(400).send({ error: serializeError(error) });
6951
+ }
6952
+ });
6872
6953
  /**
6873
6954
  * @swagger
6874
6955
  * /books:
@@ -6885,7 +6966,7 @@
6885
6966
  * items:
6886
6967
  * type: string
6887
6968
  */
6888
- app.get(`${rootPath}/books`, async (request, response) => {
6969
+ app.get([`/books`, `${rootPath}/books`], async (request, response) => {
6889
6970
  if (collection === null) {
6890
6971
  response.status(500).send('No collection available');
6891
6972
  return;
@@ -6918,7 +6999,7 @@
6918
6999
  * 404:
6919
7000
  * description: Book not found.
6920
7001
  */
6921
- app.get(`${rootPath}/books/*`, async (request, response) => {
7002
+ app.get([`/books/*`, `${rootPath}/books/*`], async (request, response) => {
6922
7003
  try {
6923
7004
  if (collection === null) {
6924
7005
  response.status(500).send('No collection nor books available');
@@ -6988,10 +7069,10 @@
6988
7069
  * items:
6989
7070
  * type: object
6990
7071
  */
6991
- app.get(`${rootPath}/executions`, async (request, response) => {
7072
+ app.get([`/executions`, `${rootPath}/executions`], async (request, response) => {
6992
7073
  response.send(runningExecutionTasks.map((runningExecutionTask) => exportExecutionTask(runningExecutionTask, false)));
6993
7074
  });
6994
- app.get(`${rootPath}/executions/last`, async (request, response) => {
7075
+ app.get([`/executions/last`, `${rootPath}/executions/last`], async (request, response) => {
6995
7076
  // TODO: [🤬] Filter only for user
6996
7077
  if (runningExecutionTasks.length === 0) {
6997
7078
  response.status(404).send('No execution tasks found');
@@ -7000,7 +7081,7 @@
7000
7081
  const lastExecutionTask = runningExecutionTasks[runningExecutionTasks.length - 1];
7001
7082
  response.send(exportExecutionTask(lastExecutionTask, true));
7002
7083
  });
7003
- app.get(`${rootPath}/executions/:taskId`, async (request, response) => {
7084
+ app.get([`/executions/:taskId`, `${rootPath}/executions/:taskId`], async (request, response) => {
7004
7085
  const { taskId } = request.params;
7005
7086
  // TODO: [🤬] Filter only for user
7006
7087
  const executionTask = runningExecutionTasks.find((executionTask) => executionTask.taskId === taskId);
@@ -7041,7 +7122,7 @@
7041
7122
  * 400:
7042
7123
  * description: Invalid input.
7043
7124
  */
7044
- app.post(`${rootPath}/executions/new`, async (request, response) => {
7125
+ app.post([`/executions/new`, `${rootPath}/executions/new`], async (request, response) => {
7045
7126
  try {
7046
7127
  const { inputParameters, identification /* <- [🤬] */ } = request.body;
7047
7128
  const pipelineUrl = request.body.pipelineUrl || request.body.book;