@rpcbase/server 0.363.0 → 0.364.0-mongoosetsindex.1

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.
@@ -0,0 +1 @@
1
+ export const SEARCH_INDEX_PREFIX = "rb-indexer"
package/express/index.js CHANGED
@@ -25,7 +25,7 @@ const has_sentry = !!SENTRY_DSN
25
25
 
26
26
  // TODO: document this
27
27
  // we could have a larger size, but it's good practice to keep it small to prevent body upload ddos attacks
28
- const BODY_MAX_SIZE_MB = 80
28
+ const BODY_MAX_SIZE_MB = 16
29
29
 
30
30
 
31
31
  log("server is production:", JSON.stringify(is_production))
package/get_object_id.ts CHANGED
@@ -9,15 +9,26 @@ const {RB_TENANT_ID} = process.env
9
9
  // TODO: WARNING: DANGER: this code is duplicated in the client
10
10
  // TODO: move it to iso
11
11
 
12
- // Validation: is defined
13
- assert(RB_TENANT_ID, "expected RB_TENANT_ID to be defined")
14
- // is hexadecimal
15
- assert(isHexadecimal(RB_TENANT_ID), "expected RB_TENANT_ID to be a hexadecimal")
16
- // is 4 bytes
17
- assert(RB_TENANT_ID.length === 8, "RB_TENANT_ID must be exactly 4 bytes (8 hex chars)")
12
+ let _is_valid_tenant_id = false
13
+
14
+ const validate_tenant_id = () => {
15
+ // Validation: is defined
16
+ assert(RB_TENANT_ID, "expected RB_TENANT_ID to be defined")
17
+ // is hexadecimal
18
+ assert(isHexadecimal(RB_TENANT_ID), "expected RB_TENANT_ID to be a hexadecimal")
19
+ // is 4 bytes
20
+ assert(RB_TENANT_ID.length === 8, "RB_TENANT_ID must be exactly 4 bytes (8 hex chars)")
21
+
22
+ _is_valid_tenant_id = true
23
+ }
24
+
18
25
 
19
26
  // generates a 12 bytes mongodb object id using the org id prefix or custom customer id
20
27
  export const get_object_id = (): mongoose.Types.ObjectId => {
28
+ if (!_is_valid_tenant_id) {
29
+ validate_tenant_id()
30
+ }
31
+
21
32
  const ts_bytes = Math.floor(Date.now() / 1000).toString(16)
22
33
  expect(ts_bytes.length).toBe(8)
23
34
 
package/mongoose/index.ts CHANGED
@@ -1,9 +1,13 @@
1
1
  import mongoose from "mongoose"
2
- import {object_id_plugin} from "./object_id_plugin"
2
+ import {object_id_plugin} from "./plugins/object_id_plugin"
3
+ import {disable_default_version_key_plugin} from "./plugins/disable_default_version_key_plugin"
4
+ import {disable_default_timestamps_plugin} from "./plugins/disable_default_timestamps_plugin"
3
5
 
4
6
  mongoose.set("strictQuery", false)
5
7
 
6
8
  mongoose.plugin(object_id_plugin)
9
+ mongoose.plugin(disable_default_version_key_plugin)
10
+ mongoose.plugin(disable_default_timestamps_plugin)
7
11
 
8
12
  export default mongoose
9
13
 
@@ -0,0 +1,5 @@
1
+ import { Schema } from "../"
2
+
3
+ export const disable_default_timestamps_plugin = (schema: Schema) => {
4
+ schema.options.timestamps = false
5
+ }
@@ -0,0 +1,5 @@
1
+ import { Schema } from "../"
2
+
3
+ export const disable_default_version_key_plugin = (schema: Schema) => {
4
+ schema.options.versionKey = false
5
+ }
@@ -0,0 +1,29 @@
1
+ import mongoose, { Schema } from "../"
2
+
3
+ import { get_object_id } from "../../get_object_id"
4
+
5
+ export const object_id_plugin = (schema: Schema) => {
6
+ if (schema.options._id === false) {
7
+ return
8
+ }
9
+ // Disable Mongoose's automatic _id field creation
10
+ if (!schema.options._id) {
11
+ schema.options._id = false
12
+ }
13
+
14
+ // Add your custom _id field
15
+ schema.add({
16
+ _id: {
17
+ type: mongoose.Schema.Types.ObjectId,
18
+ default: () => get_object_id(),
19
+ },
20
+ })
21
+
22
+ // Optional: Ensure the _id field is always set
23
+ schema.pre("save", function (next) {
24
+ if (!this._id) {
25
+ this._id = get_object_id()
26
+ }
27
+ next()
28
+ })
29
+ }
package/openai.js ADDED
@@ -0,0 +1,10 @@
1
+ const OpenAI = require("openai")
2
+
3
+ const {OPENAI_API_KEY} = process.env
4
+
5
+ export const openai = new OpenAI({
6
+ apiKey: OPENAI_API_KEY,
7
+ })
8
+
9
+ export const EMBEDDINGS_MODEL_NAME = "text-embedding-3-small"
10
+ export const EMBEDDINGS_VECTOR_LENGTH = 1536
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rpcbase/server",
3
- "version": "0.363.0",
3
+ "version": "0.364.0-mongoosetsindex.1",
4
4
  "license": "SSPL-1.0",
5
5
  "main": "./index.js",
6
6
  "scripts": {
@@ -60,6 +60,7 @@
60
60
  }
61
61
  },
62
62
  "dependencies": {
63
+ "@elastic/elasticsearch": "8.15.0",
63
64
  "@sentry/node": "8.24.0",
64
65
  "bluebird": "3.7.2",
65
66
  "body-parser": "1.20.2",
@@ -75,6 +76,7 @@
75
76
  "lodash": "4.17.21",
76
77
  "mkdirp": "3.0.1",
77
78
  "mongoose": "8.5.2",
79
+ "openai": "4.56.0",
78
80
  "picocolors": "1.0.1",
79
81
  "postmark": "4.0.4",
80
82
  "redis": "4.7.0",
@@ -0,0 +1,13 @@
1
+ /* @flow */
2
+
3
+ const dispatch_indexer_queue = (queue, model_name, coll_name, op, doc, update_description) => {
4
+
5
+ queue.add("index_item", {op, doc, model_name, coll_name, update_description}, {
6
+ jobId: `index-item-${op}-${doc._id}`,
7
+ removeOnComplete: true,
8
+ removeOnFail: true,
9
+ })
10
+ }
11
+
12
+
13
+ module.exports = dispatch_indexer_queue
@@ -1,12 +1,14 @@
1
1
  /* @flow */
2
+
2
3
  const op_names = {
3
4
  // TODO: should we deprecate create, to keep consistency with mongodb?
4
5
  insert: "create",
6
+ insert: "instert",
5
7
  delete: "delete",
6
8
  update: "update",
7
9
  }
8
10
 
9
- const dispatch_queue = (queue, model_name, op, doc, update_description) => {
11
+ const dispatch_worker_queue = (queue, model_name, op, doc, update_description) => {
10
12
  const instance = queue.instance()
11
13
 
12
14
  const tasks = queue.get_tasks()
@@ -16,6 +18,9 @@ const dispatch_queue = (queue, model_name, op, doc, update_description) => {
16
18
  // skip if there's no matching handler
17
19
  if (!Object.keys(tasks).includes(handler_name)) return
18
20
 
21
+ if (op_names[op] === "create") {
22
+ console.warn("create tasks are deprecated, rename to insert instead")
23
+ }
19
24
 
20
25
  if (update_description?.updatedFields) {
21
26
  update_description.updated_fields = Object.keys(update_description.updatedFields )
@@ -30,4 +35,4 @@ const dispatch_queue = (queue, model_name, op, doc, update_description) => {
30
35
  }
31
36
 
32
37
 
33
- module.exports = dispatch_queue
38
+ module.exports = dispatch_worker_queue
@@ -6,7 +6,8 @@ const _set = require("lodash/set")
6
6
  const mongoose = require("../mongoose")
7
7
  const queue = require("./index")
8
8
 
9
- const dispatch_queue = require("./dispatch_queue")
9
+ const dispatch_worker_queue = require("./dispatch_worker_queue")
10
+ const dispatch_indexer_queue = require("./dispatch_indexer_queue")
10
11
 
11
12
  const log = debug("rb:queue:listener")
12
13
 
@@ -32,7 +33,7 @@ const mongoose_delete_plugin = (schema) => {
32
33
  // https://mongoosejs.com/docs/queries.html
33
34
  schema.post("findOneAndDelete", function(doc) {
34
35
  log("queue:findOneAndDelete", "dispatch_doc_change NYI")
35
- log("DEL PLUGIN", doc)
36
+ log("del PLUGIN", doc)
36
37
  const coll_name = change.ns.coll
37
38
 
38
39
  const model_name = Object.keys(mongoose.models).find((k) => {
@@ -45,7 +46,8 @@ const mongoose_delete_plugin = (schema) => {
45
46
  return
46
47
  }
47
48
 
48
- dispatch_queue(queue, model_name, "delete", doc)
49
+ dispatch_worker_queue(queue, model_name, "delete", doc)
50
+ dispatch_indexer_queue(queue, model_name, "delete", doc)
49
51
  })
50
52
  }
51
53
 
@@ -77,13 +79,16 @@ const dispatch_change_handler = (change) => {
77
79
  return mongoose.models[k].collection.collectionName === coll_name
78
80
  })
79
81
 
82
+ console.log("O3333K", Object.keys(require("../mongoose").models), Object.keys(mongoose.models))
83
+
80
84
  if (!model_name) {
81
85
  return
82
86
  }
83
87
 
84
88
  const op = change.operationType
85
89
 
86
- dispatch_queue(queue, model_name, op, change.fullDocument, change.updateDescription)
90
+ dispatch_worker_queue(queue, model_name, op, change.fullDocument, change.updateDescription)
91
+ dispatch_indexer_queue(queue, model_name, coll_name, op, change.fullDocument, change.updateDescription)
87
92
  }
88
93
 
89
94
  const register_db_emitter = () => {
@@ -0,0 +1,31 @@
1
+ import debug from "debug"
2
+ import { get_client } from "./get_client"
3
+
4
+ const log = debug("rb:search:ensure_index")
5
+
6
+ export const ensure_index = async({
7
+ index_id,
8
+ mappings_properties,
9
+ }: {
10
+ index_id: string,
11
+ mappings_properties: any
12
+ }) => {
13
+ const client = get_client()
14
+
15
+ const exists = await client.indices.exists({index: index_id})
16
+ if (exists) return
17
+
18
+ const res = await client.indices.create({
19
+ index: index_id,
20
+ body: {
21
+ mappings: {
22
+ properties: mappings_properties,
23
+ },
24
+ },
25
+ })
26
+
27
+ expect(res.acknowledged).toBe(true)
28
+ expect(res.index).toBe(index_id)
29
+
30
+ log("created index", index_id)
31
+ }
@@ -0,0 +1,15 @@
1
+ const {Client} = require("@elastic/elasticsearch")
2
+
3
+ // const is_docker = require("@rpcbase/std/is_docker")
4
+ const is_docker = () => true
5
+
6
+
7
+ const {SEARCH_INDEX_PORT} = process.env
8
+ // search indexer
9
+ const search_hostname = is_docker() ? "elasticsearch" : "127.0.0.1"
10
+ const indexer_cluster_url = `http://${search_hostname}:${SEARCH_INDEX_PORT}`
11
+
12
+ export const get_client = () => {
13
+ const es_client = new Client({node: indexer_cluster_url})
14
+ return es_client
15
+ }
@@ -0,0 +1,2 @@
1
+ export * from "./get_client"
2
+ export * from "./ensure_index"
@@ -52,8 +52,8 @@ const get_query_middleware = (op) => (ac_config, schema) => function(next, save_
52
52
 
53
53
  // https://mongoosejs.com/docs/middleware.html#types-of-middleware
54
54
  const mongoose_plugin = (ac_config) => function rb_acl_plugin(schema, options) {
55
+ // TODO: should strict be true here??
55
56
  schema.options.strict = false
56
-
57
57
  // TODO:
58
58
  // DANGER: strictQuery to true silently DROPS filter params
59
59
  // which can be a critical security risk
@@ -0,0 +1,6 @@
1
+ const queue = require("../../queue")
2
+
3
+
4
+ const index_item = require("./index_item")
5
+
6
+ queue.register_task("rb_index_item", index_item)
@@ -0,0 +1,8 @@
1
+ /* @flow */
2
+
3
+ const index_item = async(payload) => {
4
+ console.log("TASK:INDEX_ITEM")
5
+ console.log("payload", payload)
6
+ }
7
+
8
+ module.exports = index_item
@@ -1,26 +0,0 @@
1
- import mongoose, { Schema } from "./"
2
-
3
- import {get_object_id} from "../get_object_id"
4
-
5
- export const object_id_plugin = (schema: Schema) => {
6
- // Disable Mongoose's automatic _id field creation
7
- if (!schema.options._id) {
8
- schema.options._id = false
9
- }
10
-
11
- // Add your custom _id field
12
- schema.add({
13
- _id: {
14
- type: mongoose.Schema.Types.ObjectId,
15
- default: () => get_object_id(),
16
- },
17
- })
18
-
19
- // Optional: Ensure the _id field is always set
20
- schema.pre("save", function(next) {
21
- if (!this._id) {
22
- this._id = get_object_id()
23
- }
24
- next()
25
- })
26
- }