@noy-db/in-nuxt 0.6.0 → 0.7.0-pre.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/runtime/rest.ts"],"sourcesContent":["/**\n * Nitro catch-all server handler for the opt-in REST API integration.\n *\n * This file is registered as a server handler entry point by the module when\n * `rest.enabled: true`. It bridges Nitro's H3 event model to\n * `@noy-db/in-rest`'s `NoydbRestHandler` via the `nitroAdapter`.\n *\n * **Store wiring (scaffold note):**\n * The handler reads the noydb store from `event.context.noydbStore`. A\n * separate Nitro server plugin must populate this before requests reach this\n * handler. That wiring is deferred to the follow-up PR.\n *\n * The handler is intentionally stateless at module scope — the lazy `_handler`\n * singleton is reset on each cold-start (Nitro worker restart), which matches\n * the expected lifecycle.\n */\n\nimport { defineEventHandler, getRequestURL, readBody } from 'h3'\nimport type { H3Event } from 'h3'\nimport { createRestHandler } from '@noy-db/in-rest'\nimport { nitroAdapter } from '@noy-db/in-rest/nitro'\nimport type { NoydbRestHandler, RestRequest } from '@noy-db/in-rest'\nimport type { NoydbStore } from '@noy-db/hub'\n\nlet _handler: NoydbRestHandler | null = null\n\n/**\n * Case-insensitive `Authorization: Bearer <token>` check against the\n * configured `rest.authToken`. HTTP header names are case-insensitive on\n * the wire — `nitroAdapter` already lowercases them, but `RestRequest`'s\n * type gives no such guarantee, so both castings are checked defensively\n * (matching what `@noy-db/in-rest`'s own pre-proxy `extractToken` did).\n */\nfunction bearerAuthorize(expectedToken: string) {\n return (req: RestRequest): boolean => {\n const auth = req.headers['authorization'] ?? req.headers['Authorization']\n if (!auth?.startsWith('Bearer ')) return false\n return auth.slice(7) === expectedToken\n }\n}\n\nfunction getHandler(\n store: NoydbStore,\n authToken: string | undefined,\n basePath: string,\n): NoydbRestHandler {\n if (!_handler) {\n // FAIL-CLOSED: @noy-db/in-rest rejects every /rpc request with 401\n // when `authorize` is omitted. Without an `authToken`, that's exactly\n // what happens here — the deployer MUST configure\n // `noydb.rest.authToken` (or wire a custom handler directly) to\n // accept any traffic.\n _handler = createRestHandler({\n store,\n basePath,\n ...(authToken ? { authorize: bearerAuthorize(authToken) } : {}),\n })\n }\n return _handler\n}\n\nexport default defineEventHandler(async (event: H3Event) => {\n // Read REST config from Nitro's runtime config. Nitro stores it at\n // `event.context.nitro.runtimeConfig` (the canonical location — confirmed\n // by reading nitropack's config.mjs). The fallback on\n // `event.context.runtimeConfig` covers bespoke setups that might inject\n // config at that alternate key. `basePath` comes off the PUBLIC branch\n // (module.ts mirrors it there too, it's not a secret); `authToken` comes\n // off the PRIVATE branch — module.ts deliberately never puts it under\n // `.public`, so it never reaches the client bundle.\n const ctx = event.context as {\n nitro?: {\n runtimeConfig?: {\n public?: { noydb?: { rest?: Record<string, unknown> } }\n noydb?: { rest?: Record<string, unknown> }\n }\n }\n runtimeConfig?: {\n public?: { noydb?: { rest?: Record<string, unknown> } }\n noydb?: { rest?: Record<string, unknown> }\n }\n noydbStore?: NoydbStore\n }\n const publicConfig =\n ctx.nitro?.runtimeConfig?.public?.noydb?.rest ??\n ctx.runtimeConfig?.public?.noydb?.rest ??\n {}\n const privateConfig =\n ctx.nitro?.runtimeConfig?.noydb?.rest ??\n ctx.runtimeConfig?.noydb?.rest ??\n {}\n\n // The store must be provided by a separate Nitro server plugin that\n // creates and populates `event.context.noydbStore` before this handler\n // runs. See module docstring above.\n const store = ctx.noydbStore\n\n if (!store) {\n return new Response(\n JSON.stringify({ error: 'noydb_store_not_configured' }),\n { status: 500, headers: { 'content-type': 'application/json' } },\n )\n }\n\n const restConfig = publicConfig as { basePath?: string }\n const authToken = (privateConfig as { authToken?: string }).authToken\n const handler = getHandler(\n store,\n authToken,\n restConfig.basePath ?? '/api/noydb',\n )\n\n // Build the adapter-friendly event shape. We pass event.headers directly\n // because `nitroAdapter` already handles both `Headers` instances and\n // plain `Record<string, string>` objects.\n const url = getRequestURL(event)\n const method = (event.method ?? 'GET').toUpperCase()\n\n let body: unknown = null\n if (method !== 'GET' && method !== 'HEAD' && method !== 'DELETE') {\n try { body = await readBody(event) } catch { body = null }\n }\n\n const h3Adapter = nitroAdapter(handler)\n return h3Adapter({\n method,\n path: url.pathname + url.search,\n // nitroAdapter's H3Event accepts Headers | Record<string,string> — pass\n // the Headers instance directly to avoid lossy serialization.\n headers: event.headers,\n _body: body,\n })\n})\n"],"mappings":";AAiBA,SAAS,oBAAoB,eAAe,gBAAgB;AAE5D,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAI7B,IAAI,WAAoC;AASxC,SAAS,gBAAgB,eAAuB;AAC9C,SAAO,CAAC,QAA8B;AACpC,UAAM,OAAO,IAAI,QAAQ,eAAe,KAAK,IAAI,QAAQ,eAAe;AACxE,QAAI,CAAC,MAAM,WAAW,SAAS,EAAG,QAAO;AACzC,WAAO,KAAK,MAAM,CAAC,MAAM;AAAA,EAC3B;AACF;AAEA,SAAS,WACP,OACA,WACA,UACkB;AAClB,MAAI,CAAC,UAAU;AAMb,eAAW,kBAAkB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,GAAI,YAAY,EAAE,WAAW,gBAAgB,SAAS,EAAE,IAAI,CAAC;AAAA,IAC/D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,IAAO,eAAQ,mBAAmB,OAAO,UAAmB;AAS1D,QAAM,MAAM,MAAM;AAalB,QAAM,eACJ,IAAI,OAAO,eAAe,QAAQ,OAAO,QACzC,IAAI,eAAe,QAAQ,OAAO,QAClC,CAAC;AACH,QAAM,gBACJ,IAAI,OAAO,eAAe,OAAO,QACjC,IAAI,eAAe,OAAO,QAC1B,CAAC;AAKH,QAAM,QAAQ,IAAI;AAElB,MAAI,CAAC,OAAO;AACV,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,6BAA6B,CAAC;AAAA,MACtD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,aAAa;AACnB,QAAM,YAAa,cAAyC;AAC5D,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,WAAW,YAAY;AAAA,EACzB;AAKA,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,UAAU,MAAM,UAAU,OAAO,YAAY;AAEnD,MAAI,OAAgB;AACpB,MAAI,WAAW,SAAS,WAAW,UAAU,WAAW,UAAU;AAChE,QAAI;AAAE,aAAO,MAAM,SAAS,KAAK;AAAA,IAAE,QAAQ;AAAE,aAAO;AAAA,IAAK;AAAA,EAC3D;AAEA,QAAM,YAAY,aAAa,OAAO;AACtC,SAAO,UAAU;AAAA,IACf;AAAA,IACA,MAAM,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA,IAGzB,SAAS,MAAM;AAAA,IACf,OAAO;AAAA,EACT,CAAC;AACH,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../src/runtime/rest.ts"],"sourcesContent":["/**\n * Nitro catch-all server handler for the opt-in REST API integration.\n *\n * This file is registered as a server handler entry point by the module when\n * `rest.enabled: true`. It bridges Nitro's H3 event model to\n * `@noy-db/in-rest`'s `NoydbRestHandler` via the `nitroAdapter`.\n *\n * **Store wiring (scaffold note):**\n * The handler reads the noydb store from `event.context.noydbStore`. A\n * separate Nitro server plugin must populate this before requests reach this\n * handler. That wiring is deferred to the follow-up PR.\n *\n * The handler is intentionally stateless at module scope — the lazy `_handler`\n * singleton is reset on each cold-start (Nitro worker restart), which matches\n * the expected lifecycle.\n */\n\nimport { defineEventHandler, getRequestURL, readBody } from 'h3'\nimport type { H3Event } from 'h3'\nimport { createRestHandler } from '@noy-db/in-rest'\nimport { nitroAdapter } from '@noy-db/in-rest/nitro'\nimport type { NoydbRestHandler, RestRequest } from '@noy-db/in-rest'\nimport type { NoydbStore } from '@noy-db/hub/to'\n\nlet _handler: NoydbRestHandler | null = null\n\n/**\n * Case-insensitive `Authorization: Bearer <token>` check against the\n * configured `rest.authToken`. HTTP header names are case-insensitive on\n * the wire — `nitroAdapter` already lowercases them, but `RestRequest`'s\n * type gives no such guarantee, so both castings are checked defensively\n * (matching what `@noy-db/in-rest`'s own pre-proxy `extractToken` did).\n */\nfunction bearerAuthorize(expectedToken: string) {\n return (req: RestRequest): boolean => {\n const auth = req.headers['authorization'] ?? req.headers['Authorization']\n if (!auth?.startsWith('Bearer ')) return false\n return auth.slice(7) === expectedToken\n }\n}\n\nfunction getHandler(\n store: NoydbStore,\n authToken: string | undefined,\n basePath: string,\n): NoydbRestHandler {\n if (!_handler) {\n // FAIL-CLOSED: @noy-db/in-rest rejects every /rpc request with 401\n // when `authorize` is omitted. Without an `authToken`, that's exactly\n // what happens here — the deployer MUST configure\n // `noydb.rest.authToken` (or wire a custom handler directly) to\n // accept any traffic.\n _handler = createRestHandler({\n store,\n basePath,\n ...(authToken ? { authorize: bearerAuthorize(authToken) } : {}),\n })\n }\n return _handler\n}\n\nexport default defineEventHandler(async (event: H3Event) => {\n // Read REST config from Nitro's runtime config. Nitro stores it at\n // `event.context.nitro.runtimeConfig` (the canonical location — confirmed\n // by reading nitropack's config.mjs). The fallback on\n // `event.context.runtimeConfig` covers bespoke setups that might inject\n // config at that alternate key. `basePath` comes off the PUBLIC branch\n // (module.ts mirrors it there too, it's not a secret); `authToken` comes\n // off the PRIVATE branch — module.ts deliberately never puts it under\n // `.public`, so it never reaches the client bundle.\n const ctx = event.context as {\n nitro?: {\n runtimeConfig?: {\n public?: { noydb?: { rest?: Record<string, unknown> } }\n noydb?: { rest?: Record<string, unknown> }\n }\n }\n runtimeConfig?: {\n public?: { noydb?: { rest?: Record<string, unknown> } }\n noydb?: { rest?: Record<string, unknown> }\n }\n noydbStore?: NoydbStore\n }\n const publicConfig =\n ctx.nitro?.runtimeConfig?.public?.noydb?.rest ??\n ctx.runtimeConfig?.public?.noydb?.rest ??\n {}\n const privateConfig =\n ctx.nitro?.runtimeConfig?.noydb?.rest ??\n ctx.runtimeConfig?.noydb?.rest ??\n {}\n\n // The store must be provided by a separate Nitro server plugin that\n // creates and populates `event.context.noydbStore` before this handler\n // runs. See module docstring above.\n const store = ctx.noydbStore\n\n if (!store) {\n return new Response(\n JSON.stringify({ error: 'noydb_store_not_configured' }),\n { status: 500, headers: { 'content-type': 'application/json' } },\n )\n }\n\n const restConfig = publicConfig as { basePath?: string }\n const authToken = (privateConfig as { authToken?: string }).authToken\n const handler = getHandler(\n store,\n authToken,\n restConfig.basePath ?? '/api/noydb',\n )\n\n // Build the adapter-friendly event shape. We pass event.headers directly\n // because `nitroAdapter` already handles both `Headers` instances and\n // plain `Record<string, string>` objects.\n const url = getRequestURL(event)\n const method = (event.method ?? 'GET').toUpperCase()\n\n let body: unknown = null\n if (method !== 'GET' && method !== 'HEAD' && method !== 'DELETE') {\n try { body = await readBody(event) } catch { body = null }\n }\n\n const h3Adapter = nitroAdapter(handler)\n return h3Adapter({\n method,\n path: url.pathname + url.search,\n // nitroAdapter's H3Event accepts Headers | Record<string,string> — pass\n // the Headers instance directly to avoid lossy serialization.\n headers: event.headers,\n _body: body,\n })\n})\n"],"mappings":";AAiBA,SAAS,oBAAoB,eAAe,gBAAgB;AAE5D,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAI7B,IAAI,WAAoC;AASxC,SAAS,gBAAgB,eAAuB;AAC9C,SAAO,CAAC,QAA8B;AACpC,UAAM,OAAO,IAAI,QAAQ,eAAe,KAAK,IAAI,QAAQ,eAAe;AACxE,QAAI,CAAC,MAAM,WAAW,SAAS,EAAG,QAAO;AACzC,WAAO,KAAK,MAAM,CAAC,MAAM;AAAA,EAC3B;AACF;AAEA,SAAS,WACP,OACA,WACA,UACkB;AAClB,MAAI,CAAC,UAAU;AAMb,eAAW,kBAAkB;AAAA,MAC3B;AAAA,MACA;AAAA,MACA,GAAI,YAAY,EAAE,WAAW,gBAAgB,SAAS,EAAE,IAAI,CAAC;AAAA,IAC/D,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,IAAO,eAAQ,mBAAmB,OAAO,UAAmB;AAS1D,QAAM,MAAM,MAAM;AAalB,QAAM,eACJ,IAAI,OAAO,eAAe,QAAQ,OAAO,QACzC,IAAI,eAAe,QAAQ,OAAO,QAClC,CAAC;AACH,QAAM,gBACJ,IAAI,OAAO,eAAe,OAAO,QACjC,IAAI,eAAe,OAAO,QAC1B,CAAC;AAKH,QAAM,QAAQ,IAAI;AAElB,MAAI,CAAC,OAAO;AACV,WAAO,IAAI;AAAA,MACT,KAAK,UAAU,EAAE,OAAO,6BAA6B,CAAC;AAAA,MACtD,EAAE,QAAQ,KAAK,SAAS,EAAE,gBAAgB,mBAAmB,EAAE;AAAA,IACjE;AAAA,EACF;AAEA,QAAM,aAAa;AACnB,QAAM,YAAa,cAAyC;AAC5D,QAAM,UAAU;AAAA,IACd;AAAA,IACA;AAAA,IACA,WAAW,YAAY;AAAA,EACzB;AAKA,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,UAAU,MAAM,UAAU,OAAO,YAAY;AAEnD,MAAI,OAAgB;AACpB,MAAI,WAAW,SAAS,WAAW,UAAU,WAAW,UAAU;AAChE,QAAI;AAAE,aAAO,MAAM,SAAS,KAAK;AAAA,IAAE,QAAQ;AAAE,aAAO;AAAA,IAAK;AAAA,EAC3D;AAEA,QAAM,YAAY,aAAa,OAAO;AACtC,SAAO,UAAU;AAAA,IACf;AAAA,IACA,MAAM,IAAI,WAAW,IAAI;AAAA;AAAA;AAAA,IAGzB,SAAS,MAAM;AAAA,IACf,OAAO;AAAA,EACT,CAAC;AACH,CAAC;","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noy-db/in-nuxt",
3
- "version": "0.6.0",
3
+ "version": "0.7.0-pre.0",
4
4
  "description": "Nuxt 4 module for noy-db — auto-imports, SSR-safe runtime plugin, and the @noy-db/in-pinia bridge",
5
5
  "license": "MIT",
6
6
  "author": "vLannaAi <vicio@lanna.ai>",
@@ -34,10 +34,10 @@
34
34
  },
35
35
  "peerDependencies": {
36
36
  "nuxt": "^4.0.0",
37
- "@noy-db/in-pinia": "0.6.0",
38
- "@noy-db/hub": "0.6.0",
39
- "@noy-db/in-vue": "0.6.0",
40
- "@noy-db/in-rest": "0.6.0"
37
+ "@noy-db/hub": "0.7.0-pre.0",
38
+ "@noy-db/in-pinia": "0.7.0-pre.0",
39
+ "@noy-db/in-rest": "0.7.0-pre.0",
40
+ "@noy-db/in-vue": "0.7.0-pre.0"
41
41
  },
42
42
  "peerDependenciesMeta": {
43
43
  "@noy-db/in-rest": {
@@ -45,7 +45,7 @@
45
45
  }
46
46
  },
47
47
  "dependencies": {
48
- "@noy-db/in-devtools": "0.6.0"
48
+ "@noy-db/in-devtools": "0.7.0-pre.0"
49
49
  },
50
50
  "devDependencies": {
51
51
  "@nuxt/kit": "^4.4.2",
@@ -56,10 +56,10 @@
56
56
  "happy-dom": "^17.4.4",
57
57
  "nuxt": "^4.4.2",
58
58
  "vue": "^3.5.32",
59
- "@noy-db/hub": "0.6.0",
60
- "@noy-db/in-pinia": "0.6.0",
61
- "@noy-db/in-rest": "0.6.0",
62
- "@noy-db/in-vue": "0.6.0"
59
+ "@noy-db/hub": "0.7.0-pre.0",
60
+ "@noy-db/in-pinia": "0.7.0-pre.0",
61
+ "@noy-db/in-rest": "0.7.0-pre.0",
62
+ "@noy-db/in-vue": "0.7.0-pre.0"
63
63
  },
64
64
  "keywords": [
65
65
  "noy-db",