@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.
Files changed (44) hide show
  1. package/API_SUMMARY.md +672 -213
  2. package/README.md +430 -0
  3. package/dist/api/collection.js +1 -1
  4. package/dist/http.d.ts +5 -3
  5. package/dist/http.js +5 -3
  6. package/package.json +19 -3
  7. package/build-docs.ts +0 -69
  8. package/debug.log +0 -6
  9. package/examples/browser-demo.html +0 -43
  10. package/examples/node-demo.ts +0 -50
  11. package/examples/react-demo.tsx +0 -58
  12. package/generate-api-summary.js +0 -279
  13. package/generate-api-summary.ts +0 -83
  14. package/openapi.yaml +0 -130
  15. package/scripts/copy-docs.js +0 -11
  16. package/src/api/appConfiguration.ts +0 -104
  17. package/src/api/asset.ts +0 -133
  18. package/src/api/attestation.ts +0 -69
  19. package/src/api/auth.ts +0 -103
  20. package/src/api/batch.ts +0 -173
  21. package/src/api/claimSet.ts +0 -131
  22. package/src/api/collection.ts +0 -117
  23. package/src/api/crate.ts +0 -43
  24. package/src/api/form.ts +0 -57
  25. package/src/api/index.ts +0 -14
  26. package/src/api/product.ts +0 -128
  27. package/src/api/proof.ts +0 -32
  28. package/src/api/serialNumber.ts +0 -0
  29. package/src/api/variant.ts +0 -173
  30. package/src/http.ts +0 -363
  31. package/src/index.ts +0 -29
  32. package/src/types/appConfiguration.ts +0 -12
  33. package/src/types/asset.ts +0 -9
  34. package/src/types/attestation.ts +0 -19
  35. package/src/types/batch.ts +0 -15
  36. package/src/types/collection.ts +0 -68
  37. package/src/types/error.ts +0 -10
  38. package/src/types/index.ts +0 -11
  39. package/src/types/product.ts +0 -33
  40. package/src/types/proof.ts +0 -20
  41. package/src/types/serialNumber.ts +0 -0
  42. package/src/types/variant.ts +0 -15
  43. package/tsconfig.json +0 -15
  44. package/typedoc.json +0 -18
@@ -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;
@@ -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();
@@ -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]
@@ -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
- }