@yottagraph-app/aether-instructions 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.
@@ -0,0 +1,175 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Simple CLI tool to query the Elemental API.
4
+ *
5
+ * Auth: set AUTH0_M2M_DEV_TOKEN as an env var or in your .env file.
6
+ * Server: set NUXT_PUBLIC_QUERY_SERVER_ADDRESS in your .env file.
7
+ */
8
+
9
+ const fs = require('fs');
10
+ const path = require('path');
11
+
12
+ const FORM_ENCODED_ENDPOINTS = ['/elemental/find', '/elemental/entities/properties'];
13
+
14
+ function loadEnvFile() {
15
+ // Try current working directory first (project .env), then script directory
16
+ const envPaths = [
17
+ path.join(process.cwd(), '.env'),
18
+ path.join(__dirname, '.env'),
19
+ ];
20
+
21
+ for (const envPath of envPaths) {
22
+ try {
23
+ const contents = fs.readFileSync(envPath, 'utf8');
24
+ for (const line of contents.split('\n')) {
25
+ const trimmed = line.trim();
26
+ if (!trimmed || trimmed.startsWith('#')) continue;
27
+ const eqIndex = trimmed.indexOf('=');
28
+ if (eqIndex === -1) continue;
29
+ const key = trimmed.slice(0, eqIndex).trim();
30
+ const value = trimmed.slice(eqIndex + 1).trim();
31
+ if (!process.env[key]) {
32
+ process.env[key] = value;
33
+ }
34
+ }
35
+ return; // Stop after first successful load
36
+ } catch {
37
+ // Try next path
38
+ }
39
+ }
40
+ }
41
+
42
+ function requiresFormEncoding(endpoint) {
43
+ return FORM_ENCODED_ENDPOINTS.some((e) => endpoint.startsWith(e));
44
+ }
45
+
46
+ function buildFormBody(endpoint, params) {
47
+ const formParams = new URLSearchParams();
48
+ for (const [key, value] of Object.entries(params)) {
49
+ if (typeof value === 'object') {
50
+ formParams.append(key, JSON.stringify(value));
51
+ } else {
52
+ formParams.append(key, String(value));
53
+ }
54
+ }
55
+ return formParams.toString();
56
+ }
57
+
58
+ async function main() {
59
+ loadEnvFile();
60
+
61
+ const args = process.argv.slice(2);
62
+
63
+ if (args.length < 2 || args[0] === '--help' || args[0] === '-h') {
64
+ console.log(`
65
+ Elemental API Query Tool
66
+
67
+ Usage:
68
+ node query-api.js <METHOD> <ENDPOINT> [JSON_PARAMS]
69
+
70
+ Examples:
71
+ # Search for entities (JSON body)
72
+ node query-api.js POST /entities/search '{"queries":[{"queryId":1,"query":"Apple"}],"maxResults":3}'
73
+
74
+ # Get entity details
75
+ node query-api.js GET /entities/00416400910670863867
76
+
77
+ # Find entities by expression (auto form-encoded)
78
+ node query-api.js POST /elemental/find '{"expression":{"type":"is_type","is_type":{"fid":10}},"limit":5}'
79
+
80
+ # Find entities with a property value
81
+ node query-api.js POST /elemental/find '{"expression":{"type":"comparison","comparison":{"operator":"has_value","pid":313}},"limit":10}'
82
+
83
+ # Get entity properties (auto form-encoded)
84
+ node query-api.js POST /elemental/entities/properties '{"eids":["00416400910670863867"],"pids":[8,313]}'
85
+
86
+ Environment variables (required):
87
+ AUTH0_M2M_DEV_TOKEN Bearer token for API auth
88
+ NUXT_PUBLIC_QUERY_SERVER_ADDRESS Query server URL (e.g. https://query.news.prod.g.lovelace.ai)
89
+
90
+ Setup:
91
+ 1. Get a dev token from your team
92
+ 2. Add AUTH0_M2M_DEV_TOKEN to your .env file or export in your shell
93
+ (NUXT_PUBLIC_QUERY_SERVER_ADDRESS should already be in your .env from project init)
94
+
95
+ Note: /elemental/find and /elemental/entities/properties require form-encoded bodies.
96
+ This tool automatically handles the encoding for these endpoints.
97
+ `);
98
+ process.exit(0);
99
+ }
100
+
101
+ const [method, endpoint, jsonParams] = args;
102
+
103
+ const token = process.env.AUTH0_M2M_DEV_TOKEN;
104
+ if (!token) {
105
+ console.error('Error: AUTH0_M2M_DEV_TOKEN is not set.');
106
+ console.error('Add it to your .env file or export it in your shell.');
107
+ console.error('Run: node query-api.js --help');
108
+ process.exit(1);
109
+ }
110
+
111
+ let params = {};
112
+ if (jsonParams) {
113
+ try {
114
+ params = JSON.parse(jsonParams);
115
+ } catch (err) {
116
+ console.error('Error: Invalid JSON parameters');
117
+ console.error(err.message);
118
+ process.exit(1);
119
+ }
120
+ }
121
+
122
+ const server = process.env.NUXT_PUBLIC_QUERY_SERVER_ADDRESS;
123
+ if (!server) {
124
+ console.error('Error: NUXT_PUBLIC_QUERY_SERVER_ADDRESS is not set.');
125
+ console.error('Add it to your .env file or export it in your shell.');
126
+ console.error('Run: node query-api.js --help');
127
+ process.exit(1);
128
+ }
129
+
130
+ const normalizedEndpoint = endpoint.startsWith('/') ? endpoint : '/' + endpoint;
131
+ let url = `${server}${normalizedEndpoint}`;
132
+
133
+ const useFormEncoding = requiresFormEncoding(normalizedEndpoint);
134
+ const fetchOptions = {
135
+ method: method.toUpperCase(),
136
+ headers: {
137
+ Authorization: `Bearer ${token}`,
138
+ 'Content-Type': useFormEncoding
139
+ ? 'application/x-www-form-urlencoded'
140
+ : 'application/json',
141
+ Accept: 'application/json',
142
+ },
143
+ };
144
+
145
+ if (method.toUpperCase() === 'GET' && Object.keys(params).length > 0) {
146
+ const queryString = new URLSearchParams(params).toString();
147
+ url = `${url}?${queryString}`;
148
+ } else if (method.toUpperCase() !== 'GET' && Object.keys(params).length > 0) {
149
+ if (useFormEncoding) {
150
+ fetchOptions.body = buildFormBody(normalizedEndpoint, params);
151
+ } else {
152
+ fetchOptions.body = JSON.stringify(params);
153
+ }
154
+ }
155
+
156
+ console.error(`\nšŸ“” ${method.toUpperCase()} ${url}\n`);
157
+
158
+ try {
159
+ const response = await fetch(url, fetchOptions);
160
+ const data = await response.json();
161
+
162
+ if (!response.ok) {
163
+ console.error(`āŒ Error ${response.status}: ${response.statusText}`);
164
+ } else {
165
+ console.error(`āœ… Success (${response.status})\n`);
166
+ }
167
+
168
+ console.log(JSON.stringify(data, null, 2));
169
+ } catch (err) {
170
+ console.error('āŒ Request failed:', err.message);
171
+ process.exit(1);
172
+ }
173
+ }
174
+
175
+ main();