couchset 0.2.7 → 0.4.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.
Files changed (117) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/README.md +292 -152
  3. package/dist/connection/connection.d.ts +68 -0
  4. package/dist/connection/connection.js +495 -0
  5. package/dist/connection/connection.js.map +1 -0
  6. package/dist/connection/env.d.ts +2 -0
  7. package/dist/connection/env.js +16 -0
  8. package/dist/connection/env.js.map +1 -0
  9. package/dist/connection/index.d.ts +3 -0
  10. package/dist/connection/index.js +25 -0
  11. package/dist/connection/index.js.map +1 -0
  12. package/dist/connection/types.d.ts +25 -0
  13. package/dist/connection/types.js +3 -0
  14. package/dist/connection/types.js.map +1 -0
  15. package/dist/database.d.ts +9 -0
  16. package/dist/database.js +196 -0
  17. package/dist/database.js.map +1 -0
  18. package/dist/index.d.ts +20 -6
  19. package/dist/index.js +55 -8
  20. package/dist/index.js.map +1 -1
  21. package/dist/legacy/connection.d.ts +2 -0
  22. package/dist/legacy/connection.js +24 -0
  23. package/dist/legacy/connection.js.map +1 -0
  24. package/dist/legacy/index.d.ts +10 -0
  25. package/dist/legacy/index.js +93 -0
  26. package/dist/legacy/index.js.map +1 -0
  27. package/dist/legacy/model.d.ts +55 -0
  28. package/dist/legacy/model.js +282 -0
  29. package/dist/legacy/model.js.map +1 -0
  30. package/dist/legacy/pagination/index.d.ts +1 -0
  31. package/dist/legacy/pagination/index.js +18 -0
  32. package/dist/legacy/pagination/index.js.map +1 -0
  33. package/dist/legacy/pagination/pagination.d.ts +12 -0
  34. package/dist/legacy/pagination/pagination.js +85 -0
  35. package/dist/legacy/pagination/pagination.js.map +1 -0
  36. package/dist/legacy/search/customQuery.d.ts +13 -0
  37. package/dist/legacy/search/customQuery.js +73 -0
  38. package/dist/legacy/search/customQuery.js.map +1 -0
  39. package/dist/legacy/search/index.d.ts +1 -0
  40. package/dist/legacy/search/index.js +18 -0
  41. package/dist/legacy/search/index.js.map +1 -0
  42. package/dist/model/default-scope.d.ts +10 -0
  43. package/dist/model/default-scope.js +47 -0
  44. package/dist/model/default-scope.js.map +1 -0
  45. package/dist/model/hydrated-document.d.ts +30 -0
  46. package/dist/model/hydrated-document.js +118 -0
  47. package/dist/model/hydrated-document.js.map +1 -0
  48. package/dist/model/include.d.ts +33 -0
  49. package/dist/model/include.js +250 -0
  50. package/dist/model/include.js.map +1 -0
  51. package/dist/model/index.d.ts +192 -52
  52. package/dist/model/index.js +646 -172
  53. package/dist/model/index.js.map +1 -1
  54. package/dist/model/indexes.d.ts +18 -0
  55. package/dist/model/indexes.js +155 -0
  56. package/dist/model/indexes.js.map +1 -0
  57. package/dist/model/keyspace.d.ts +9 -0
  58. package/dist/model/keyspace.js +28 -0
  59. package/dist/model/keyspace.js.map +1 -0
  60. package/dist/model/read-helpers.d.ts +36 -0
  61. package/dist/model/read-helpers.js +275 -0
  62. package/dist/model/read-helpers.js.map +1 -0
  63. package/dist/model/safe-query.d.ts +23 -0
  64. package/dist/model/safe-query.js +138 -0
  65. package/dist/model/safe-query.js.map +1 -0
  66. package/dist/model/ttl.d.ts +9 -0
  67. package/dist/model/ttl.js +73 -0
  68. package/dist/model/ttl.js.map +1 -0
  69. package/dist/model/validation.d.ts +5 -0
  70. package/dist/model/validation.js +104 -0
  71. package/dist/model/validation.js.map +1 -0
  72. package/dist/model/write-helpers.d.ts +39 -0
  73. package/dist/model/write-helpers.js +245 -0
  74. package/dist/model/write-helpers.js.map +1 -0
  75. package/dist/next.d.ts +204 -0
  76. package/dist/next.js +1190 -0
  77. package/dist/next.js.map +1 -0
  78. package/dist/next.types.d.ts +1 -0
  79. package/dist/next.types.js +38 -0
  80. package/dist/next.types.js.map +1 -0
  81. package/dist/pagination/index.d.ts +1 -0
  82. package/dist/pagination/index.js +1 -0
  83. package/dist/pagination/index.js.map +1 -1
  84. package/dist/pagination/pagination.d.ts +1 -8
  85. package/dist/pagination/pagination.js +16 -29
  86. package/dist/pagination/pagination.js.map +1 -1
  87. package/dist/pagination/safe-pagination.d.ts +15 -0
  88. package/dist/pagination/safe-pagination.js +221 -0
  89. package/dist/pagination/safe-pagination.js.map +1 -0
  90. package/dist/pagination/types.d.ts +11 -0
  91. package/dist/pagination/types.js +3 -0
  92. package/dist/pagination/types.js.map +1 -0
  93. package/dist/search/customQuery.d.ts +10 -3
  94. package/dist/search/customQuery.js +17 -18
  95. package/dist/search/customQuery.js.map +1 -1
  96. package/dist/shared/common.model.js +2 -2
  97. package/dist/shared/common.model.js.map +1 -1
  98. package/dist/timeseries/index.d.ts +1 -0
  99. package/dist/timeseries/index.js +18 -0
  100. package/dist/timeseries/index.js.map +1 -0
  101. package/dist/timeseries/time-series-model.d.ts +60 -0
  102. package/dist/timeseries/time-series-model.js +267 -0
  103. package/dist/timeseries/time-series-model.js.map +1 -0
  104. package/dist/utils/awaitTo.d.ts +1 -1
  105. package/dist/utils/awaitTo.js +1 -1
  106. package/dist/utils/awaitTo.js.map +1 -1
  107. package/docs/beta-migration.md +175 -0
  108. package/docs/document-modeling.md +133 -0
  109. package/docs/next-primitives.md +81 -0
  110. package/legacy/index.js +1 -0
  111. package/legacy/package.json +4 -0
  112. package/next/index.js +1 -0
  113. package/next/package.json +4 -0
  114. package/package.json +18 -10
  115. package/dist/connection.d.ts +0 -42
  116. package/dist/connection.js +0 -156
  117. package/dist/connection.js.map +0 -1
@@ -0,0 +1,175 @@
1
+ # CouchSet Beta Migration
2
+
3
+ The beta release keeps the main `couchset` import on the legacy implementation so existing projects can upgrade safely. The modern implementation is available from `couchset/next`.
4
+
5
+ ```ts
6
+ import {Model as LegacyModel} from 'couchset';
7
+ import {Model as NextModel} from 'couchset/next';
8
+
9
+ const legacyUsers = new LegacyModel('User');
10
+ const nextUsers = new NextModel('User');
11
+ ```
12
+
13
+ Use `couchset` when an application depends on old pagination or custom query behavior. New work should use `couchset/next`.
14
+
15
+ Modern and legacy models share the same connection singleton. Initialize CouchSet once and use both model APIs side by side while migrating.
16
+
17
+ ```ts
18
+ import {couchset, Model} from 'couchset';
19
+ import {Model as NextModel} from 'couchset/next';
20
+
21
+ await couchset(args);
22
+
23
+ const legacyUsers = new Model('User');
24
+ const nextUsers = new NextModel('User');
25
+ ```
26
+
27
+ ## Connection Lifecycle
28
+
29
+ Models can be constructed before the Couchbase connection is ready. Model methods wait for the shared connection before touching the bucket or collection.
30
+
31
+ ```ts
32
+ import {couchset, Model, ready, health, ping, shutdown} from 'couchset/next';
33
+
34
+ const users = new Model('User');
35
+
36
+ await couchset({
37
+ connectionString: process.env.COUCHBASE_URL || 'couchbase://localhost',
38
+ username: process.env.COUCHBASE_USERNAME || 'admin',
39
+ password: process.env.COUCHBASE_PASSWORD || '1234',
40
+ bucketName: process.env.COUCHBASE_BUCKET || 'dev',
41
+ });
42
+
43
+ await ready();
44
+ await ping();
45
+ console.log(health());
46
+
47
+ await couchset.ready();
48
+
49
+ const user = await users.insert({userId: 'ceddy'});
50
+
51
+ await shutdown();
52
+ ```
53
+
54
+ Reconnect is enabled by default. It can be controlled with connection args or environment variables.
55
+
56
+ ```ts
57
+ await couchset({
58
+ connectionString: 'couchbase://localhost',
59
+ username: 'admin',
60
+ password: '1234',
61
+ bucketName: 'dev',
62
+ autoReconnect: true,
63
+ reconnectIntervalMs: 5000,
64
+ });
65
+ ```
66
+
67
+ Environment flags:
68
+
69
+ - `COUCHSET_RECONNECT`: defaults to enabled. Use `false`, `0`, or `no` to disable.
70
+ - `COUCHSET_RECONNECT_INTERVAL_MS`: reconnect and health-check interval in milliseconds. Defaults to `5000`.
71
+
72
+ `couchset/next` also exports env-based starter helpers:
73
+
74
+ ```ts
75
+ import {startCouchbase, startCouchbaseServerless} from 'couchset/next';
76
+
77
+ await startCouchbase();
78
+ await startCouchbaseServerless();
79
+ ```
80
+
81
+ The starters read `COUCHBASE_URL`, `COUCHBASE_BUCKET`, `COUCHBASE_USERNAME`, `COUCHBASE_PASSWORD`, and `COUCHBASE_PROXY`, and accept `CouchsetArgs` overrides.
82
+
83
+ ## Query Behavior
84
+
85
+ Modern query helpers throw by default. This makes production failures visible and keeps silent fallbacks explicit.
86
+
87
+ ```ts
88
+ const rows = await users.findMany({
89
+ where: {userId: {$eq: 'ceddy'}},
90
+ });
91
+
92
+ const page = await users.page({
93
+ where: {userId: {$eq: 'ceddy'}},
94
+ limit: 25,
95
+ page: 0,
96
+ });
97
+
98
+ const customRows = await users.queryRows(
99
+ `SELECT * FROM ${users.bucket()} WHERE userId=$userId LIMIT $limit`,
100
+ {userId: 'ceddy', limit: 25}
101
+ );
102
+ ```
103
+
104
+ If a caller intentionally wants the old empty-result fallback, pass `throwOnError: false`.
105
+
106
+ ```ts
107
+ const rows = await users.findMany({
108
+ where: {userId: {$eq: 'ceddy'}},
109
+ limit: 25,
110
+ page: 0,
111
+ throwOnError: false,
112
+ });
113
+ ```
114
+
115
+ ## Safer SQL++ Helpers
116
+
117
+ Use the model keyspace helpers instead of hardcoding bucket names.
118
+
119
+ ```ts
120
+ users.bucket(); // `dev`
121
+ users.from('u'); // `dev` AS u
122
+ ```
123
+
124
+ For scoped collections, `from()` includes the full keyspace.
125
+
126
+ ```ts
127
+ const audit = new Model('AuditEvent', {
128
+ scope: 'app',
129
+ collection: 'events',
130
+ });
131
+
132
+ audit.from('event'); // `dev`.`app`.`events` AS event
133
+ ```
134
+
135
+ ## New Model APIs
136
+
137
+ The modern path includes safer read, write, document, TTL, include, index, and time series helpers.
138
+
139
+ ```ts
140
+ await users.insert({id: 'user::1', userId: 'ceddy'});
141
+ await users.patchById('user::1', {$set: {email: 'ceddy@example.com'}});
142
+ await users.softDeleteById('user::1');
143
+ await users.restoreById('user::1');
144
+
145
+ const exists = await users.exists({where: {userId: {$eq: 'ceddy'}}});
146
+ const count = await users.count({where: {userId: {$eq: 'ceddy'}}});
147
+ ```
148
+
149
+ ## Removed Modern Model Aliases
150
+
151
+ The old method names belong to the default `couchset` entrypoint and the explicit `couchset/legacy` alias.
152
+
153
+ | Old method | Modern method |
154
+ | --- | --- |
155
+ | `create()` | `insert()` or `upsert()` |
156
+ | `findById()` | `getById()` |
157
+ | `updateById()` / `save()` | `replaceById()` or `patchById()` |
158
+ | `delete()` | `deleteById()` |
159
+ | `pagination()` | `findMany()` or `page()` |
160
+ | `customQuery()` | `queryRows()`, `queryOne()`, or `queryPage()` |
161
+
162
+ Index declarations can live on the model and be created at app boot.
163
+
164
+ ```ts
165
+ const users = new Model('User', {
166
+ indexes: [
167
+ {
168
+ name: 'idx_user_userId',
169
+ fields: ['userId'],
170
+ },
171
+ ],
172
+ });
173
+
174
+ await couchset.ensureIndexes();
175
+ ```
@@ -0,0 +1,133 @@
1
+ # Document Modeling
2
+
3
+ CouchSet keeps document modeling explicit. Large application objects should not
4
+ be the documents that list pages paginate over. Use one model for lightweight
5
+ list and routing metadata, then keep the full payload in a separate document
6
+ that is fetched by id when a detail view, offline view, export, or worker needs
7
+ the whole object.
8
+
9
+ ## Large Documents
10
+
11
+ Prefer this read shape:
12
+
13
+ - Fetch large documents by id with `getById()` or `findDocById()`.
14
+ - Page smaller metadata documents with `page()` or `findMany()`.
15
+ - Denormalize the fields needed for cards, tables, filters, sort order, auth,
16
+ and cleanup onto the paged metadata document.
17
+ - Store the heavy nested state, snapshots, logs, source data, or arrays in a
18
+ companion model.
19
+ - Join or fetch the companion document only after the caller has selected the
20
+ specific item that needs it.
21
+
22
+ This keeps list queries fast and predictable. A list page should not read a
23
+ large payload only to render a title, status, timestamp, and a few counters.
24
+
25
+ ## Example
26
+
27
+ ```ts
28
+ import {Model} from 'couchset/next';
29
+
30
+ type ReportSummary = {
31
+ id: string;
32
+ tenantId: string;
33
+ payloadId: string;
34
+ title: string;
35
+ status: 'draft' | 'running' | 'complete';
36
+ updatedAt: Date;
37
+ itemCount: number;
38
+ errorCount: number;
39
+ };
40
+
41
+ type ReportPayload = {
42
+ id: string;
43
+ reportId: string;
44
+ tenantId: string;
45
+ sourceRows: unknown[];
46
+ generatedSections: unknown[];
47
+ auditLog: unknown[];
48
+ };
49
+
50
+ const reports = new Model('Report', {
51
+ indexes: [
52
+ {
53
+ name: 'idx_report_tenant_updated',
54
+ fields: ['tenantId', 'updatedAt'],
55
+ },
56
+ ],
57
+ });
58
+
59
+ const reportPayloads = new Model('ReportPayload');
60
+ ```
61
+
62
+ Page the lightweight model:
63
+
64
+ ```ts
65
+ const page = await reports.page<ReportSummary>({
66
+ select: [
67
+ 'id',
68
+ 'tenantId',
69
+ 'payloadId',
70
+ 'title',
71
+ 'status',
72
+ 'updatedAt',
73
+ 'itemCount',
74
+ 'errorCount',
75
+ ],
76
+ where: {tenantId: {$eq: tenantId}},
77
+ orderBy: {updatedAt: 'DESC'},
78
+ limit: 25,
79
+ });
80
+ ```
81
+
82
+ Fetch the heavy document by id only when needed:
83
+
84
+ ```ts
85
+ const summary = await reports.getById<ReportSummary>(reportId);
86
+ const payload = await reportPayloads.getById<ReportPayload>(summary.payloadId);
87
+ ```
88
+
89
+ Use stable id formulas so the relationship is obvious and easy to backfill:
90
+
91
+ ```ts
92
+ const reportId = 'report::123';
93
+ const payloadId = `report-payload::${reportId}`;
94
+ ```
95
+
96
+ ## Joining
97
+
98
+ CouchSet includes can join related documents by key, but large payload joins
99
+ should be reserved for focused detail reads or small result sets.
100
+
101
+ ```ts
102
+ const report = await reports.findOne<ReportSummary & {payload: ReportPayload}>({
103
+ where: {id: {$eq: reportId}},
104
+ include: [
105
+ {
106
+ as: 'payload',
107
+ key: 'payloadId',
108
+ model: reportPayloads,
109
+ optional: true,
110
+ },
111
+ ],
112
+ });
113
+ ```
114
+
115
+ For list pages, keep the companion model out of the query and rely on summary
116
+ fields instead.
117
+
118
+ ## Migrations
119
+
120
+ When splitting an existing large document:
121
+
122
+ - Add the summary fields to the lightweight model first.
123
+ - Backfill companion payload documents with deterministic ids.
124
+ - Keep ownership fields such as `tenantId`, `workspaceId`, or `userId` on both
125
+ documents when they are needed for authorization or cleanup.
126
+ - Keep lifecycle fields such as `createdAt`, `updatedAt`, `deleted`, and
127
+ `deletedAt` on both documents if each document can be cleaned up separately.
128
+ - Switch list reads to the lightweight model before removing legacy heavy
129
+ fields from the list path.
130
+
131
+ The split is a read-model decision, not a CouchSet requirement. Keep a single
132
+ document when callers normally need the whole object and the document remains
133
+ small enough for the expected list and query volume.
@@ -0,0 +1,81 @@
1
+ # CouchSet next primitives
2
+
3
+ `couchset/next` adds a client-owned API without changing the singleton-based `Model` and `couchset` APIs. The new client is useful when an application needs dependency injection, isolated tests, model manifests, or an administrative bootstrap connection.
4
+
5
+ ```ts
6
+ import {createCouchsetClient, dateCodec, defineModel} from 'couchset/next';
7
+
8
+ const sessions = defineModel<{id: string; userId: string; expiresAt: Date}>({
9
+ name: 'Session',
10
+ scope: 'auth',
11
+ collection: 'sessions',
12
+ codecs: {expiresAt: dateCodec},
13
+ indexes: [{name: 'idx_session_user', fields: ['userId']}],
14
+ });
15
+
16
+ const db = createCouchsetClient({
17
+ connectionString: process.env.COUCHBASE_URL,
18
+ bucketName: 'app',
19
+ username: process.env.COUCHBASE_USERNAME,
20
+ password: process.env.COUCHBASE_PASSWORD,
21
+ models: [sessions],
22
+ });
23
+ ```
24
+
25
+ `defineModel()` only describes metadata; `db.model(sessions)` only binds and registers the model. Neither operation creates Couchbase resources. Legacy `new Model()` remains supported and continues to use the existing singleton.
26
+
27
+ ## Provisioning and dynamic models
28
+
29
+ Run administrative DDL explicitly, with credentials that have `Manage Scopes` and query-index permissions:
30
+
31
+ ```ts
32
+ await db.ensureCollections(); // creates missing named scopes, then collections
33
+ await db.ensureIndexes(); // CREATE INDEX IF NOT EXISTS only
34
+
35
+ // An explicitly dynamic model can provision itself.
36
+ const reports = await db.registerModel(reportDefinition, {
37
+ provision: {collections: true, indexes: true, waitForIndexes: true},
38
+ });
39
+ ```
40
+
41
+ Collection creation is idempotent: concurrent already-exists responses are accepted, while existing scopes and collections are never updated, renamed, or dropped. The built-in `_default` scope and collection are not created. A named collection in `_default` is supported. Conflicting collection settings declared for the same target fail instead of silently choosing one.
42
+
43
+ ## Transactions and CAS
44
+
45
+ ```ts
46
+ await db.transaction(async (tx) => {
47
+ const session = tx.model(sessions);
48
+ const found = await session.getById(id);
49
+ if (found) await session.remove(found);
50
+ });
51
+ ```
52
+
53
+ Transaction-bound models use only the SDK transaction attempt context. Couchbase may retry the callback, so it must not send an email, webhook, or other non-idempotent external side effect. Perform that work after the transaction resolves, or use an outbox/idempotency key. Commit-ambiguous errors are surfaced to the caller; CouchSet does not claim success or rerun external work.
54
+
55
+ For an optimistic single-document workflow:
56
+
57
+ ```ts
58
+ const current = await model.getWithCas(id);
59
+ await model.replaceIfCas(id, nextValue, current.cas);
60
+
61
+ const outcome = await model.consumeOnce(id, current.cas);
62
+ // {status: 'consumed'} | {status: 'missing'} | {status: 'conflict'}
63
+ ```
64
+
65
+ `consumeOnce` issues exactly one conditional remove. It does not re-read and retry with a fresh CAS.
66
+
67
+ ## Index drift
68
+
69
+ `ensureIndexes()` remains intentionally create-only. It never compares, changes, drops, or rebuilds an existing index. Operators can instead review a plan:
70
+
71
+ ```ts
72
+ const plan = await db.planIndexes();
73
+ await db.applyIndexPlan(plan); // create missing/versioned replacement indexes and wait for online
74
+ await db.applyIndexPlan(plan, {dropReplaced: true}); // explicit old-index removal after review
75
+ ```
76
+
77
+ When a live definition drifts, the plan creates a versioned physical replacement and waits for it to become online before an old index can be dropped. This avoids an unindexed interval and makes destructive cleanup an affirmative operator action.
78
+
79
+ ## Tests
80
+
81
+ `createCouchsetTestFixture(client, definition)` provisions a unique named scope/collection and returns an explicit `cleanup()` helper. Use it in test setup/teardown; fixture cleanup is the only helper that drops a resource.
@@ -0,0 +1 @@
1
+ module.exports = require('../dist/legacy');
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../dist/legacy/index.js",
3
+ "types": "../dist/legacy/index.d.ts"
4
+ }
package/next/index.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('../dist');
@@ -0,0 +1,4 @@
1
+ {
2
+ "main": "../dist/index.js",
3
+ "types": "../dist/index.d.ts"
4
+ }
package/package.json CHANGED
@@ -1,22 +1,26 @@
1
1
  {
2
2
  "name": "couchset",
3
- "version": "0.2.7",
3
+ "version": "0.4.0",
4
4
  "description": "Couchbase ORM",
5
5
  "private": false,
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
6
+ "main": "dist/legacy/index.js",
7
+ "types": "dist/legacy/index.d.ts",
8
8
  "files": [
9
+ "CHANGELOG.md",
9
10
  "docs/",
10
11
  "dist/",
12
+ "legacy/",
13
+ "next/",
11
14
  "register/",
12
15
  "LICENSE"
13
16
  ],
14
17
  "scripts": {
15
18
  "lint": "tslint \"src/**/*.ts\" --project tsconfig.json",
16
19
  "build": "rimraf dist && ./node_modules/.bin/tsc --skipLibCheck",
17
- "test": "mocha src/index.test.ts --exit",
20
+ "test": "npm run test:unit && npm run test:integration",
21
+ "test:unit": "mocha \"src/**/*.test.ts\" --ignore src/index.test.ts --ignore src/index.serverless.test.ts --exit",
22
+ "test:integration": "mocha src/index.test.ts --exit",
18
23
  "test:serverless": "mocha src/index.serverless.test.ts --exit",
19
- "test:auto": "mocha src/automation.test.ts --exit",
20
24
  "prepublishOnly": "npm run build",
21
25
  "eslint": "eslint ./src --fix --ext=ts"
22
26
  },
@@ -65,7 +69,7 @@
65
69
  "@types/dotenv": "^6.1.1",
66
70
  "@types/express": "^4.17.13",
67
71
  "@types/lodash": "^4.17.10",
68
- "@types/mocha": "^8.2.0",
72
+ "@types/mocha": "^10.0.10",
69
73
  "@types/node": "^10.0.3",
70
74
  "@types/source-map-support": "^0.4.0",
71
75
  "@types/uuid": "^8.3.0",
@@ -83,7 +87,7 @@
83
87
  "eslint-plugin-typescript": "^0.14.0",
84
88
  "husky": "^4.2.5",
85
89
  "lint-staged": "^10.1.7",
86
- "mocha": "^9.2.0",
90
+ "mocha": "^12.0.0",
87
91
  "prettier": "^2.0.5",
88
92
  "reflect-metadata": "^0.1.13",
89
93
  "rimraf": "^2.5.4",
@@ -94,10 +98,14 @@
94
98
  "typescript": "^5.6.3"
95
99
  },
96
100
  "dependencies": {
97
- "couchbase": "^4.4.2",
101
+ "couchbase": "^4.7.0",
98
102
  "couchbase-serverless": "^0.0.4",
99
103
  "debug": "^4.3.1",
100
- "lodash": "^4.17.21",
101
- "uuid": "^8.3.2"
104
+ "lodash": "^4.18.1",
105
+ "uuid": "^14.0.0"
106
+ },
107
+ "overrides": {
108
+ "serialize-javascript": "^7.0.5",
109
+ "js-yaml": "^4.1.1"
102
110
  }
103
111
  }
@@ -1,42 +0,0 @@
1
- import type { Collection, Cluster, Bucket } from 'couchbase';
2
- export interface CouchsetArgs {
3
- connectionString: string;
4
- bucketName: string;
5
- username: string;
6
- password: string;
7
- proxy?: string;
8
- }
9
- /**
10
- * CouchbaseConnection class
11
- * Only one CouchbaseConnection can exist that's why it's a singleton
12
- */
13
- export declare class CouchbaseConnection implements CouchsetArgs {
14
- private static _instance;
15
- bucket: Bucket;
16
- cluster: Cluster;
17
- connectionString: string;
18
- bucketName: string;
19
- username: string;
20
- password: string;
21
- static get Instance(): CouchbaseConnection;
22
- private constructor();
23
- /**
24
- * start
25
- */
26
- init: (args: CouchsetArgs) => Promise<CouchbaseConnection>;
27
- /**
28
- * start serverless start
29
- */
30
- initServerless: (args: CouchsetArgs) => CouchbaseConnection;
31
- /**
32
- * getCollection
33
- */
34
- getCollection: () => Collection;
35
- getCluster: () => Cluster;
36
- getBucket: () => string;
37
- /**
38
- * shutdown cluster
39
- */
40
- shutdown: () => Promise<void>;
41
- }
42
- export default CouchbaseConnection;
@@ -1,156 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
24
- };
25
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
26
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
27
- return new (P || (P = Promise))(function (resolve, reject) {
28
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
29
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
30
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
31
- step((generator = generator.apply(thisArg, _arguments || [])).next());
32
- });
33
- };
34
- var __generator = (this && this.__generator) || function (thisArg, body) {
35
- var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
36
- return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
37
- function verb(n) { return function (v) { return step([n, v]); }; }
38
- function step(op) {
39
- if (f) throw new TypeError("Generator is already executing.");
40
- while (g && (g = 0, op[0] && (_ = 0)), _) try {
41
- if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
42
- if (y = 0, t) op = [op[0] & 2, t.value];
43
- switch (op[0]) {
44
- case 0: case 1: t = op; break;
45
- case 4: _.label++; return { value: op[1], done: false };
46
- case 5: _.label++; y = op[1]; op = [0]; continue;
47
- case 7: op = _.ops.pop(); _.trys.pop(); continue;
48
- default:
49
- if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
50
- if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
51
- if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
52
- if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
53
- if (t[2]) _.ops.pop();
54
- _.trys.pop(); continue;
55
- }
56
- op = body.call(thisArg, _);
57
- } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
58
- if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
59
- }
60
- };
61
- Object.defineProperty(exports, "__esModule", { value: true });
62
- exports.CouchbaseConnection = void 0;
63
- var couchbase = __importStar(require("couchbase"));
64
- /**
65
- * CouchbaseConnection class
66
- * Only one CouchbaseConnection can exist that's why it's a singleton
67
- */
68
- var CouchbaseConnection = /** @class */ (function () {
69
- function CouchbaseConnection() {
70
- var _this = this;
71
- this.bucket = null;
72
- this.cluster = null;
73
- // Args
74
- this.connectionString = null;
75
- this.bucketName = null;
76
- this.username = null;
77
- this.password = null;
78
- /**
79
- * start
80
- */
81
- this.init = function (args) { return __awaiter(_this, void 0, void 0, function () {
82
- var connectionString, password, username, _a, bucketName, cluster;
83
- return __generator(this, function (_b) {
84
- switch (_b.label) {
85
- case 0:
86
- connectionString = args.connectionString, password = args.password, username = args.username, _a = args.bucketName, bucketName = _a === void 0 ? 'default' : _a;
87
- this.connectionString = connectionString;
88
- this.bucketName = bucketName;
89
- this.username = username;
90
- this.password = password;
91
- return [4 /*yield*/, couchbase.connect(connectionString, {
92
- username: username,
93
- password: password,
94
- })];
95
- case 1:
96
- cluster = _b.sent();
97
- this.cluster = cluster;
98
- this.bucket = this.cluster.bucket(bucketName);
99
- return [2 /*return*/, this];
100
- }
101
- });
102
- }); };
103
- /**
104
- * start serverless start
105
- */
106
- this.initServerless = function (args) {
107
- var connectionString = args.connectionString, password = args.password, username = args.username, _a = args.bucketName, bucketName = _a === void 0 ? 'default' : _a;
108
- _this.connectionString = connectionString;
109
- _this.bucketName = bucketName;
110
- _this.username = username;
111
- _this.password = password;
112
- var connectionOpt = {
113
- username: username,
114
- password: password,
115
- };
116
- if (args.proxy) {
117
- connectionOpt['proxy'] = args.proxy;
118
- }
119
- var cluster = new couchbase.Cluster(connectionString, connectionOpt);
120
- _this.cluster = cluster;
121
- _this.bucket = _this.cluster.bucket(bucketName);
122
- return _this;
123
- };
124
- /**
125
- * getCollection
126
- */
127
- this.getCollection = function () {
128
- return _this.bucket.defaultCollection();
129
- };
130
- this.getCluster = function () {
131
- return _this.cluster;
132
- };
133
- this.getBucket = function () {
134
- return _this.bucketName;
135
- };
136
- /**
137
- * shutdown cluster
138
- */
139
- this.shutdown = function () { return __awaiter(_this, void 0, void 0, function () {
140
- return __generator(this, function (_a) {
141
- return [2 /*return*/, this.cluster.close()];
142
- });
143
- }); };
144
- }
145
- Object.defineProperty(CouchbaseConnection, "Instance", {
146
- get: function () {
147
- return this._instance || (this._instance = new this());
148
- },
149
- enumerable: false,
150
- configurable: true
151
- });
152
- return CouchbaseConnection;
153
- }());
154
- exports.CouchbaseConnection = CouchbaseConnection;
155
- exports.default = CouchbaseConnection;
156
- //# sourceMappingURL=connection.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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","sourcesContent":["import type {Collection, Cluster, Bucket} from 'couchbase';\nimport * as couchbase from 'couchbase';\n\nexport interface CouchsetArgs {\n connectionString: string;\n bucketName: string;\n username: string;\n password: string;\n proxy?: string;\n}\n\n/**\n * CouchbaseConnection class\n * Only one CouchbaseConnection can exist that's why it's a singleton\n */\nexport class CouchbaseConnection implements CouchsetArgs {\n private static _instance: CouchbaseConnection;\n\n bucket: Bucket = null;\n cluster: Cluster = null;\n\n // Args\n connectionString: string = null;\n bucketName: string = null;\n username: string = null;\n password: string = null;\n\n public static get Instance(): CouchbaseConnection {\n return this._instance || (this._instance = new this());\n }\n\n private constructor() {}\n\n /**\n * start\n */\n public init = async (args: CouchsetArgs): Promise<CouchbaseConnection> => {\n const {connectionString, password, username, bucketName = 'default'} = args;\n\n this.connectionString = connectionString;\n this.bucketName = bucketName;\n this.username = username;\n this.password = password;\n\n const cluster = await couchbase.connect(connectionString, {\n username,\n password,\n });\n\n this.cluster = cluster as any;\n this.bucket = this.cluster.bucket(bucketName);\n\n return this;\n };\n\n /**\n * start serverless start\n */\n public initServerless = (args: CouchsetArgs): CouchbaseConnection => {\n const {connectionString, password, username, bucketName = 'default'} = args;\n\n this.connectionString = connectionString;\n this.bucketName = bucketName;\n this.username = username;\n this.password = password;\n\n const connectionOpt = {\n username,\n password,\n };\n\n if (args.proxy) {\n connectionOpt['proxy'] = args.proxy;\n }\n\n const cluster = new couchbase.Cluster(connectionString, connectionOpt);\n\n this.cluster = cluster as any;\n this.bucket = this.cluster.bucket(bucketName);\n\n return this;\n };\n\n /**\n * getCollection\n */\n public getCollection = (): Collection => {\n return this.bucket.defaultCollection();\n };\n\n public getCluster = (): Cluster => {\n return this.cluster;\n };\n\n public getBucket = (): string => {\n return this.bucketName;\n };\n\n /**\n * shutdown cluster\n */\n public shutdown = async (): Promise<void> => {\n return this.cluster.close();\n };\n}\n\nexport default CouchbaseConnection;\n"]}