within-sdk 1.0.0 → 1.0.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.
@@ -1,201 +1,201 @@
1
- "use strict";
2
- import { randomBytes } from "node:crypto";
3
- import { inspect } from "node:util";
4
- import { promisify } from "node:util";
5
- import * as base62 from "./base62.js";
6
-
7
- const customInspectSymbol = inspect.custom;
8
-
9
- const asyncRandomBytes = promisify(randomBytes);
10
-
11
- // KSUID's epoch starts more recently so that the 32-bit number space gives a
12
- // significantly higher useful lifetime of around 136 years from March 2014.
13
- // This number (14e11) was picked to be easy to remember.
14
- const EPOCH_IN_MS = 14e11;
15
-
16
- const MAX_TIME_IN_MS = 1e3 * (2 ** 32 - 1) + EPOCH_IN_MS;
17
-
18
- // Timestamp is a uint32
19
- const TIMESTAMP_BYTE_LENGTH = 4;
20
-
21
- // Payload is 16-bytes
22
- const PAYLOAD_BYTE_LENGTH = 16;
23
-
24
- // KSUIDs are 20 bytes when binary encoded
25
- const BYTE_LENGTH = TIMESTAMP_BYTE_LENGTH + PAYLOAD_BYTE_LENGTH;
26
-
27
- // The length of a KSUID when string (base62) encoded
28
- const STRING_ENCODED_LENGTH = 27;
29
-
30
- const TIME_IN_MS_ASSERTION =
31
- `Valid KSUID timestamps must be in milliseconds since ${new Date(0).toISOString()},
32
- no earlier than ${new Date(EPOCH_IN_MS).toISOString()} and no later than ${new Date(MAX_TIME_IN_MS).toISOString()}
33
- `
34
- .trim()
35
- .replace(/(\n|\s)+/g, " ")
36
- .replace(/\.000Z/g, "Z");
37
-
38
- const VALID_ENCODING_ASSERTION = `Valid encoded KSUIDs are ${STRING_ENCODED_LENGTH} characters`;
39
-
40
- const VALID_BUFFER_ASSERTION = `Valid KSUID buffers are ${BYTE_LENGTH} bytes`;
41
-
42
- const VALID_PAYLOAD_ASSERTION = `Valid KSUID payloads are ${PAYLOAD_BYTE_LENGTH} bytes`;
43
-
44
- function fromParts(timeInMs, payload) {
45
- const timestamp = Math.floor((timeInMs - EPOCH_IN_MS) / 1e3);
46
- const timestampBuffer = Buffer.allocUnsafe(TIMESTAMP_BYTE_LENGTH);
47
- timestampBuffer.writeUInt32BE(timestamp, 0);
48
-
49
- return Buffer.concat([timestampBuffer, payload], BYTE_LENGTH);
50
- }
51
-
52
- const bufferLookup = new WeakMap();
53
-
54
- class KSUID {
55
- constructor(buffer) {
56
- if (!KSUID.isValid(buffer)) {
57
- throw new TypeError(VALID_BUFFER_ASSERTION);
58
- }
59
-
60
- bufferLookup.set(this, buffer);
61
- Object.defineProperty(this, "buffer", {
62
- enumerable: true,
63
- get() {
64
- return Buffer.from(buffer);
65
- },
66
- });
67
- }
68
-
69
- get raw() {
70
- return Buffer.from(bufferLookup.get(this).slice(0));
71
- }
72
-
73
- get date() {
74
- return new Date(1e3 * this.timestamp + EPOCH_IN_MS);
75
- }
76
-
77
- get timestamp() {
78
- return bufferLookup.get(this).readUInt32BE(0);
79
- }
80
-
81
- get payload() {
82
- const payload = bufferLookup
83
- .get(this)
84
- .slice(TIMESTAMP_BYTE_LENGTH, BYTE_LENGTH);
85
- return Buffer.from(payload);
86
- }
87
-
88
- get string() {
89
- const encoded = base62.encode(
90
- bufferLookup.get(this),
91
- STRING_ENCODED_LENGTH,
92
- );
93
- return encoded.padStart(STRING_ENCODED_LENGTH, "0");
94
- }
95
-
96
- compare(other) {
97
- if (!bufferLookup.has(other)) {
98
- return 0;
99
- }
100
-
101
- return bufferLookup
102
- .get(this)
103
- .compare(bufferLookup.get(other), 0, BYTE_LENGTH);
104
- }
105
-
106
- equals(other) {
107
- return (
108
- this === other || (bufferLookup.has(other) && this.compare(other) === 0)
109
- );
110
- }
111
-
112
- toString() {
113
- return `${this[Symbol.toStringTag]} { ${this.string} }`;
114
- }
115
-
116
- toJSON() {
117
- return this.string;
118
- }
119
-
120
- [customInspectSymbol]() {
121
- return this.toString();
122
- }
123
-
124
- static async random(time = Date.now()) {
125
- const payload = await asyncRandomBytes(PAYLOAD_BYTE_LENGTH);
126
- return new KSUID(fromParts(Number(time), payload));
127
- }
128
-
129
- static randomSync(time = Date.now()) {
130
- const payload = randomBytes(PAYLOAD_BYTE_LENGTH);
131
- return new KSUID(fromParts(Number(time), payload));
132
- }
133
-
134
- static fromParts(timeInMs, payload) {
135
- if (
136
- !Number.isInteger(timeInMs) ||
137
- timeInMs < EPOCH_IN_MS ||
138
- timeInMs > MAX_TIME_IN_MS
139
- ) {
140
- throw new TypeError(TIME_IN_MS_ASSERTION);
141
- }
142
- if (
143
- !Buffer.isBuffer(payload) ||
144
- payload.byteLength !== PAYLOAD_BYTE_LENGTH
145
- ) {
146
- throw new TypeError(VALID_PAYLOAD_ASSERTION);
147
- }
148
-
149
- return new KSUID(fromParts(timeInMs, payload));
150
- }
151
-
152
- static isValid(buffer) {
153
- return Buffer.isBuffer(buffer) && buffer.byteLength === BYTE_LENGTH;
154
- }
155
-
156
- static parse(string) {
157
- if (string.length !== STRING_ENCODED_LENGTH) {
158
- throw new TypeError(VALID_ENCODING_ASSERTION);
159
- }
160
-
161
- const decoded = base62.decode(string, BYTE_LENGTH);
162
- if (decoded.byteLength === BYTE_LENGTH) {
163
- return new KSUID(decoded);
164
- }
165
-
166
- const buffer = Buffer.allocUnsafe(BYTE_LENGTH);
167
- const padEnd = BYTE_LENGTH - decoded.byteLength;
168
- buffer.fill(0, 0, padEnd);
169
- decoded.copy(buffer, padEnd);
170
- return new KSUID(buffer);
171
- }
172
- }
173
- Object.defineProperty(KSUID.prototype, Symbol.toStringTag, { value: "KSUID" });
174
- // A string-encoded maximum value for a KSUID
175
- Object.defineProperty(KSUID, "MAX_STRING_ENCODED", {
176
- value: "aWgEPTl1tmebfsQzFP4bxwgy80V",
177
- });
178
- // A string-encoded minimum value for a KSUID
179
- Object.defineProperty(KSUID, "MIN_STRING_ENCODED", {
180
- value: "000000000000000000000000000",
181
- });
182
-
183
- // Add prefix functionality
184
- KSUID.withPrefix = function (prefix) {
185
- return {
186
- random: async (time = Date.now()) => {
187
- const ksuid = await KSUID.random(time);
188
- return `${prefix}_${ksuid.string}`;
189
- },
190
- randomSync: (time = Date.now()) => {
191
- const ksuid = KSUID.randomSync(time);
192
- return `${prefix}_${ksuid.string}`;
193
- },
194
- fromParts: (timeInMs, payload) => {
195
- const ksuid = KSUID.fromParts(timeInMs, payload);
196
- return `${prefix}_${ksuid.string}`;
197
- },
198
- };
199
- };
200
-
201
- export default KSUID;
1
+ "use strict";
2
+ import { randomBytes } from "node:crypto";
3
+ import { inspect } from "node:util";
4
+ import { promisify } from "node:util";
5
+ import * as base62 from "./base62.js";
6
+
7
+ const customInspectSymbol = inspect.custom;
8
+
9
+ const asyncRandomBytes = promisify(randomBytes);
10
+
11
+ // KSUID's epoch starts more recently so that the 32-bit number space gives a
12
+ // significantly higher useful lifetime of around 136 years from March 2014.
13
+ // This number (14e11) was picked to be easy to remember.
14
+ const EPOCH_IN_MS = 14e11;
15
+
16
+ const MAX_TIME_IN_MS = 1e3 * (2 ** 32 - 1) + EPOCH_IN_MS;
17
+
18
+ // Timestamp is a uint32
19
+ const TIMESTAMP_BYTE_LENGTH = 4;
20
+
21
+ // Payload is 16-bytes
22
+ const PAYLOAD_BYTE_LENGTH = 16;
23
+
24
+ // KSUIDs are 20 bytes when binary encoded
25
+ const BYTE_LENGTH = TIMESTAMP_BYTE_LENGTH + PAYLOAD_BYTE_LENGTH;
26
+
27
+ // The length of a KSUID when string (base62) encoded
28
+ const STRING_ENCODED_LENGTH = 27;
29
+
30
+ const TIME_IN_MS_ASSERTION =
31
+ `Valid KSUID timestamps must be in milliseconds since ${new Date(0).toISOString()},
32
+ no earlier than ${new Date(EPOCH_IN_MS).toISOString()} and no later than ${new Date(MAX_TIME_IN_MS).toISOString()}
33
+ `
34
+ .trim()
35
+ .replace(/(\n|\s)+/g, " ")
36
+ .replace(/\.000Z/g, "Z");
37
+
38
+ const VALID_ENCODING_ASSERTION = `Valid encoded KSUIDs are ${STRING_ENCODED_LENGTH} characters`;
39
+
40
+ const VALID_BUFFER_ASSERTION = `Valid KSUID buffers are ${BYTE_LENGTH} bytes`;
41
+
42
+ const VALID_PAYLOAD_ASSERTION = `Valid KSUID payloads are ${PAYLOAD_BYTE_LENGTH} bytes`;
43
+
44
+ function fromParts(timeInMs, payload) {
45
+ const timestamp = Math.floor((timeInMs - EPOCH_IN_MS) / 1e3);
46
+ const timestampBuffer = Buffer.allocUnsafe(TIMESTAMP_BYTE_LENGTH);
47
+ timestampBuffer.writeUInt32BE(timestamp, 0);
48
+
49
+ return Buffer.concat([timestampBuffer, payload], BYTE_LENGTH);
50
+ }
51
+
52
+ const bufferLookup = new WeakMap();
53
+
54
+ class KSUID {
55
+ constructor(buffer) {
56
+ if (!KSUID.isValid(buffer)) {
57
+ throw new TypeError(VALID_BUFFER_ASSERTION);
58
+ }
59
+
60
+ bufferLookup.set(this, buffer);
61
+ Object.defineProperty(this, "buffer", {
62
+ enumerable: true,
63
+ get() {
64
+ return Buffer.from(buffer);
65
+ },
66
+ });
67
+ }
68
+
69
+ get raw() {
70
+ return Buffer.from(bufferLookup.get(this).slice(0));
71
+ }
72
+
73
+ get date() {
74
+ return new Date(1e3 * this.timestamp + EPOCH_IN_MS);
75
+ }
76
+
77
+ get timestamp() {
78
+ return bufferLookup.get(this).readUInt32BE(0);
79
+ }
80
+
81
+ get payload() {
82
+ const payload = bufferLookup
83
+ .get(this)
84
+ .slice(TIMESTAMP_BYTE_LENGTH, BYTE_LENGTH);
85
+ return Buffer.from(payload);
86
+ }
87
+
88
+ get string() {
89
+ const encoded = base62.encode(
90
+ bufferLookup.get(this),
91
+ STRING_ENCODED_LENGTH,
92
+ );
93
+ return encoded.padStart(STRING_ENCODED_LENGTH, "0");
94
+ }
95
+
96
+ compare(other) {
97
+ if (!bufferLookup.has(other)) {
98
+ return 0;
99
+ }
100
+
101
+ return bufferLookup
102
+ .get(this)
103
+ .compare(bufferLookup.get(other), 0, BYTE_LENGTH);
104
+ }
105
+
106
+ equals(other) {
107
+ return (
108
+ this === other || (bufferLookup.has(other) && this.compare(other) === 0)
109
+ );
110
+ }
111
+
112
+ toString() {
113
+ return `${this[Symbol.toStringTag]} { ${this.string} }`;
114
+ }
115
+
116
+ toJSON() {
117
+ return this.string;
118
+ }
119
+
120
+ [customInspectSymbol]() {
121
+ return this.toString();
122
+ }
123
+
124
+ static async random(time = Date.now()) {
125
+ const payload = await asyncRandomBytes(PAYLOAD_BYTE_LENGTH);
126
+ return new KSUID(fromParts(Number(time), payload));
127
+ }
128
+
129
+ static randomSync(time = Date.now()) {
130
+ const payload = randomBytes(PAYLOAD_BYTE_LENGTH);
131
+ return new KSUID(fromParts(Number(time), payload));
132
+ }
133
+
134
+ static fromParts(timeInMs, payload) {
135
+ if (
136
+ !Number.isInteger(timeInMs) ||
137
+ timeInMs < EPOCH_IN_MS ||
138
+ timeInMs > MAX_TIME_IN_MS
139
+ ) {
140
+ throw new TypeError(TIME_IN_MS_ASSERTION);
141
+ }
142
+ if (
143
+ !Buffer.isBuffer(payload) ||
144
+ payload.byteLength !== PAYLOAD_BYTE_LENGTH
145
+ ) {
146
+ throw new TypeError(VALID_PAYLOAD_ASSERTION);
147
+ }
148
+
149
+ return new KSUID(fromParts(timeInMs, payload));
150
+ }
151
+
152
+ static isValid(buffer) {
153
+ return Buffer.isBuffer(buffer) && buffer.byteLength === BYTE_LENGTH;
154
+ }
155
+
156
+ static parse(string) {
157
+ if (string.length !== STRING_ENCODED_LENGTH) {
158
+ throw new TypeError(VALID_ENCODING_ASSERTION);
159
+ }
160
+
161
+ const decoded = base62.decode(string, BYTE_LENGTH);
162
+ if (decoded.byteLength === BYTE_LENGTH) {
163
+ return new KSUID(decoded);
164
+ }
165
+
166
+ const buffer = Buffer.allocUnsafe(BYTE_LENGTH);
167
+ const padEnd = BYTE_LENGTH - decoded.byteLength;
168
+ buffer.fill(0, 0, padEnd);
169
+ decoded.copy(buffer, padEnd);
170
+ return new KSUID(buffer);
171
+ }
172
+ }
173
+ Object.defineProperty(KSUID.prototype, Symbol.toStringTag, { value: "KSUID" });
174
+ // A string-encoded maximum value for a KSUID
175
+ Object.defineProperty(KSUID, "MAX_STRING_ENCODED", {
176
+ value: "aWgEPTl1tmebfsQzFP4bxwgy80V",
177
+ });
178
+ // A string-encoded minimum value for a KSUID
179
+ Object.defineProperty(KSUID, "MIN_STRING_ENCODED", {
180
+ value: "000000000000000000000000000",
181
+ });
182
+
183
+ // Add prefix functionality
184
+ KSUID.withPrefix = function (prefix) {
185
+ return {
186
+ random: async (time = Date.now()) => {
187
+ const ksuid = await KSUID.random(time);
188
+ return `${prefix}_${ksuid.string}`;
189
+ },
190
+ randomSync: (time = Date.now()) => {
191
+ const ksuid = KSUID.randomSync(time);
192
+ return `${prefix}_${ksuid.string}`;
193
+ },
194
+ fromParts: (timeInMs, payload) => {
195
+ const ksuid = KSUID.fromParts(timeInMs, payload);
196
+ return `${prefix}_${ksuid.string}`;
197
+ },
198
+ };
199
+ };
200
+
201
+ export default KSUID;
package/package.json CHANGED
@@ -1,43 +1,43 @@
1
- {
2
- "name": "within-sdk",
3
- "version": "1.0.0",
4
- "description": "Within SDK for MCP analytics, workflow intelligence, and qualified opportunities.",
5
- "type": "module",
6
- "main": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js"
12
- }
13
- },
14
- "files": [
15
- "dist",
16
- "README.md",
17
- "LICENSE"
18
- ],
19
- "keywords": [
20
- "mcp",
21
- "model-context-protocol",
22
- "within",
23
- "sdk",
24
- "workflow",
25
- "qualification"
26
- ],
27
- "license": "MIT",
28
- "homepage": "https://getwith.in",
29
- "scripts": {
30
- "build": "tsc -p tsconfig.json && rm -rf dist/thirdparty && cp -R src/thirdparty dist/thirdparty",
31
- "prepublishOnly": "npm run build",
32
- "test": "tsx --test src/*.test.ts"
33
- },
34
- "peerDependencies": {
35
- "@modelcontextprotocol/sdk": ">=1.11"
36
- },
37
- "devDependencies": {
38
- "@modelcontextprotocol/sdk": "~1.24.2",
39
- "@types/node": "^25.5.0",
40
- "tsx": "^4.21.0",
41
- "typescript": "^6.0.2"
42
- }
43
- }
1
+ {
2
+ "name": "within-sdk",
3
+ "version": "1.0.1",
4
+ "description": "Within SDK for MCP analytics, workflow intelligence, and qualified opportunities.",
5
+ "type": "module",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md",
17
+ "LICENSE"
18
+ ],
19
+ "keywords": [
20
+ "mcp",
21
+ "model-context-protocol",
22
+ "within",
23
+ "sdk",
24
+ "workflow",
25
+ "qualification"
26
+ ],
27
+ "license": "MIT",
28
+ "homepage": "https://getwith.in",
29
+ "scripts": {
30
+ "build": "tsc -p tsconfig.json && rm -rf dist/thirdparty && cp -R src/thirdparty dist/thirdparty",
31
+ "prepublishOnly": "npm run build",
32
+ "test": "tsx --test src/*.test.ts"
33
+ },
34
+ "peerDependencies": {
35
+ "@modelcontextprotocol/sdk": ">=1.11"
36
+ },
37
+ "devDependencies": {
38
+ "@modelcontextprotocol/sdk": "~1.24.2",
39
+ "@types/node": "^25.5.0",
40
+ "tsx": "^4.21.0",
41
+ "typescript": "^6.0.2"
42
+ }
43
+ }
@@ -1,40 +0,0 @@
1
- /**
2
- * With.in MCP Auth SDK — sealed request handler.
3
- *
4
- * Exposes ONE function, `createWithinHandler`, that returns a handler with:
5
- * - `mcpHandler(req, res)` — node HTTP handler for the MCP endpoint
6
- * - `subscribeHandler(req,res)` — node HTTP handler for the /subscribe route
7
- * - `vendorSlug`, `authServerUrl` — readonly fields for logging
8
- *
9
- * Everything else — token validation, tool-call reporting, trial-exhausted
10
- * gating, subscriber cross-check + auto conversion, transport construction
11
- * and session caching, network-tool injection, auth propagation into tool
12
- * handlers — is hidden inside `mcpHandler`. Vendors cannot accidentally
13
- * skip a step.
14
- */
15
- export interface WithinRequestLike {
16
- url?: string;
17
- method?: string;
18
- headers: Record<string, string | string[] | undefined>;
19
- on(event: 'data', listener: (chunk: any) => void): unknown;
20
- on(event: 'end', listener: () => void): unknown;
21
- }
22
- export interface WithinResponseLike {
23
- writeHead(status: number, headers?: Record<string, string>): unknown;
24
- write(chunk: any): unknown;
25
- end(body?: string): unknown;
26
- }
27
- import type { WithinConfig } from './types.js';
28
- export interface WithinHandler {
29
- mcpHandler: (req: WithinRequestLike, res: WithinResponseLike) => Promise<void>;
30
- subscribeHandler: (req: WithinRequestLike, res: WithinResponseLike) => Promise<void>;
31
- /** Serves RFC 9728 Protected Resource Metadata at the vendor's well-known
32
- * path. Derives `resource` from the incoming Host + X-Forwarded-Proto so
33
- * the byte-equality check in §3.3 passes no matter what hostname the
34
- * vendor runs under. Vendors route GET /.well-known/oauth-protected-resource
35
- * through this handler instead of hand-rolling their own JSON. */
36
- prmHandler: (req: WithinRequestLike, res: WithinResponseLike) => void;
37
- readonly vendorSlug: string;
38
- readonly authServerUrl: string;
39
- }
40
- export declare function createWithinHandler(config: WithinConfig): WithinHandler;