@proveanything/smartlinks 1.0.28 → 1.0.30
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.
- package/API_SUMMARY.md +672 -213
- package/README.md +430 -0
- package/dist/api/collection.js +1 -1
- package/dist/http.d.ts +5 -3
- package/dist/http.js +5 -3
- package/package.json +19 -3
- package/build-docs.ts +0 -69
- package/debug.log +0 -6
- package/examples/browser-demo.html +0 -43
- package/examples/node-demo.ts +0 -50
- package/examples/react-demo.tsx +0 -58
- package/generate-api-summary.js +0 -279
- package/generate-api-summary.ts +0 -83
- package/openapi.yaml +0 -130
- package/scripts/copy-docs.js +0 -11
- package/src/api/appConfiguration.ts +0 -104
- package/src/api/asset.ts +0 -133
- package/src/api/attestation.ts +0 -69
- package/src/api/auth.ts +0 -103
- package/src/api/batch.ts +0 -173
- package/src/api/claimSet.ts +0 -131
- package/src/api/collection.ts +0 -117
- package/src/api/crate.ts +0 -43
- package/src/api/form.ts +0 -57
- package/src/api/index.ts +0 -14
- package/src/api/product.ts +0 -128
- package/src/api/proof.ts +0 -32
- package/src/api/serialNumber.ts +0 -0
- package/src/api/variant.ts +0 -173
- package/src/http.ts +0 -363
- package/src/index.ts +0 -29
- package/src/types/appConfiguration.ts +0 -12
- package/src/types/asset.ts +0 -9
- package/src/types/attestation.ts +0 -19
- package/src/types/batch.ts +0 -15
- package/src/types/collection.ts +0 -68
- package/src/types/error.ts +0 -10
- package/src/types/index.ts +0 -11
- package/src/types/product.ts +0 -33
- package/src/types/proof.ts +0 -20
- package/src/types/serialNumber.ts +0 -0
- package/src/types/variant.ts +0 -15
- package/tsconfig.json +0 -15
- package/typedoc.json +0 -18
package/examples/react-demo.tsx
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState } from 'react';
|
|
2
|
-
import { initializeApi } from '../dist/index';
|
|
3
|
-
import { collection } from '../dist/api/collection';
|
|
4
|
-
import { product } from '../dist/api/product';
|
|
5
|
-
import { proof } from '../dist/api/proof';
|
|
6
|
-
import type { CollectionResponse } from '../dist/types/collection';
|
|
7
|
-
import type { ProductResponse } from '../dist/types/product';
|
|
8
|
-
import type { ProofResponse } from '../dist/types/proof';
|
|
9
|
-
|
|
10
|
-
// You can provide either or both of these values:
|
|
11
|
-
const apiKey = 'YOUR_API_KEY'; // optional
|
|
12
|
-
const bearerToken = 'YOUR_BEARER_TOKEN'; // optional
|
|
13
|
-
|
|
14
|
-
initializeApi({
|
|
15
|
-
baseURL: 'https://smartlinks.app/api/v1',
|
|
16
|
-
apiKey,
|
|
17
|
-
bearerToken,
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
const ReactDemo: React.FC = () => {
|
|
21
|
-
const [collectionData, setCollection] = useState<CollectionResponse | null>(null);
|
|
22
|
-
const [productData, setProduct] = useState<ProductResponse | null>(null);
|
|
23
|
-
const [proofData, setProof] = useState<ProofResponse | null>(null);
|
|
24
|
-
const [error, setError] = useState<string | null>(null);
|
|
25
|
-
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
async function fetchData() {
|
|
28
|
-
try {
|
|
29
|
-
const col = await collection.get('abc123');
|
|
30
|
-
const prod = await product.get('abc123', 'prod789');
|
|
31
|
-
const prf = await proof.get('abc123', 'proof456');
|
|
32
|
-
setCollection(col);
|
|
33
|
-
setProduct(prod);
|
|
34
|
-
setProof(prf);
|
|
35
|
-
} catch (err) {
|
|
36
|
-
setError((err as Error).message);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
fetchData();
|
|
40
|
-
}, []);
|
|
41
|
-
|
|
42
|
-
if (error) return <div>Error: {error}</div>;
|
|
43
|
-
if (!collectionData || !productData || !proofData) return <div>Loading...</div>;
|
|
44
|
-
|
|
45
|
-
return (
|
|
46
|
-
<div>
|
|
47
|
-
<h1>{collectionData.title}</h1>
|
|
48
|
-
<img src={collectionData.logoImage} alt={collectionData.title} width="100" />
|
|
49
|
-
<h2>{productData.name}</h2>
|
|
50
|
-
<img src={productData.heroImage} alt={productData.name} width="100" />
|
|
51
|
-
<p>{productData.description}</p>
|
|
52
|
-
<h3>Proof</h3>
|
|
53
|
-
<pre>{JSON.stringify(proofData, null, 2)}</pre>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
export default ReactDemo;
|
package/generate-api-summary.js
DELETED
|
@@ -1,279 +0,0 @@
|
|
|
1
|
-
// generate-api-summary.js
|
|
2
|
-
const fs = require('fs');
|
|
3
|
-
const path = require('path');
|
|
4
|
-
|
|
5
|
-
function extractFunctionsFromFile(filePath, moduleName) {
|
|
6
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
7
|
-
const functions = [];
|
|
8
|
-
|
|
9
|
-
// Extract export async function declarations
|
|
10
|
-
const functionRegex = /export\s+async\s+function\s+(\w+)\s*\((.*?)\)\s*:\s*Promise<([^>]+)>/gs;
|
|
11
|
-
let match;
|
|
12
|
-
|
|
13
|
-
while ((match = functionRegex.exec(content)) !== null) {
|
|
14
|
-
const [, name, paramsStr, returnType] = match;
|
|
15
|
-
const params = paramsStr.split(',').map(p => p.trim()).filter(p => p);
|
|
16
|
-
|
|
17
|
-
// Extract JSDoc comment if present
|
|
18
|
-
const beforeFunction = content.substring(0, match.index);
|
|
19
|
-
const commentMatch = beforeFunction.match(/\/\*\*\s*(.*?)\s*\*\//s);
|
|
20
|
-
const description = commentMatch ?
|
|
21
|
-
commentMatch[1].replace(/\s*\*\s*/g, ' ').replace(/\n/g, ' ').trim() :
|
|
22
|
-
undefined;
|
|
23
|
-
|
|
24
|
-
functions.push({
|
|
25
|
-
name,
|
|
26
|
-
params,
|
|
27
|
-
returnType,
|
|
28
|
-
description
|
|
29
|
-
});
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
return { name: moduleName, functions };
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function extractTypesFromFile(filePath, moduleName) {
|
|
36
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
37
|
-
const types = [];
|
|
38
|
-
|
|
39
|
-
// Extract interface declarations with proper bracket matching
|
|
40
|
-
const interfaceRegex = /export\s+interface\s+(\w+)\s*\{/g;
|
|
41
|
-
let match;
|
|
42
|
-
|
|
43
|
-
while ((match = interfaceRegex.exec(content)) !== null) {
|
|
44
|
-
const [, name] = match;
|
|
45
|
-
const startPos = match.index + match[0].length;
|
|
46
|
-
|
|
47
|
-
// Find the matching closing bracket
|
|
48
|
-
let braceCount = 1;
|
|
49
|
-
let endPos = startPos;
|
|
50
|
-
|
|
51
|
-
while (braceCount > 0 && endPos < content.length) {
|
|
52
|
-
if (content[endPos] === '{') braceCount++;
|
|
53
|
-
else if (content[endPos] === '}') braceCount--;
|
|
54
|
-
endPos++;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
if (braceCount === 0) {
|
|
58
|
-
const body = content.substring(startPos, endPos - 1);
|
|
59
|
-
|
|
60
|
-
// Parse the interface body more carefully
|
|
61
|
-
const properties = parseInterfaceProperties(body);
|
|
62
|
-
|
|
63
|
-
types.push({
|
|
64
|
-
name,
|
|
65
|
-
type: 'interface',
|
|
66
|
-
properties
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
// Extract type aliases
|
|
72
|
-
const typeAliasRegex = /export\s+type\s+(\w+)\s*=\s*([^;\n]+)/g;
|
|
73
|
-
let typeMatch;
|
|
74
|
-
|
|
75
|
-
while ((typeMatch = typeAliasRegex.exec(content)) !== null) {
|
|
76
|
-
const [, name, definition] = typeMatch;
|
|
77
|
-
types.push({
|
|
78
|
-
name,
|
|
79
|
-
type: 'type',
|
|
80
|
-
definition: definition.trim()
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
return { name: moduleName, types };
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
function parseInterfaceProperties(body, depth = 0) {
|
|
88
|
-
const properties = [];
|
|
89
|
-
const lines = body.split('\n');
|
|
90
|
-
let i = 0;
|
|
91
|
-
|
|
92
|
-
while (i < lines.length) {
|
|
93
|
-
const line = lines[i].trim();
|
|
94
|
-
|
|
95
|
-
// Skip empty lines and comments
|
|
96
|
-
if (!line || line.startsWith('/**') || line.startsWith('*') || line.startsWith('*/')) {
|
|
97
|
-
i++;
|
|
98
|
-
continue;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Check for property declaration
|
|
102
|
-
const propMatch = line.match(/^(\w+)(\??):\s*(.*)$/);
|
|
103
|
-
if (propMatch) {
|
|
104
|
-
const [, propName, optional, typeStart] = propMatch;
|
|
105
|
-
|
|
106
|
-
// Check if this is a nested object starting with {
|
|
107
|
-
if (typeStart.trim() === '{') {
|
|
108
|
-
// Find the matching closing brace and parse nested properties
|
|
109
|
-
let braceCount = 1;
|
|
110
|
-
let j = i + 1;
|
|
111
|
-
let nestedLines = [];
|
|
112
|
-
|
|
113
|
-
while (j < lines.length && braceCount > 0) {
|
|
114
|
-
const nestedLine = lines[j];
|
|
115
|
-
|
|
116
|
-
// Count braces to find the matching closing brace
|
|
117
|
-
for (const char of nestedLine) {
|
|
118
|
-
if (char === '{') braceCount++;
|
|
119
|
-
else if (char === '}') braceCount--;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
if (braceCount > 0) {
|
|
123
|
-
nestedLines.push(nestedLine);
|
|
124
|
-
}
|
|
125
|
-
j++;
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Parse the nested content recursively
|
|
129
|
-
const nestedBody = nestedLines.join('\n');
|
|
130
|
-
const nestedProps = parseInterfaceProperties(nestedBody, depth + 1);
|
|
131
|
-
|
|
132
|
-
properties.push({
|
|
133
|
-
name: propName,
|
|
134
|
-
type: 'object',
|
|
135
|
-
nestedProperties: nestedProps,
|
|
136
|
-
optional: !!optional
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
i = j;
|
|
140
|
-
} else {
|
|
141
|
-
// Simple property
|
|
142
|
-
let propType = typeStart.replace(/[;,]$/, '').trim();
|
|
143
|
-
properties.push({
|
|
144
|
-
name: propName,
|
|
145
|
-
type: propType,
|
|
146
|
-
optional: !!optional
|
|
147
|
-
});
|
|
148
|
-
i++;
|
|
149
|
-
}
|
|
150
|
-
} else {
|
|
151
|
-
i++;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
return properties;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
function formatProperty(prop, indent = ' ') {
|
|
159
|
-
let result = '';
|
|
160
|
-
|
|
161
|
-
if (prop.type === 'object' && prop.nestedProperties) {
|
|
162
|
-
// Format nested object property
|
|
163
|
-
result += `${indent}${prop.name}${prop.optional ? '?' : ''}: {\n`;
|
|
164
|
-
for (const nestedProp of prop.nestedProperties) {
|
|
165
|
-
result += formatProperty(nestedProp, indent + ' ');
|
|
166
|
-
}
|
|
167
|
-
result += `${indent}};\n`;
|
|
168
|
-
} else {
|
|
169
|
-
// Format simple property
|
|
170
|
-
result += `${indent}${prop.name}${prop.optional ? '?' : ''}: ${prop.type};\n`;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
return result;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
function parseNestedProperties(lines) {
|
|
177
|
-
// This function is now replaced by the recursive parseInterfaceProperties
|
|
178
|
-
const nestedProps = [];
|
|
179
|
-
|
|
180
|
-
for (const line of lines) {
|
|
181
|
-
const propMatch = line.match(/^(\w+)(\??):\s*(.+?)[;,]?$/);
|
|
182
|
-
if (propMatch) {
|
|
183
|
-
const [, propName, optional, propType] = propMatch;
|
|
184
|
-
nestedProps.push({
|
|
185
|
-
name: propName,
|
|
186
|
-
type: propType.trim(),
|
|
187
|
-
optional: !!optional
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
return nestedProps;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
function generateAPISummary() {
|
|
196
|
-
const apiDir = path.join(__dirname, 'src', 'api');
|
|
197
|
-
const typesDir = path.join(__dirname, 'src', 'types');
|
|
198
|
-
const modules = [];
|
|
199
|
-
const typeModules = [];
|
|
200
|
-
|
|
201
|
-
// Get all TypeScript files in the API directory
|
|
202
|
-
const apiFiles = fs.readdirSync(apiDir).filter(file => file.endsWith('.ts') && file !== 'index.ts');
|
|
203
|
-
|
|
204
|
-
for (const file of apiFiles) {
|
|
205
|
-
const filePath = path.join(apiDir, file);
|
|
206
|
-
const moduleName = path.basename(file, '.ts');
|
|
207
|
-
const module = extractFunctionsFromFile(filePath, moduleName);
|
|
208
|
-
|
|
209
|
-
if (module.functions.length > 0) {
|
|
210
|
-
modules.push(module);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
// Get all TypeScript files in the types directory
|
|
215
|
-
const typeFiles = fs.readdirSync(typesDir).filter(file => file.endsWith('.ts') && file !== 'index.ts');
|
|
216
|
-
|
|
217
|
-
for (const file of typeFiles) {
|
|
218
|
-
const filePath = path.join(typesDir, file);
|
|
219
|
-
const moduleName = path.basename(file, '.ts');
|
|
220
|
-
const module = extractTypesFromFile(filePath, moduleName);
|
|
221
|
-
|
|
222
|
-
if (module.types.length > 0) {
|
|
223
|
-
typeModules.push(module);
|
|
224
|
-
}
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Generate clean summary
|
|
228
|
-
let summary = '# Smartlinks API Summary\n\n';
|
|
229
|
-
summary += 'This is a concise summary of all available API functions and types.\n\n';
|
|
230
|
-
|
|
231
|
-
// Add types section
|
|
232
|
-
if (typeModules.length > 0) {
|
|
233
|
-
summary += '## Types\n\n';
|
|
234
|
-
|
|
235
|
-
for (const typeModule of typeModules) {
|
|
236
|
-
summary += `### ${typeModule.name}\n\n`;
|
|
237
|
-
|
|
238
|
-
for (const type of typeModule.types) {
|
|
239
|
-
if (type.type === 'interface') {
|
|
240
|
-
summary += `**${type.name}** (interface)\n`;
|
|
241
|
-
if (type.properties.length > 0) {
|
|
242
|
-
summary += '```typescript\n';
|
|
243
|
-
summary += `interface ${type.name} {\n`;
|
|
244
|
-
for (const prop of type.properties) {
|
|
245
|
-
summary += formatProperty(prop);
|
|
246
|
-
}
|
|
247
|
-
summary += '}\n';
|
|
248
|
-
summary += '```\n\n';
|
|
249
|
-
}
|
|
250
|
-
} else if (type.type === 'type') {
|
|
251
|
-
summary += `**${type.name}** = \`${type.definition}\`\n\n`;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
// Add API functions section
|
|
258
|
-
summary += '## API Functions\n\n';
|
|
259
|
-
|
|
260
|
-
for (const module of modules) {
|
|
261
|
-
summary += `### ${module.name}\n\n`;
|
|
262
|
-
|
|
263
|
-
for (const func of module.functions) {
|
|
264
|
-
summary += `**${func.name}**(${func.params.join(', ')}) → \`${func.returnType}\`\n`;
|
|
265
|
-
if (func.description) {
|
|
266
|
-
summary += `${func.description}\n`;
|
|
267
|
-
}
|
|
268
|
-
summary += '\n';
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
// Write to file
|
|
273
|
-
fs.writeFileSync(path.join(__dirname, 'API_SUMMARY.md'), summary);
|
|
274
|
-
console.log('✅ API summary generated: API_SUMMARY.md');
|
|
275
|
-
console.log(`📊 Found ${modules.length} API modules with ${modules.reduce((total, m) => total + m.functions.length, 0)} functions`);
|
|
276
|
-
console.log(`📝 Found ${typeModules.length} type modules with ${typeModules.reduce((total, m) => total + m.types.length, 0)} types`);
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
generateAPISummary();
|
package/generate-api-summary.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
// generate-api-summary.ts
|
|
2
|
-
import * as fs from 'fs';
|
|
3
|
-
import * as path from 'path';
|
|
4
|
-
|
|
5
|
-
interface APIFunction {
|
|
6
|
-
name: string;
|
|
7
|
-
params: string[];
|
|
8
|
-
returnType: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
interface APIModule {
|
|
13
|
-
name: string;
|
|
14
|
-
functions: APIFunction[];
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
function extractFunctionsFromFile(filePath: string, moduleName: string): APIModule {
|
|
18
|
-
const content = fs.readFileSync(filePath, 'utf8');
|
|
19
|
-
const functions: APIFunction[] = [];
|
|
20
|
-
|
|
21
|
-
// Extract export async function declarations
|
|
22
|
-
const functionRegex = /export\s+async\s+function\s+(\w+)\s*\((.*?)\)\s*:\s*Promise<([^>]+)>/gs;
|
|
23
|
-
let match;
|
|
24
|
-
|
|
25
|
-
while ((match = functionRegex.exec(content)) !== null) {
|
|
26
|
-
const [, name, paramsStr, returnType] = match;
|
|
27
|
-
const params = paramsStr.split(',').map(p => p.trim()).filter(p => p);
|
|
28
|
-
|
|
29
|
-
// Extract JSDoc comment if present
|
|
30
|
-
const beforeFunction = content.substring(0, match.index);
|
|
31
|
-
const commentMatch = beforeFunction.match(/\/\*\*\s*(.*?)\s*\*\//s);
|
|
32
|
-
const description = commentMatch ? commentMatch[1].replace(/\s*\*\s*/g, ' ').trim() : undefined;
|
|
33
|
-
|
|
34
|
-
functions.push({
|
|
35
|
-
name,
|
|
36
|
-
params,
|
|
37
|
-
returnType,
|
|
38
|
-
description
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
return { name: moduleName, functions };
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function generateAPISummary(): void {
|
|
46
|
-
const apiDir = path.join(__dirname, 'src', 'api');
|
|
47
|
-
const modules: APIModule[] = [];
|
|
48
|
-
|
|
49
|
-
// Get all TypeScript files in the API directory
|
|
50
|
-
const files = fs.readdirSync(apiDir).filter(file => file.endsWith('.ts') && file !== 'index.ts');
|
|
51
|
-
|
|
52
|
-
for (const file of files) {
|
|
53
|
-
const filePath = path.join(apiDir, file);
|
|
54
|
-
const moduleName = path.basename(file, '.ts');
|
|
55
|
-
const module = extractFunctionsFromFile(filePath, moduleName);
|
|
56
|
-
|
|
57
|
-
if (module.functions.length > 0) {
|
|
58
|
-
modules.push(module);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
// Generate clean summary
|
|
63
|
-
let summary = '# Smartlinks API Summary\n\n';
|
|
64
|
-
summary += 'This is a concise summary of all available API functions.\n\n';
|
|
65
|
-
|
|
66
|
-
for (const module of modules) {
|
|
67
|
-
summary += `## ${module.name}\n\n`;
|
|
68
|
-
|
|
69
|
-
for (const func of module.functions) {
|
|
70
|
-
summary += `### ${func.name}(${func.params.join(', ')})\n`;
|
|
71
|
-
if (func.description) {
|
|
72
|
-
summary += `${func.description}\n`;
|
|
73
|
-
}
|
|
74
|
-
summary += `Returns: \`${func.returnType}\`\n\n`;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// Write to file
|
|
79
|
-
fs.writeFileSync(path.join(__dirname, 'API_SUMMARY.md'), summary);
|
|
80
|
-
console.log('API summary generated: API_SUMMARY.md');
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
generateAPISummary();
|
package/openapi.yaml
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
openapi: 3.0.3
|
|
2
|
-
info:
|
|
3
|
-
title: Smartlinks API
|
|
4
|
-
version: "1.0.0"
|
|
5
|
-
description: |
|
|
6
|
-
OpenAPI 3.0 specification for the Smartlinks REST API.
|
|
7
|
-
servers:
|
|
8
|
-
- url: https://smartlinks.app/api/v1
|
|
9
|
-
paths:
|
|
10
|
-
/collections/{collectionId}:
|
|
11
|
-
get:
|
|
12
|
-
summary: Get a collection by ID
|
|
13
|
-
operationId: getCollection
|
|
14
|
-
parameters:
|
|
15
|
-
- name: collectionId
|
|
16
|
-
in: path
|
|
17
|
-
required: true
|
|
18
|
-
schema:
|
|
19
|
-
type: string
|
|
20
|
-
responses:
|
|
21
|
-
'200':
|
|
22
|
-
description: Collection found
|
|
23
|
-
content:
|
|
24
|
-
application/json:
|
|
25
|
-
schema:
|
|
26
|
-
$ref: '#/components/schemas/CollectionResponse'
|
|
27
|
-
'401':
|
|
28
|
-
description: Unauthorized
|
|
29
|
-
'404':
|
|
30
|
-
description: Not Found
|
|
31
|
-
security:
|
|
32
|
-
- bearerAuth: []
|
|
33
|
-
/collections/{collectionId}/products/{productId}:
|
|
34
|
-
get:
|
|
35
|
-
summary: Get a product item by collection and product ID
|
|
36
|
-
operationId: getProductItem
|
|
37
|
-
parameters:
|
|
38
|
-
- name: collectionId
|
|
39
|
-
in: path
|
|
40
|
-
required: true
|
|
41
|
-
schema:
|
|
42
|
-
type: string
|
|
43
|
-
- name: productId
|
|
44
|
-
in: path
|
|
45
|
-
required: true
|
|
46
|
-
schema:
|
|
47
|
-
type: string
|
|
48
|
-
responses:
|
|
49
|
-
'200':
|
|
50
|
-
description: Product found
|
|
51
|
-
content:
|
|
52
|
-
application/json:
|
|
53
|
-
schema:
|
|
54
|
-
$ref: '#/components/schemas/ProductResponse'
|
|
55
|
-
'401':
|
|
56
|
-
description: Unauthorized
|
|
57
|
-
'404':
|
|
58
|
-
description: Not Found
|
|
59
|
-
security:
|
|
60
|
-
- bearerAuth: []
|
|
61
|
-
/collections/{collectionId}/apps/{appId}/configuration:
|
|
62
|
-
get:
|
|
63
|
-
summary: Get app configuration by collection and app ID
|
|
64
|
-
operationId: getAppConfiguration
|
|
65
|
-
parameters:
|
|
66
|
-
- name: collectionId
|
|
67
|
-
in: path
|
|
68
|
-
required: true
|
|
69
|
-
schema:
|
|
70
|
-
type: string
|
|
71
|
-
- name: appId
|
|
72
|
-
in: path
|
|
73
|
-
required: true
|
|
74
|
-
schema:
|
|
75
|
-
type: string
|
|
76
|
-
responses:
|
|
77
|
-
'200':
|
|
78
|
-
description: App configuration found
|
|
79
|
-
content:
|
|
80
|
-
application/json:
|
|
81
|
-
schema:
|
|
82
|
-
$ref: '#/components/schemas/AppConfigurationResponse'
|
|
83
|
-
'401':
|
|
84
|
-
description: Unauthorized
|
|
85
|
-
'404':
|
|
86
|
-
description: Not Found
|
|
87
|
-
security:
|
|
88
|
-
- bearerAuth: []
|
|
89
|
-
components:
|
|
90
|
-
securitySchemes:
|
|
91
|
-
bearerAuth:
|
|
92
|
-
type: http
|
|
93
|
-
scheme: bearer
|
|
94
|
-
bearerFormat: JWT
|
|
95
|
-
schemas:
|
|
96
|
-
CollectionResponse:
|
|
97
|
-
type: object
|
|
98
|
-
properties:
|
|
99
|
-
id:
|
|
100
|
-
type: string
|
|
101
|
-
name:
|
|
102
|
-
type: string
|
|
103
|
-
title:
|
|
104
|
-
type: string
|
|
105
|
-
logoImage:
|
|
106
|
-
type: string
|
|
107
|
-
required: [id, name, title, logoImage]
|
|
108
|
-
ProductResponse:
|
|
109
|
-
type: object
|
|
110
|
-
properties:
|
|
111
|
-
id:
|
|
112
|
-
type: string
|
|
113
|
-
name:
|
|
114
|
-
type: string
|
|
115
|
-
description:
|
|
116
|
-
type: string
|
|
117
|
-
heroImage:
|
|
118
|
-
type: string
|
|
119
|
-
required: [id, name, description, heroImage]
|
|
120
|
-
AppConfigurationResponse:
|
|
121
|
-
type: object
|
|
122
|
-
properties:
|
|
123
|
-
id:
|
|
124
|
-
type: string
|
|
125
|
-
name:
|
|
126
|
-
type: string
|
|
127
|
-
settings:
|
|
128
|
-
type: object
|
|
129
|
-
additionalProperties: true
|
|
130
|
-
required: [id, name]
|
package/scripts/copy-docs.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const path = require('path');
|
|
3
|
-
|
|
4
|
-
const src = path.join(__dirname, '..', 'docs', 'README.md');
|
|
5
|
-
const destDir = path.join(process.cwd(), 'src', 'docs', 'smartlinks');
|
|
6
|
-
const dest = path.join(destDir, 'api-reference.md');
|
|
7
|
-
|
|
8
|
-
fs.mkdirSync(destDir, { recursive: true });
|
|
9
|
-
fs.copyFileSync(src, dest);
|
|
10
|
-
|
|
11
|
-
console.log(`Copied ${src} to ${dest}`);
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
// src/api/appConfiguration.ts
|
|
2
|
-
import { request, post, del } from "../http"
|
|
3
|
-
|
|
4
|
-
export type AppConfigOptions = {
|
|
5
|
-
appId: string
|
|
6
|
-
collectionId?: string
|
|
7
|
-
productId?: string
|
|
8
|
-
variantId?: string
|
|
9
|
-
batchId?: string
|
|
10
|
-
itemId?: string
|
|
11
|
-
user?: boolean
|
|
12
|
-
userData?: boolean
|
|
13
|
-
admin?: boolean
|
|
14
|
-
config?: any
|
|
15
|
-
data?: any
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
function buildAppPath(opts: AppConfigOptions, type: "config" | "data" | "dataItem"): string {
|
|
19
|
-
if (opts.user) {
|
|
20
|
-
// /public/auth/app/:appId
|
|
21
|
-
let path = `/public/auth/app/${encodeURIComponent(opts.appId)}`
|
|
22
|
-
if (type === "data") path += "/data"
|
|
23
|
-
if (type === "dataItem" && opts.itemId) path += `/data/${encodeURIComponent(opts.itemId)}`
|
|
24
|
-
return path
|
|
25
|
-
}
|
|
26
|
-
if (opts.userData) {
|
|
27
|
-
// /public/auth/app/:appId/data or /public/auth/app/:appId/data/:itemId
|
|
28
|
-
let path = `/public/auth/app/${encodeURIComponent(opts.appId)}/data`
|
|
29
|
-
if (type === "dataItem" && opts.itemId) path += `/${encodeURIComponent(opts.itemId)}`
|
|
30
|
-
return path
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const base = opts.admin ? "admin" : "public"
|
|
34
|
-
let path = `/${base}`
|
|
35
|
-
|
|
36
|
-
if (opts.collectionId) {
|
|
37
|
-
path += `/collection/${encodeURIComponent(opts.collectionId)}`
|
|
38
|
-
if (opts.productId) {
|
|
39
|
-
path += `/product/${encodeURIComponent(opts.productId)}`
|
|
40
|
-
if (opts.variantId) {
|
|
41
|
-
path += `/variant/${encodeURIComponent(opts.variantId)}`
|
|
42
|
-
} else if (opts.batchId) {
|
|
43
|
-
path += `/batch/${encodeURIComponent(opts.batchId)}`
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
path += `/app/${encodeURIComponent(opts.appId)}`
|
|
49
|
-
|
|
50
|
-
if (type === "data" || type === "dataItem") {
|
|
51
|
-
path += "/data"
|
|
52
|
-
if (type === "dataItem" && opts.itemId) {
|
|
53
|
-
path += `/${encodeURIComponent(opts.itemId)}`
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return path
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export namespace appConfiguration {
|
|
61
|
-
// Get config (app, collection, product, variant, batch, user)
|
|
62
|
-
export async function getConfig(opts: AppConfigOptions): Promise<any> {
|
|
63
|
-
const path = buildAppPath(opts, "config")
|
|
64
|
-
return request<any>(path)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// Set config (app, collection, product, variant, batch, user)
|
|
68
|
-
export async function setConfig(opts: AppConfigOptions): Promise<any> {
|
|
69
|
-
const path = buildAppPath(opts, "config")
|
|
70
|
-
return post<any>(path, opts.config)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
// Delete config (user only)
|
|
74
|
-
export async function deleteConfig(opts: AppConfigOptions): Promise<void> {
|
|
75
|
-
const path = buildAppPath(opts, "config")
|
|
76
|
-
return del<void>(path)
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Get all data items (app, collection, product, variant, batch, userData)
|
|
80
|
-
export async function getData(opts: AppConfigOptions): Promise<any[]> {
|
|
81
|
-
const path = buildAppPath(opts, "data")
|
|
82
|
-
return request<any[]>(path)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
// Get a single data item (app, collection, product, variant, batch, userData)
|
|
86
|
-
export async function getDataItem(opts: AppConfigOptions): Promise<any> {
|
|
87
|
-
if (!opts.itemId) throw new Error("itemId is required for getDataItem")
|
|
88
|
-
const path = buildAppPath(opts, "dataItem")
|
|
89
|
-
return request<any>(path)
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
// Set a data item (app, collection, product, variant, batch, userData)
|
|
93
|
-
export async function setDataItem(opts: AppConfigOptions): Promise<any> {
|
|
94
|
-
const path = buildAppPath(opts, "data")
|
|
95
|
-
return post<any>(path, opts.data)
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
// Delete a data item (app, collection, product, variant, batch, userData)
|
|
99
|
-
export async function deleteDataItem(opts: AppConfigOptions): Promise<void> {
|
|
100
|
-
if (!opts.itemId) throw new Error("itemId is required for deleteDataItem")
|
|
101
|
-
const path = buildAppPath(opts, "dataItem")
|
|
102
|
-
return del<void>(path)
|
|
103
|
-
}
|
|
104
|
-
}
|