@nosana/endpoints 1.0.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.
@@ -0,0 +1,17 @@
1
+ import type { ExposedPort, JobDefinition, Operation } from '@nosana/types';
2
+ declare const createHash: (inputString: string, idLength?: number) => string;
3
+ declare const getExposePorts: (op: Operation<"container/run">) => ExposedPort[];
4
+ declare const isOpExposed: (op: Operation<"container/run">) => boolean;
5
+ declare const getExposeIdHash: (flowId: string, op: number | string, port: number | string) => string;
6
+ export type ExposedService = {
7
+ hash: string;
8
+ opIndex: number;
9
+ opId: string;
10
+ port: number | string;
11
+ hasHealthCheck: boolean;
12
+ };
13
+ declare const getJobExposeIdHash: (job: JobDefinition, flowId: string) => string[];
14
+ declare const getJobExposedServices: (job: JobDefinition, flowId: string) => ExposedService[];
15
+ export declare const isOperator: (v: string | number | object) => v is string;
16
+ export declare const isSpreadMarker: (v: string | number | object) => boolean;
17
+ export { getJobExposedServices, getJobExposeIdHash, getExposeIdHash, getExposePorts, isOpExposed, createHash, };
package/dist/index.js ADDED
@@ -0,0 +1,120 @@
1
+ import bs58 from 'bs58';
2
+ import nacl from 'tweetnacl';
3
+ const createHash = (inputString, idLength = 44) => {
4
+ const base58Encoded = bs58.encode(nacl.hash(new TextEncoder().encode(inputString)));
5
+ return base58Encoded.slice(0, idLength);
6
+ };
7
+ const isPrivate = (job) => {
8
+ return job.ops.some((op) => {
9
+ if (op.type !== 'container/run')
10
+ return false;
11
+ const args = op.args;
12
+ const expose = args.expose;
13
+ const isExposed = (Array.isArray(expose) && expose.length > 0) ||
14
+ typeof expose === 'number' ||
15
+ typeof expose === 'string';
16
+ return isExposed && args.private === true;
17
+ });
18
+ };
19
+ const getExposePorts = (op) => {
20
+ const expose = op.args.expose;
21
+ if (!expose)
22
+ return [];
23
+ const isOperator = (v) => typeof v === 'string' && /^%%(ops|globals)\.[^%]+%%$/.test(v);
24
+ const isSpreadMarker = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && '__spread__' in v;
25
+ if (typeof expose === 'number') {
26
+ return [{ port: expose, type: 'none' }];
27
+ }
28
+ if (typeof expose === 'string') {
29
+ // Skip dynamic operator strings; no concrete port to expose yet
30
+ if (isOperator(expose))
31
+ return [];
32
+ // Treat as concrete string port/range
33
+ return [{ port: expose, type: 'none' }];
34
+ }
35
+ if (Array.isArray(expose)) {
36
+ const out = [];
37
+ for (const e of expose) {
38
+ if (typeof e === 'number') {
39
+ out.push({ port: e, type: 'none' });
40
+ continue;
41
+ }
42
+ if (typeof e === 'string') {
43
+ if (isOperator(e))
44
+ continue; // skip dynamic
45
+ out.push({ port: e, type: 'none' });
46
+ continue;
47
+ }
48
+ if (isSpreadMarker(e)) {
49
+ // dynamic spread marker; skip for concrete expose list
50
+ continue;
51
+ }
52
+ // assume ExposedPort shape; rely on typing for port union
53
+ out.push(e);
54
+ }
55
+ return out;
56
+ }
57
+ return [];
58
+ };
59
+ const isOpExposed = (op) => {
60
+ const exposePorts = getExposePorts(op);
61
+ return exposePorts.length > 0;
62
+ };
63
+ const getExposeIdHash = (flowId, op, port) => {
64
+ const idLength = 44;
65
+ const inputString = `${op}:${port}:${flowId}`;
66
+ return createHash(inputString, idLength);
67
+ };
68
+ const getJobExposeIdHash = (job, flowId) => {
69
+ const hashes = [];
70
+ const privateMode = isPrivate(job);
71
+ if (privateMode) {
72
+ return ['private'];
73
+ }
74
+ Object.entries(job.ops).forEach(([, op], index) => {
75
+ if (isOpExposed(op)) {
76
+ const exposePorts = getExposePorts(op);
77
+ exposePorts.forEach((port) => {
78
+ const exposeId = getExposeIdHash(flowId, index, port.port);
79
+ hashes.push(exposeId);
80
+ });
81
+ }
82
+ });
83
+ return hashes;
84
+ };
85
+ const getJobExposedServices = (job, flowId) => {
86
+ const hashes = [];
87
+ const privateMode = isPrivate(job);
88
+ if (privateMode) {
89
+ return [
90
+ {
91
+ hash: 'private',
92
+ opIndex: -1,
93
+ opId: '',
94
+ port: -1,
95
+ hasHealthCheck: false,
96
+ },
97
+ ];
98
+ }
99
+ Object.entries(job.ops).forEach(([, op], index) => {
100
+ if (isOpExposed(op)) {
101
+ const exposePorts = getExposePorts(op);
102
+ exposePorts.forEach((port) => {
103
+ const exposeId = getExposeIdHash(flowId, index, port.port);
104
+ hashes.push({
105
+ hash: exposeId,
106
+ opIndex: index,
107
+ opId: op.id,
108
+ port: port.port,
109
+ hasHealthCheck: !!port.health_checks,
110
+ });
111
+ });
112
+ }
113
+ });
114
+ return hashes;
115
+ };
116
+ // Extract validation functions for reuse
117
+ export const isOperator = (v) => typeof v === 'string' && /^%%(ops|globals)\.[^%]+%%$/.test(v);
118
+ export const isSpreadMarker = (v) => typeof v === 'object' && v !== null && !Array.isArray(v) && '__spread__' in v;
119
+ export { getJobExposedServices, getJobExposeIdHash, getExposeIdHash, getExposePorts, isOpExposed, createHash, };
120
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@nosana/endpoints",
3
+ "version": "1.0.0",
4
+ "description": "Nosana endpoints module",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "author": "Nosana",
8
+ "license": "MIT",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc",
14
+ "build:watch": "tsc --watch",
15
+ "clean": "rm -rf dist",
16
+ "test": "vitest run",
17
+ "test:watch": "vitest",
18
+ "test:coverage": "vitest run --coverage",
19
+ "eslint": "eslint ./src",
20
+ "eslint:fix": "eslint --fix ./src",
21
+ "format": "npm run eslint",
22
+ "format:fix": "npm run eslint:fix",
23
+ "publish:public": "npm run build && npm publish --access public"
24
+ },
25
+ "devDependencies": {
26
+ "@types/node": "^24.0.14",
27
+ "@typescript-eslint/eslint-plugin": "^8.38.0",
28
+ "@typescript-eslint/parser": "^8.38.0",
29
+ "@vitest/coverage-v8": "^4.0.3",
30
+ "eslint": "^9.31.0",
31
+ "eslint-plugin-import": "^2.32.0",
32
+ "husky": "^9.1.7",
33
+ "typescript": "^5.8.3",
34
+ "vitest": "^4.0.3"
35
+ },
36
+ "dependencies": {
37
+ "@nosana/types": "^0.1.6",
38
+ "bs58": "^5.0.0",
39
+ "tweetnacl": "^1.0.3"
40
+ }
41
+ }