@sekyuriti/attest 0.2.0 → 0.2.2
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/bin/attest.js +110 -53
- package/package.json +1 -1
package/bin/attest.js
CHANGED
|
@@ -139,7 +139,109 @@ function printHeader() {
|
|
|
139
139
|
logBold(" █▀▀ █▀▀ █▄▀ █▄█ █ █ █▀█ █ ▀█▀ █");
|
|
140
140
|
logBold(" ▄▄█ ██▄ █ █ █ █▄█ █▀▄ █ █ █");
|
|
141
141
|
log("");
|
|
142
|
-
logDim(" ATTEST CLI v0.2.
|
|
142
|
+
logDim(" ATTEST CLI v0.2.1");
|
|
143
|
+
log("");
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
147
|
+
// INIT HELPER (used by both login and init commands)
|
|
148
|
+
// ═══════════════════════════════════════════════════════════════════
|
|
149
|
+
|
|
150
|
+
async function runInit(publicKey, apiKey) {
|
|
151
|
+
let steps = [];
|
|
152
|
+
|
|
153
|
+
// Step 1: Add .env variables
|
|
154
|
+
const envPath = path.join(process.cwd(), ".env");
|
|
155
|
+
const envLocalPath = path.join(process.cwd(), ".env.local");
|
|
156
|
+
let targetEnvPath = envLocalPath;
|
|
157
|
+
|
|
158
|
+
if (fs.existsSync(envLocalPath)) {
|
|
159
|
+
targetEnvPath = envLocalPath;
|
|
160
|
+
} else if (fs.existsSync(envPath)) {
|
|
161
|
+
targetEnvPath = envPath;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const envVars = `
|
|
165
|
+
# ATTEST Configuration
|
|
166
|
+
NEXT_PUBLIC_ATTEST_KEY=${publicKey}
|
|
167
|
+
ATTEST_SECRET_KEY=${apiKey}
|
|
168
|
+
`.trim();
|
|
169
|
+
|
|
170
|
+
if (fs.existsSync(targetEnvPath)) {
|
|
171
|
+
let content = fs.readFileSync(targetEnvPath, "utf-8");
|
|
172
|
+
if (!content.includes("ATTEST_KEY")) {
|
|
173
|
+
content += "\n\n" + envVars + "\n";
|
|
174
|
+
fs.writeFileSync(targetEnvPath, content);
|
|
175
|
+
steps.push(`Added ATTEST config to ${path.basename(targetEnvPath)}`);
|
|
176
|
+
} else {
|
|
177
|
+
steps.push(`ATTEST config already in ${path.basename(targetEnvPath)}`);
|
|
178
|
+
}
|
|
179
|
+
} else {
|
|
180
|
+
fs.writeFileSync(envLocalPath, envVars + "\n");
|
|
181
|
+
steps.push("Created .env.local with ATTEST config");
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Step 2: Find and update layout.tsx
|
|
185
|
+
const layoutPaths = [
|
|
186
|
+
path.join(process.cwd(), "src/app/layout.tsx"),
|
|
187
|
+
path.join(process.cwd(), "app/layout.tsx"),
|
|
188
|
+
path.join(process.cwd(), "src/app/layout.js"),
|
|
189
|
+
path.join(process.cwd(), "app/layout.js"),
|
|
190
|
+
];
|
|
191
|
+
|
|
192
|
+
let layoutPath = null;
|
|
193
|
+
for (const p of layoutPaths) {
|
|
194
|
+
if (fs.existsSync(p)) {
|
|
195
|
+
layoutPath = p;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const scriptTag = `<Script
|
|
201
|
+
src="https://sekyuriti.build/api/v2/attest/script/${publicKey}"
|
|
202
|
+
strategy="beforeInteractive"
|
|
203
|
+
/>`;
|
|
204
|
+
|
|
205
|
+
if (layoutPath) {
|
|
206
|
+
let layoutContent = fs.readFileSync(layoutPath, "utf-8");
|
|
207
|
+
|
|
208
|
+
if (layoutContent.includes("sekyuriti.build/api/v2/attest/script")) {
|
|
209
|
+
steps.push("ATTEST script already in layout");
|
|
210
|
+
} else {
|
|
211
|
+
// Check if Script is already imported
|
|
212
|
+
const hasScriptImport = layoutContent.includes("from 'next/script'") || layoutContent.includes('from "next/script"');
|
|
213
|
+
|
|
214
|
+
if (!hasScriptImport) {
|
|
215
|
+
// Add Script import after the first import line
|
|
216
|
+
layoutContent = layoutContent.replace(
|
|
217
|
+
/(import .+ from ['"][^'"]+['"];?\n)/,
|
|
218
|
+
`$1import Script from "next/script";\n`
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Add script tag after <body> or <body className=...>
|
|
223
|
+
if (layoutContent.includes("<body")) {
|
|
224
|
+
layoutContent = layoutContent.replace(
|
|
225
|
+
/(<body[^>]*>)/,
|
|
226
|
+
`$1\n ${scriptTag}`
|
|
227
|
+
);
|
|
228
|
+
fs.writeFileSync(layoutPath, layoutContent);
|
|
229
|
+
steps.push(`Added ATTEST script to ${path.basename(layoutPath)}`);
|
|
230
|
+
} else {
|
|
231
|
+
steps.push("Could not find <body> tag in layout");
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
} else {
|
|
235
|
+
steps.push("No layout.tsx found - add script manually");
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// Print results
|
|
239
|
+
for (const step of steps) {
|
|
240
|
+
log(` ${c.bold}✓${c.reset} ${step}`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
log("");
|
|
244
|
+
log(" Documentation: https://sekyuriti.build/docs/attest");
|
|
143
245
|
log("");
|
|
144
246
|
}
|
|
145
247
|
|
|
@@ -211,6 +313,11 @@ async function cmdLogin() {
|
|
|
211
313
|
apiKey: data.apiKey,
|
|
212
314
|
});
|
|
213
315
|
|
|
316
|
+
// Auto-run init after successful login
|
|
317
|
+
log(" Setting up your project...");
|
|
318
|
+
log("");
|
|
319
|
+
await runInit(data.publicKey, data.apiKey);
|
|
320
|
+
|
|
214
321
|
return;
|
|
215
322
|
}
|
|
216
323
|
}
|
|
@@ -334,59 +441,9 @@ async function cmdInit() {
|
|
|
334
441
|
return;
|
|
335
442
|
}
|
|
336
443
|
|
|
337
|
-
|
|
338
|
-
const envPath = path.join(process.cwd(), ".env");
|
|
339
|
-
const envLocalPath = path.join(process.cwd(), ".env.local");
|
|
340
|
-
let targetPath = envLocalPath;
|
|
341
|
-
|
|
342
|
-
if (fs.existsSync(envLocalPath)) {
|
|
343
|
-
targetPath = envLocalPath;
|
|
344
|
-
} else if (fs.existsSync(envPath)) {
|
|
345
|
-
targetPath = envPath;
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
const envVars = `
|
|
349
|
-
# ATTEST Configuration
|
|
350
|
-
NEXT_PUBLIC_ATTEST_KEY=${config.publicKey}
|
|
351
|
-
ATTEST_SECRET_KEY=${config.apiKey}
|
|
352
|
-
`.trim();
|
|
353
|
-
|
|
354
|
-
if (fs.existsSync(targetPath)) {
|
|
355
|
-
// Append to existing
|
|
356
|
-
let content = fs.readFileSync(targetPath, "utf-8");
|
|
357
|
-
|
|
358
|
-
if (content.includes("ATTEST_KEY")) {
|
|
359
|
-
log(" ATTEST is already configured in your .env file.");
|
|
360
|
-
log("");
|
|
361
|
-
return;
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
content += "\n\n" + envVars + "\n";
|
|
365
|
-
fs.writeFileSync(targetPath, content);
|
|
366
|
-
|
|
367
|
-
log(` ${c.bold}✓${c.reset} Added ATTEST config to ${path.basename(targetPath)}`);
|
|
368
|
-
} else {
|
|
369
|
-
// Create new .env.local
|
|
370
|
-
fs.writeFileSync(envLocalPath, envVars + "\n");
|
|
371
|
-
log(` ${c.bold}✓${c.reset} Created .env.local with ATTEST config`);
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
log("");
|
|
375
|
-
log(" Next steps:");
|
|
376
|
-
log("");
|
|
377
|
-
log(` ${c.dim}1.${c.reset} Add the script to your app:`);
|
|
378
|
-
log("");
|
|
379
|
-
log(` ${c.dim}<Script`);
|
|
380
|
-
log(` src="https://sekyuriti.build/api/v2/attest/script/${config.publicKey}"`);
|
|
381
|
-
log(` strategy="beforeInteractive"`);
|
|
382
|
-
log(` />${c.reset}`);
|
|
383
|
-
log("");
|
|
384
|
-
log(` ${c.dim}2.${c.reset} Add the middleware (optional):`);
|
|
385
|
-
log("");
|
|
386
|
-
log(` ${c.dim}import { createAttestMiddleware } from '@sekyuriti/attest/middleware';${c.reset}`);
|
|
387
|
-
log("");
|
|
388
|
-
log(" Documentation: https://sekyuriti.build/docs/attest");
|
|
444
|
+
log(" Setting up ATTEST...");
|
|
389
445
|
log("");
|
|
446
|
+
await runInit(config.publicKey, config.apiKey);
|
|
390
447
|
}
|
|
391
448
|
|
|
392
449
|
// ═══════════════════════════════════════════════════════════════════
|