@promptbook/remote-server 0.98.0-9 → 0.99.0-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.
package/esm/index.es.js CHANGED
@@ -33,7 +33,7 @@ const BOOK_LANGUAGE_VERSION = '1.0.0';
33
33
  * @generated
34
34
  * @see https://github.com/webgptorg/promptbook
35
35
  */
36
- const PROMPTBOOK_ENGINE_VERSION = '0.98.0-9';
36
+ const PROMPTBOOK_ENGINE_VERSION = '0.99.0-0';
37
37
  /**
38
38
  * TODO: string_promptbook_version should be constrained to the all versions of Promptbook engine
39
39
  * Note: [💞] Ignore a discrepancy between file name and entity name
@@ -6366,6 +6366,46 @@ function createPipelineExecutor(options) {
6366
6366
  return pipelineExecutor;
6367
6367
  }
6368
6368
 
6369
+ /**
6370
+ * Detects if the code is running in a browser environment in main thread (Not in a web worker)
6371
+ *
6372
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
6373
+ *
6374
+ * @public exported from `@promptbook/utils`
6375
+ */
6376
+ const $isRunningInBrowser = new Function(`
6377
+ try {
6378
+ return this === window;
6379
+ } catch (e) {
6380
+ return false;
6381
+ }
6382
+ `);
6383
+ /**
6384
+ * TODO: [🎺]
6385
+ */
6386
+
6387
+ /**
6388
+ * Detects if the code is running in a web worker
6389
+ *
6390
+ * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
6391
+ *
6392
+ * @public exported from `@promptbook/utils`
6393
+ */
6394
+ const $isRunningInWebWorker = new Function(`
6395
+ try {
6396
+ if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
6397
+ return true;
6398
+ } else {
6399
+ return false;
6400
+ }
6401
+ } catch (e) {
6402
+ return false;
6403
+ }
6404
+ `);
6405
+ /**
6406
+ * TODO: [🎺]
6407
+ */
6408
+
6369
6409
  /**
6370
6410
  * Register for LLM tools.
6371
6411
  *
@@ -6534,9 +6574,10 @@ function createLlmToolsFromConfiguration(configuration, options = {}) {
6534
6574
  .list()
6535
6575
  .find(({ packageName, className }) => llmConfiguration.packageName === packageName && llmConfiguration.className === className);
6536
6576
  if (registeredItem === undefined) {
6537
- console.log('!!! $llmToolsRegister.list()', $llmToolsRegister.list());
6577
+ // console.log('$llmToolsRegister.list()', $llmToolsRegister.list());
6538
6578
  throw new Error(spaceTrim((block) => `
6539
6579
  There is no constructor for LLM provider \`${llmConfiguration.className}\` from \`${llmConfiguration.packageName}\`
6580
+ Running in ${!$isRunningInBrowser() ? '' : 'browser environment'}${!$isRunningInNode() ? '' : 'node environment'}${!$isRunningInWebWorker() ? '' : 'worker environment'}
6540
6581
 
6541
6582
  You have probably forgotten install and import the provider package.
6542
6583
  To fix this issue, you can:
@@ -6654,24 +6695,6 @@ function normalizeTo_camelCase(text, _isFirstLetterCapital = false) {
6654
6695
  * TODO: [🌺] Use some intermediate util splitWords
6655
6696
  */
6656
6697
 
6657
- /**
6658
- * Detects if the code is running in a browser environment in main thread (Not in a web worker)
6659
- *
6660
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
6661
- *
6662
- * @public exported from `@promptbook/utils`
6663
- */
6664
- new Function(`
6665
- try {
6666
- return this === window;
6667
- } catch (e) {
6668
- return false;
6669
- }
6670
- `);
6671
- /**
6672
- * TODO: [🎺]
6673
- */
6674
-
6675
6698
  /**
6676
6699
  * Detects if the code is running in jest environment
6677
6700
  *
@@ -6690,28 +6713,6 @@ new Function(`
6690
6713
  * TODO: [🎺]
6691
6714
  */
6692
6715
 
6693
- /**
6694
- * Detects if the code is running in a web worker
6695
- *
6696
- * Note: `$` is used to indicate that this function is not a pure function - it looks at the global object to determine the environment
6697
- *
6698
- * @public exported from `@promptbook/utils`
6699
- */
6700
- new Function(`
6701
- try {
6702
- if (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {
6703
- return true;
6704
- } else {
6705
- return false;
6706
- }
6707
- } catch (e) {
6708
- return false;
6709
- }
6710
- `);
6711
- /**
6712
- * TODO: [🎺]
6713
- */
6714
-
6715
6716
  /**
6716
6717
  * Makes first letter of a string uppercase
6717
6718
  *
@@ -8060,6 +8061,152 @@ function startRemoteServer(options) {
8060
8061
  response.status(400).send({ error: serializeError(error) });
8061
8062
  }
8062
8063
  });
8064
+ // OAuth Authentication Endpoints
8065
+ // These endpoints provide social authentication support (Facebook, Google, etc.)
8066
+ app.get('/auth/:provider', async (request, response) => {
8067
+ const { provider } = request.params;
8068
+ if (!isApplicationModeAllowed) {
8069
+ response.status(400).json({
8070
+ error: 'Application mode is not allowed',
8071
+ message: 'Social authentication requires application mode to be enabled'
8072
+ });
8073
+ return;
8074
+ }
8075
+ try {
8076
+ // Get OAuth configuration from query params or environment
8077
+ const { redirectUri, clientId, appId } = request.query;
8078
+ if (!redirectUri || !clientId) {
8079
+ response.status(400).json({
8080
+ error: 'Missing OAuth parameters',
8081
+ message: 'redirectUri and clientId are required for OAuth flow'
8082
+ });
8083
+ return;
8084
+ }
8085
+ let authUrl;
8086
+ const state = Buffer.from(JSON.stringify({
8087
+ appId: appId || 'default',
8088
+ timestamp: Date.now()
8089
+ })).toString('base64');
8090
+ switch (provider.toLowerCase()) {
8091
+ case 'facebook':
8092
+ authUrl = `https://www.facebook.com/v18.0/dialog/oauth?` +
8093
+ `client_id=${encodeURIComponent(clientId)}&` +
8094
+ `redirect_uri=${encodeURIComponent(redirectUri)}&` +
8095
+ `scope=email,public_profile&` +
8096
+ `response_type=code&` +
8097
+ `state=${encodeURIComponent(state)}`;
8098
+ break;
8099
+ case 'google':
8100
+ authUrl = `https://accounts.google.com/o/oauth2/v2/auth?` +
8101
+ `client_id=${encodeURIComponent(clientId)}&` +
8102
+ `redirect_uri=${encodeURIComponent(redirectUri)}&` +
8103
+ `scope=openid%20email%20profile&` +
8104
+ `response_type=code&` +
8105
+ `state=${encodeURIComponent(state)}`;
8106
+ break;
8107
+ default:
8108
+ response.status(400).json({
8109
+ error: 'Unsupported provider',
8110
+ message: `Social authentication provider '${provider}' is not supported. Supported providers: facebook, google`
8111
+ });
8112
+ return;
8113
+ }
8114
+ // Log the OAuth attempt for debugging
8115
+ if (isVerbose) {
8116
+ console.info(colors.cyan(`OAuth ${provider} flow started for app ${appId || 'default'}`));
8117
+ }
8118
+ response.json({
8119
+ authUrl,
8120
+ provider,
8121
+ state,
8122
+ message: `Redirect user to authUrl to complete ${provider} authentication`
8123
+ });
8124
+ }
8125
+ catch (error) {
8126
+ assertsError(error);
8127
+ console.warn(`OAuth ${provider} initialization failed:`, error);
8128
+ response.status(500).json({
8129
+ error: 'OAuth initialization failed',
8130
+ message: error.message
8131
+ });
8132
+ }
8133
+ });
8134
+ app.post('/auth/:provider/callback', async (request, response) => {
8135
+ const { provider } = request.params;
8136
+ if (!isApplicationModeAllowed || login === null) {
8137
+ response.status(400).json({
8138
+ error: 'Application mode is not allowed',
8139
+ message: 'Social authentication requires application mode and login handler to be configured'
8140
+ });
8141
+ return;
8142
+ }
8143
+ try {
8144
+ const { code, state, error: oauthError } = request.body;
8145
+ if (oauthError) {
8146
+ response.status(400).json({
8147
+ isSuccess: false,
8148
+ error: 'OAuth authorization failed',
8149
+ message: `${provider} authentication was denied or failed: ${oauthError}`
8150
+ });
8151
+ return;
8152
+ }
8153
+ if (!code || !state) {
8154
+ response.status(400).json({
8155
+ isSuccess: false,
8156
+ error: 'Missing OAuth callback parameters',
8157
+ message: 'code and state parameters are required'
8158
+ });
8159
+ return;
8160
+ }
8161
+ // Decode state to get app information
8162
+ let appInfo;
8163
+ try {
8164
+ appInfo = JSON.parse(Buffer.from(state, 'base64').toString());
8165
+ }
8166
+ catch (_a) {
8167
+ response.status(400).json({
8168
+ isSuccess: false,
8169
+ error: 'Invalid state parameter',
8170
+ message: 'The OAuth state parameter is malformed'
8171
+ });
8172
+ return;
8173
+ }
8174
+ // Log the OAuth callback for debugging
8175
+ if (isVerbose) {
8176
+ console.info(colors.cyan(`OAuth ${provider} callback received for app ${appInfo.appId}`));
8177
+ }
8178
+ // Note: In a real implementation, you would:
8179
+ // 1. Exchange the code for an access token with the OAuth provider
8180
+ // 2. Use the access token to get user information
8181
+ // 3. Create or find the user in your system
8182
+ // 4. Call the login function with the user's information
8183
+ // For now, we provide a framework that the implementer can extend
8184
+ const mockUserInfo = {
8185
+ username: `${provider}_user_${code.substring(0, 8)}`,
8186
+ password: '',
8187
+ appId: appInfo.appId
8188
+ };
8189
+ const loginResult = await login({
8190
+ ...mockUserInfo,
8191
+ rawRequest: request,
8192
+ rawResponse: response,
8193
+ });
8194
+ response.status(200).json({
8195
+ ...loginResult,
8196
+ provider,
8197
+ message: loginResult.message || `${provider} authentication completed`,
8198
+ });
8199
+ }
8200
+ catch (error) {
8201
+ assertsError(error);
8202
+ console.warn(`OAuth ${provider} callback failed:`, error);
8203
+ response.status(500).json({
8204
+ isSuccess: false,
8205
+ error: 'OAuth callback processing failed',
8206
+ message: error.message
8207
+ });
8208
+ }
8209
+ });
8063
8210
  app.get(`/books`, async (request, response) => {
8064
8211
  if (collection === null) {
8065
8212
  response.status(500).send('No collection available');
@@ -8303,7 +8450,6 @@ function startRemoteServer(options) {
8303
8450
  catch (error) {
8304
8451
  assertsError(error);
8305
8452
  socket.emit('error', serializeError(error));
8306
- // <- TODO: [🚋] There is a problem with the remote server handling errors and sending them back to the client
8307
8453
  }
8308
8454
  finally {
8309
8455
  socket.disconnect();