@qelos/plugin-netlify-api 1.0.1 → 1.0.2

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/README.md CHANGED
@@ -4,14 +4,29 @@ Netlify build plugin for Qelos frontend apps: proxies `/api/*` to your Qelos API
4
4
 
5
5
  ## Setup
6
6
 
7
- In your site’s `netlify.toml`:
7
+ In your site’s `netlify.toml`, add the plugin next to your existing `[build]` / `[build.environment]` (same idea as a manual `[functions]` + `[[redirects]]` + `api-proxy.ts`, but without checking in the function or redirect yourself):
8
8
 
9
9
  ```toml
10
+ [build]
11
+ command = "npm run build"
12
+ publish = "dist"
13
+
14
+ [build.environment]
15
+ # Used by the injected proxy at runtime (and by your build if you read it in app config)
16
+ QELOS_API_IP = "http://159.203.152.168"
17
+
10
18
  [[plugins]]
11
19
  package = "@qelos/plugin-netlify-api"
12
20
  ```
13
21
 
14
- Optional: set the API URL (default `http://159.203.152.168`):
22
+ Minimal variant (defaults API URL inside the plugin if you omit env):
23
+
24
+ ```toml
25
+ [[plugins]]
26
+ package = "@qelos/plugin-netlify-api"
27
+ ```
28
+
29
+ Optional: set the API URL (default `http://159.203.152.168`) and/or enable bypass-admin header:
15
30
 
16
31
  ```toml
17
32
  [[plugins]]
@@ -19,9 +34,11 @@ Optional: set the API URL (default `http://159.203.152.168`):
19
34
 
20
35
  [plugins.inputs]
21
36
  api_url = "http://159.203.152.168"
37
+ bypass_admin = true
22
38
  ```
23
39
 
24
- Or set the `QELOS_API_IP` environment variable in the Netlify UI (build or runtime).
40
+ - **api_url** — Target for the `/api/*` proxy. You can also set **`QELOS_API_IP`** or **`API_HOST`** in `[build.environment]` or in the Netlify UI (same role as `API_HOST` in a hand-written `netlify/functions/api-proxy.ts`).
41
+ - **bypass_admin** — If `true`, the proxy adds the header `x-bypass-admin: true` to every request so that admin users are scoped as regular users. See root docs: `documentation/docs/plugins/api-proxy.md` and `documentation/docs/sdk/token_refresh.md`.
25
42
 
26
43
  ## What it does
27
44
 
@@ -30,3 +47,5 @@ Or set the `QELOS_API_IP` environment variable in the Netlify UI (build or runti
30
47
  - **Function:** Injects a serverless function `qelos-api-proxy` that forwards requests to the host/port from `QELOS_API_IP` (supports a full URL like `http://159.203.152.168` or a hostname).
31
48
 
32
49
  No need to add redirects or the function file to your repo; the plugin does it at build time.
50
+
51
+ **Parity with a manual Netlify function** (e.g. `[[redirects]]` → `/.netlify/functions/api-proxy` and a function using `process.env.API_HOST`): use this plugin instead of those entries; set `QELOS_API_IP` or `API_HOST` to the same value you used for `API_HOST`, and set `bypass_admin = true` under `[plugins.inputs]` if your old proxy always sent `x-bypass-admin: true`.
@@ -1,13 +1,31 @@
1
1
  import http from "http";
2
+ import https from "https";
2
3
  import type { Handler } from "@netlify/functions";
3
4
 
4
- const raw = process.env.QELOS_API_IP ?? "159.203.152.168";
5
- const parsed =
6
- raw.startsWith("http://") || raw.startsWith("https://")
7
- ? new URL(raw)
8
- : { hostname: raw, port: "80" };
9
- const PROXY_HOST = parsed.hostname;
10
- const PROXY_PORT = parseInt(parsed.port || "80", 10);
5
+ /** Same-origin proxy target; mirrors manual setups that use API_HOST (e.g. ai-words api-proxy). */
6
+ const raw =
7
+ process.env.QELOS_API_IP ?? process.env.API_HOST ?? "159.203.152.168";
8
+
9
+ let PROXY_HOST: string;
10
+ let PROXY_PORT: number;
11
+ let requestImpl: typeof http.request;
12
+
13
+ if (raw.startsWith("http://") || raw.startsWith("https://")) {
14
+ const u = new URL(raw);
15
+ PROXY_HOST = u.hostname;
16
+ PROXY_PORT = u.port
17
+ ? parseInt(u.port, 10)
18
+ : u.protocol === "https:"
19
+ ? 443
20
+ : 80;
21
+ requestImpl = u.protocol === "https:" ? https.request : http.request;
22
+ } else {
23
+ PROXY_HOST = raw;
24
+ PROXY_PORT = 80;
25
+ requestImpl = http.request;
26
+ }
27
+ const ADD_BYPASS_ADMIN_HEADER =
28
+ process.env.QELOS_BYPASS_ADMIN_HEADER === "true";
11
29
 
12
30
  export const handler: Handler = (event) =>
13
31
  new Promise((resolve) => {
@@ -17,6 +35,9 @@ export const handler: Handler = (event) =>
17
35
  if (val) headers[key] = val;
18
36
  }
19
37
  headers["host"] = event.headers["host"] ?? PROXY_HOST;
38
+ if (ADD_BYPASS_ADMIN_HEADER) {
39
+ headers["x-bypass-admin"] = "true";
40
+ }
20
41
  // Lambda buffers the body, so chunked encoding is not applicable
21
42
  delete headers["transfer-encoding"];
22
43
 
@@ -28,7 +49,7 @@ export const handler: Handler = (event) =>
28
49
  ? Buffer.from(event.body, event.isBase64Encoded ? "base64" : "utf8")
29
50
  : undefined;
30
51
 
31
- const proxyReq = http.request(
52
+ const proxyReq = requestImpl(
32
53
  {
33
54
  hostname: PROXY_HOST,
34
55
  port: PROXY_PORT,
package/index.js CHANGED
@@ -1,31 +1,49 @@
1
- const path = require("node:path");
1
+ const path = require('node:path');
2
2
 
3
- const DEFAULT_API_URL = "http://159.203.152.168";
3
+ const DEFAULT_API_URL = 'http://159.203.152.168';
4
4
 
5
5
  module.exports = {
6
6
  async onPreBuild({ netlifyConfig, utils, inputs }) {
7
- const apiUrl = inputs.api_url ?? process.env.QELOS_API_IP ?? DEFAULT_API_URL;
7
+ const apiUrl =
8
+ inputs.api_url ?? process.env.QELOS_API_IP ?? DEFAULT_API_URL;
9
+ const bypassAdmin =
10
+ inputs.bypass_admin === true || inputs.bypass_admin === 'true';
8
11
 
9
12
  // Ensure build.environment exists
10
13
  if (!netlifyConfig.build.environment) {
11
14
  netlifyConfig.build.environment = {};
12
15
  }
13
16
  netlifyConfig.build.environment.QELOS_API_IP = apiUrl;
17
+ if (bypassAdmin) {
18
+ netlifyConfig.build.environment.QELOS_BYPASS_ADMIN_HEADER = 'true';
19
+ }
20
+
21
+ if (!netlifyConfig.functions) {
22
+ // [functions]
23
+ // directory = "netlify/functions"
24
+ netlifyConfig.functions = { directory: 'netlify/functions' };
25
+ } else {
26
+ // should use this dir as path of the stored function
27
+ }
14
28
 
15
29
  // Add redirect: /api/* -> Netlify function (proxy)
16
30
  if (!netlifyConfig.redirects) {
17
31
  netlifyConfig.redirects = [];
18
32
  }
19
33
  netlifyConfig.redirects.push({
20
- from: "/api/*",
21
- to: "/.netlify/functions/qelos-api-proxy",
34
+ from: '/api/*',
35
+ to: '/.netlify/functions/qelos-api-proxy',
22
36
  status: 200,
23
37
  force: true,
24
38
  });
25
39
 
26
40
  // Inject the proxy function (must run in onPreBuild so it's bundled)
27
41
  const pluginRoot = __dirname;
28
- const functionPath = path.join(pluginRoot, "functions", "qelos-api-proxy.ts");
42
+ const functionPath = path.join(
43
+ pluginRoot,
44
+ 'functions',
45
+ 'qelos-api-proxy.ts',
46
+ );
29
47
  await utils.functions.add(functionPath);
30
48
  },
31
49
  };
package/manifest.yml CHANGED
@@ -4,3 +4,7 @@ inputs:
4
4
  required: false
5
5
  description: "Qelos API base URL (e.g. http://159.203.152.168). Used as QELOS_API_IP and for /api/* proxy."
6
6
  default: "http://159.203.152.168"
7
+ - name: bypass_admin
8
+ required: false
9
+ description: "If true, the proxy adds header x-bypass-admin: true to every request (so admins are scoped as regular users)."
10
+ default: false
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qelos/plugin-netlify-api",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "Netlify build plugin: proxy /api/* to Qelos API and inject config",
5
5
  "main": "index.js",
6
6
  "files": [