@awi-protocol/site-sdk 0.1.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,14 @@
1
+ $ tsup src/index.ts --format cjs,esm --dts
2
+ CLI Building entry: src/index.ts
3
+ CLI tsup v8.5.1
4
+ CLI Target: node16
5
+ CJS Build start
6
+ ESM Build start
7
+ ESM dist\index.mjs 2.84 KB
8
+ ESM ⚡️ Build success in 42ms
9
+ CJS dist\index.js 3.45 KB
10
+ CJS ⚡️ Build success in 43ms
11
+ DTS Build start
12
+ DTS ⚡️ Build success in 2096ms
13
+ DTS dist\index.d.ts 1.27 KB
14
+ DTS dist\index.d.mts 1.27 KB
@@ -0,0 +1,51 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+
3
+ /**
4
+ * AWI Site SDK for JavaScript/TypeScript
5
+ *
6
+ * Build agent-native endpoints for your website.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { AWISite } from '@awi-protocol/site-sdk';
11
+ * import express from 'express';
12
+ *
13
+ * const app = new AWISite();
14
+ *
15
+ * app.route('/jobs/search', (req, res) => {
16
+ * const { query, location } = req.body.params;
17
+ * const jobs = db.search(query, location);
18
+ * res.json({ success: true, data: jobs });
19
+ * });
20
+ *
21
+ * // Mount on your Express app
22
+ * express().use('/awi', app.middleware());
23
+ * ```
24
+ */
25
+
26
+ interface RouteHandler {
27
+ (req: Request, res: Response, next: NextFunction): void;
28
+ }
29
+ interface RouteDefinition {
30
+ path: string;
31
+ methods: string[];
32
+ handler: RouteHandler;
33
+ parameters: Array<{
34
+ name: string;
35
+ type: string;
36
+ required: boolean;
37
+ }>;
38
+ returnType: string;
39
+ intent: string;
40
+ }
41
+ declare class AWISite {
42
+ private routes;
43
+ private axirRegistry;
44
+ route(path: string, handler: RouteHandler, methods?: string[]): this;
45
+ middleware(): any;
46
+ getRecipeBlueprint(domain: string, path: string): any;
47
+ generateManifest(): any;
48
+ private _extractParamNames;
49
+ }
50
+
51
+ export { AWISite, type RouteDefinition, type RouteHandler, AWISite as default };
@@ -0,0 +1,51 @@
1
+ import { Request, Response, NextFunction } from 'express';
2
+
3
+ /**
4
+ * AWI Site SDK for JavaScript/TypeScript
5
+ *
6
+ * Build agent-native endpoints for your website.
7
+ *
8
+ * @example
9
+ * ```typescript
10
+ * import { AWISite } from '@awi-protocol/site-sdk';
11
+ * import express from 'express';
12
+ *
13
+ * const app = new AWISite();
14
+ *
15
+ * app.route('/jobs/search', (req, res) => {
16
+ * const { query, location } = req.body.params;
17
+ * const jobs = db.search(query, location);
18
+ * res.json({ success: true, data: jobs });
19
+ * });
20
+ *
21
+ * // Mount on your Express app
22
+ * express().use('/awi', app.middleware());
23
+ * ```
24
+ */
25
+
26
+ interface RouteHandler {
27
+ (req: Request, res: Response, next: NextFunction): void;
28
+ }
29
+ interface RouteDefinition {
30
+ path: string;
31
+ methods: string[];
32
+ handler: RouteHandler;
33
+ parameters: Array<{
34
+ name: string;
35
+ type: string;
36
+ required: boolean;
37
+ }>;
38
+ returnType: string;
39
+ intent: string;
40
+ }
41
+ declare class AWISite {
42
+ private routes;
43
+ private axirRegistry;
44
+ route(path: string, handler: RouteHandler, methods?: string[]): this;
45
+ middleware(): any;
46
+ getRecipeBlueprint(domain: string, path: string): any;
47
+ generateManifest(): any;
48
+ private _extractParamNames;
49
+ }
50
+
51
+ export { AWISite, type RouteDefinition, type RouteHandler, AWISite as default };
package/dist/index.js ADDED
@@ -0,0 +1,112 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+
19
+ // src/index.ts
20
+ var index_exports = {};
21
+ __export(index_exports, {
22
+ AWISite: () => AWISite,
23
+ default: () => index_default
24
+ });
25
+ module.exports = __toCommonJS(index_exports);
26
+ var AWISite = class {
27
+ routes = /* @__PURE__ */ new Map();
28
+ axirRegistry = /* @__PURE__ */ new Map();
29
+ route(path, handler, methods = ["POST"]) {
30
+ const paramNames = this._extractParamNames(handler);
31
+ this.routes.set(path, {
32
+ path,
33
+ methods,
34
+ handler,
35
+ parameters: paramNames.map((name) => ({
36
+ name,
37
+ type: "string",
38
+ required: true
39
+ })),
40
+ returnType: "unknown",
41
+ intent: handler.name || "unnamed"
42
+ });
43
+ this.axirRegistry.set(path, {
44
+ intent: handler.name || "unnamed",
45
+ action: path.replace(/\//g, "_").replace(/^_/, ""),
46
+ parameters: paramNames,
47
+ semantic_context: {
48
+ native: true,
49
+ return_schema: "unknown"
50
+ }
51
+ });
52
+ return this;
53
+ }
54
+ middleware() {
55
+ const express = require("express");
56
+ const router = express.Router();
57
+ for (const [path, def] of this.routes) {
58
+ for (const method of def.methods) {
59
+ router[method.toLowerCase()](path, def.handler);
60
+ }
61
+ }
62
+ router.get("/manifest", (_req, res) => {
63
+ res.json(this.generateManifest());
64
+ });
65
+ router.post("/blueprint", (req, res) => {
66
+ const { path: routePath } = req.body;
67
+ const blueprint = this.getRecipeBlueprint(req.hostname, routePath);
68
+ res.json(blueprint);
69
+ });
70
+ return router;
71
+ }
72
+ getRecipeBlueprint(domain, path) {
73
+ const route = this.routes.get(path);
74
+ if (!route) {
75
+ throw new Error(`Route not found: ${path}`);
76
+ }
77
+ return {
78
+ recipe_id: `${domain.replace(/\./g, "_")}${path.replace(/\//g, "_")}_v1`,
79
+ target: `awi://${domain}${path}/v1`,
80
+ native: true,
81
+ endpoint: `https://${domain}/awi${path}`,
82
+ method: route.methods[0],
83
+ parameters: route.parameters,
84
+ return_schema: route.returnType,
85
+ axir: this.axirRegistry.get(path),
86
+ estimated_latency_ms: 50
87
+ };
88
+ }
89
+ generateManifest() {
90
+ return {
91
+ version: "1.0.0",
92
+ native: true,
93
+ routes: Array.from(this.routes.values()).map((route) => ({
94
+ path: route.path,
95
+ intent: route.intent,
96
+ parameters: route.parameters,
97
+ methods: route.methods
98
+ }))
99
+ };
100
+ }
101
+ _extractParamNames(handler) {
102
+ const fnStr = handler.toString();
103
+ const match = fnStr.match(/\(([^)]*)\)/);
104
+ if (!match) return [];
105
+ return match[1].split(",").map((p) => p.trim().split(/[=:\s]/)[0]).filter((p) => p && p !== "req" && p !== "res" && p !== "next");
106
+ }
107
+ };
108
+ var index_default = AWISite;
109
+ // Annotate the CommonJS export names for ESM import in node:
110
+ 0 && (module.exports = {
111
+ AWISite
112
+ });
package/dist/index.mjs ADDED
@@ -0,0 +1,95 @@
1
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
2
+ get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
3
+ }) : x)(function(x) {
4
+ if (typeof require !== "undefined") return require.apply(this, arguments);
5
+ throw Error('Dynamic require of "' + x + '" is not supported');
6
+ });
7
+
8
+ // src/index.ts
9
+ var AWISite = class {
10
+ routes = /* @__PURE__ */ new Map();
11
+ axirRegistry = /* @__PURE__ */ new Map();
12
+ route(path, handler, methods = ["POST"]) {
13
+ const paramNames = this._extractParamNames(handler);
14
+ this.routes.set(path, {
15
+ path,
16
+ methods,
17
+ handler,
18
+ parameters: paramNames.map((name) => ({
19
+ name,
20
+ type: "string",
21
+ required: true
22
+ })),
23
+ returnType: "unknown",
24
+ intent: handler.name || "unnamed"
25
+ });
26
+ this.axirRegistry.set(path, {
27
+ intent: handler.name || "unnamed",
28
+ action: path.replace(/\//g, "_").replace(/^_/, ""),
29
+ parameters: paramNames,
30
+ semantic_context: {
31
+ native: true,
32
+ return_schema: "unknown"
33
+ }
34
+ });
35
+ return this;
36
+ }
37
+ middleware() {
38
+ const express = __require("express");
39
+ const router = express.Router();
40
+ for (const [path, def] of this.routes) {
41
+ for (const method of def.methods) {
42
+ router[method.toLowerCase()](path, def.handler);
43
+ }
44
+ }
45
+ router.get("/manifest", (_req, res) => {
46
+ res.json(this.generateManifest());
47
+ });
48
+ router.post("/blueprint", (req, res) => {
49
+ const { path: routePath } = req.body;
50
+ const blueprint = this.getRecipeBlueprint(req.hostname, routePath);
51
+ res.json(blueprint);
52
+ });
53
+ return router;
54
+ }
55
+ getRecipeBlueprint(domain, path) {
56
+ const route = this.routes.get(path);
57
+ if (!route) {
58
+ throw new Error(`Route not found: ${path}`);
59
+ }
60
+ return {
61
+ recipe_id: `${domain.replace(/\./g, "_")}${path.replace(/\//g, "_")}_v1`,
62
+ target: `awi://${domain}${path}/v1`,
63
+ native: true,
64
+ endpoint: `https://${domain}/awi${path}`,
65
+ method: route.methods[0],
66
+ parameters: route.parameters,
67
+ return_schema: route.returnType,
68
+ axir: this.axirRegistry.get(path),
69
+ estimated_latency_ms: 50
70
+ };
71
+ }
72
+ generateManifest() {
73
+ return {
74
+ version: "1.0.0",
75
+ native: true,
76
+ routes: Array.from(this.routes.values()).map((route) => ({
77
+ path: route.path,
78
+ intent: route.intent,
79
+ parameters: route.parameters,
80
+ methods: route.methods
81
+ }))
82
+ };
83
+ }
84
+ _extractParamNames(handler) {
85
+ const fnStr = handler.toString();
86
+ const match = fnStr.match(/\(([^)]*)\)/);
87
+ if (!match) return [];
88
+ return match[1].split(",").map((p) => p.trim().split(/[=:\s]/)[0]).filter((p) => p && p !== "req" && p !== "res" && p !== "next");
89
+ }
90
+ };
91
+ var index_default = AWISite;
92
+ export {
93
+ AWISite,
94
+ index_default as default
95
+ };
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@awi-protocol/site-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Build agent-native endpoints for your website",
5
+ "main": "dist/index.js",
6
+ "module": "dist/index.mjs",
7
+ "types": "dist/index.d.ts",
8
+ "scripts": {
9
+ "build": "tsup src/index.ts --format cjs,esm --dts",
10
+ "test": "vitest run"
11
+ },
12
+ "keywords": [
13
+ "awi",
14
+ "agent-web-interface",
15
+ "site-sdk",
16
+ "ai-agent",
17
+ "browser-automation"
18
+ ],
19
+ "publishConfig": {
20
+ "access": "public"
21
+ },
22
+ "peerDependencies": {
23
+ "express": "^4.18.0"
24
+ },
25
+ "devDependencies": {
26
+ "@types/express": "^4.17.0",
27
+ "express": "^4.18.0",
28
+ "tsup": "^8.0.0",
29
+ "typescript": "^5.3.0"
30
+ }
31
+ }
package/src/index.ts ADDED
@@ -0,0 +1,147 @@
1
+ /**
2
+ * AWI Site SDK for JavaScript/TypeScript
3
+ *
4
+ * Build agent-native endpoints for your website.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { AWISite } from '@awi-protocol/site-sdk';
9
+ * import express from 'express';
10
+ *
11
+ * const app = new AWISite();
12
+ *
13
+ * app.route('/jobs/search', (req, res) => {
14
+ * const { query, location } = req.body.params;
15
+ * const jobs = db.search(query, location);
16
+ * res.json({ success: true, data: jobs });
17
+ * });
18
+ *
19
+ * // Mount on your Express app
20
+ * express().use('/awi', app.middleware());
21
+ * ```
22
+ */
23
+
24
+ import type { Request, Response, NextFunction } from 'express';
25
+
26
+ export interface RouteHandler {
27
+ (req: Request, res: Response, next: NextFunction): void;
28
+ }
29
+
30
+ export interface RouteDefinition {
31
+ path: string;
32
+ methods: string[];
33
+ handler: RouteHandler;
34
+ parameters: Array<{
35
+ name: string;
36
+ type: string;
37
+ required: boolean;
38
+ }>;
39
+ returnType: string;
40
+ intent: string;
41
+ }
42
+
43
+ export class AWISite {
44
+ private routes: Map<string, RouteDefinition> = new Map();
45
+ private axirRegistry: Map<string, any> = new Map();
46
+
47
+ route(path: string, handler: RouteHandler, methods: string[] = ['POST']): this {
48
+ // Extract parameter info from handler
49
+ const paramNames = this._extractParamNames(handler);
50
+
51
+ this.routes.set(path, {
52
+ path,
53
+ methods,
54
+ handler,
55
+ parameters: paramNames.map(name => ({
56
+ name,
57
+ type: 'string',
58
+ required: true,
59
+ })),
60
+ returnType: 'unknown',
61
+ intent: handler.name || 'unnamed',
62
+ });
63
+
64
+ this.axirRegistry.set(path, {
65
+ intent: handler.name || 'unnamed',
66
+ action: path.replace(/\//g, '_').replace(/^_/,''),
67
+ parameters: paramNames,
68
+ semantic_context: {
69
+ native: true,
70
+ return_schema: 'unknown',
71
+ },
72
+ });
73
+
74
+ return this;
75
+ }
76
+
77
+ middleware(): any {
78
+ const express = require('express');
79
+ const router = express.Router();
80
+
81
+ // Register all routes
82
+ for (const [path, def] of this.routes) {
83
+ for (const method of def.methods) {
84
+ router[method.toLowerCase()](path, def.handler);
85
+ }
86
+ }
87
+
88
+ // Add manifest endpoint
89
+ router.get('/manifest', (_req: Request, res: Response) => {
90
+ res.json(this.generateManifest());
91
+ });
92
+
93
+ // Add blueprint endpoint
94
+ router.post('/blueprint', (req: Request, res: Response) => {
95
+ const { path: routePath } = req.body;
96
+ const blueprint = this.getRecipeBlueprint(req.hostname, routePath);
97
+ res.json(blueprint);
98
+ });
99
+
100
+ return router;
101
+ }
102
+
103
+ getRecipeBlueprint(domain: string, path: string): any {
104
+ const route = this.routes.get(path);
105
+ if (!route) {
106
+ throw new Error(`Route not found: ${path}`);
107
+ }
108
+
109
+ return {
110
+ recipe_id: `${domain.replace(/\./g, '_')}${path.replace(/\//g, '_')}_v1`,
111
+ target: `awi://${domain}${path}/v1`,
112
+ native: true,
113
+ endpoint: `https://${domain}/awi${path}`,
114
+ method: route.methods[0],
115
+ parameters: route.parameters,
116
+ return_schema: route.returnType,
117
+ axir: this.axirRegistry.get(path),
118
+ estimated_latency_ms: 50,
119
+ };
120
+ }
121
+
122
+ generateManifest(): any {
123
+ return {
124
+ version: '1.0.0',
125
+ native: true,
126
+ routes: Array.from(this.routes.values()).map(route => ({
127
+ path: route.path,
128
+ intent: route.intent,
129
+ parameters: route.parameters,
130
+ methods: route.methods,
131
+ })),
132
+ };
133
+ }
134
+
135
+ private _extractParamNames(handler: Function): string[] {
136
+ const fnStr = handler.toString();
137
+ const match = fnStr.match(/\(([^)]*)\)/);
138
+ if (!match) return [];
139
+
140
+ return match[1]
141
+ .split(',')
142
+ .map(p => p.trim().split(/[=:\s]/)[0])
143
+ .filter(p => p && p !== 'req' && p !== 'res' && p !== 'next');
144
+ }
145
+ }
146
+
147
+ export default AWISite;