@qelos/plugin-netlify-api 1.0.2 → 1.0.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.
Files changed (3) hide show
  1. package/README.md +3 -3
  2. package/index.js +37 -13
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -43,9 +43,9 @@ Optional: set the API URL (default `http://159.203.152.168`) and/or enable bypas
43
43
  ## What it does
44
44
 
45
45
  - **Environment:** Sets `QELOS_API_IP` for the build (and for the proxy function at runtime).
46
- - **Redirect:** Adds a rewrite so `/api/*` is served by `/.netlify/functions/qelos-api-proxy` (status 200, force).
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).
46
+ - **Redirect:** Adds a rewrite in `netlify.toml` and, **after the site build**, prepends the same rule to **`publish/_redirects`** when that file exists. Netlify applies `_redirects` **before** `netlify.toml`; frameworks (e.g. Nuxt `netlify-static`) often emit `/* → /404.html` first, which would otherwise match `/api/*` and never reach the proxy.
47
+ - **Function:** Copies `qelos-api-proxy.ts` from the package into your Netlify **functions directory** (default `netlify/functions`, or `[functions] directory` in `netlify.toml`) during `onPreBuild`, so the bundler sees a normal function file. Forwards requests using `QELOS_API_IP` / `API_HOST` (full URL or hostname).
48
48
 
49
- No need to add redirects or the function file to your repo; the plugin does it at build time.
49
+ No need to add redirects or commit the proxy yourself; the plugin writes it each build. Optional: add `netlify/functions/qelos-api-proxy.ts` to `.gitignore` if you run local Netlify builds and do not want the copy tracked.
50
50
 
51
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`.
package/index.js CHANGED
@@ -1,9 +1,19 @@
1
+ const fs = require('node:fs/promises');
1
2
  const path = require('node:path');
2
3
 
3
4
  const DEFAULT_API_URL = 'http://159.203.152.168';
4
5
 
6
+ /** Must appear before any `/*` rule in publish/_redirects — Netlify evaluates that file before netlify.toml. */
7
+ const REDIRECTS_FILE_LINE =
8
+ '/api/* /.netlify/functions/qelos-api-proxy 200!\n';
9
+
10
+ function resolveFunctionsDirectory(netlifyConfig) {
11
+ const dir = netlifyConfig.functions?.directory ?? 'netlify/functions';
12
+ return path.isAbsolute(dir) ? dir : path.join(process.cwd(), dir);
13
+ }
14
+
5
15
  module.exports = {
6
- async onPreBuild({ netlifyConfig, utils, inputs }) {
16
+ async onPreBuild({ netlifyConfig, inputs }) {
7
17
  const apiUrl =
8
18
  inputs.api_url ?? process.env.QELOS_API_IP ?? DEFAULT_API_URL;
9
19
  const bypassAdmin =
@@ -19,13 +29,17 @@ module.exports = {
19
29
  }
20
30
 
21
31
  if (!netlifyConfig.functions) {
22
- // [functions]
23
- // directory = "netlify/functions"
24
32
  netlifyConfig.functions = { directory: 'netlify/functions' };
25
- } else {
26
- // should use this dir as path of the stored function
27
33
  }
28
34
 
35
+ // Copy the proxy into the site's functions dir so Netlify bundles it like any
36
+ // checked-in function (utils.functions.add from node_modules is unreliable for .ts).
37
+ const destDir = resolveFunctionsDirectory(netlifyConfig);
38
+ const destFile = path.join(destDir, 'qelos-api-proxy.ts');
39
+ const srcFile = path.join(__dirname, 'functions', 'qelos-api-proxy.ts');
40
+ await fs.mkdir(destDir, { recursive: true });
41
+ await fs.copyFile(srcFile, destFile);
42
+
29
43
  // Add redirect: /api/* -> Netlify function (proxy)
30
44
  if (!netlifyConfig.redirects) {
31
45
  netlifyConfig.redirects = [];
@@ -36,14 +50,24 @@ module.exports = {
36
50
  status: 200,
37
51
  force: true,
38
52
  });
53
+ },
39
54
 
40
- // Inject the proxy function (must run in onPreBuild so it's bundled)
41
- const pluginRoot = __dirname;
42
- const functionPath = path.join(
43
- pluginRoot,
44
- 'functions',
45
- 'qelos-api-proxy.ts',
46
- );
47
- await utils.functions.add(functionPath);
55
+ /**
56
+ * Nuxt/static generators emit `dist/_redirects` with `/* → 404` first. Netlify runs
57
+ * `_redirects` rules before `netlify.toml`, so that catch-all wins unless `/api/*` is
58
+ * prepended here (after the framework build).
59
+ */
60
+ async onPostBuild({ constants }) {
61
+ const publishDir = constants.PUBLISH_DIR;
62
+ if (!publishDir) return;
63
+ const redirectsPath = path.join(publishDir, '_redirects');
64
+ let existing = '';
65
+ try {
66
+ existing = await fs.readFile(redirectsPath, 'utf8');
67
+ } catch (e) {
68
+ if (e.code !== 'ENOENT') throw e;
69
+ }
70
+ if (existing.includes('qelos-api-proxy')) return;
71
+ await fs.writeFile(redirectsPath, REDIRECTS_FILE_LINE + existing, 'utf8');
48
72
  },
49
73
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qelos/plugin-netlify-api",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Netlify build plugin: proxy /api/* to Qelos API and inject config",
5
5
  "main": "index.js",
6
6
  "files": [