@learncard/cli 3.6.8 → 4.0.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.
Files changed (72) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/README.md +36 -12
  3. package/dist/index.js +6673 -2038
  4. package/package.json +27 -15
  5. package/project.json +0 -42
  6. package/rollup.config.js +0 -34
  7. package/scripts/embed-snippets.ts +0 -47
  8. package/src/auth-grant.test.ts +0 -54
  9. package/src/auth-grant.ts +0 -34
  10. package/src/clr/validate.test.ts +0 -65
  11. package/src/clr/validate.ts +0 -242
  12. package/src/clr.ts +0 -119
  13. package/src/consent-contract.ts +0 -116
  14. package/src/demo-inbox-refresh.test.ts +0 -737
  15. package/src/demo-inbox-refresh.ts +0 -804
  16. package/src/demo-refresh-command.test.ts +0 -57
  17. package/src/demo-refresh-command.ts +0 -22
  18. package/src/demo-refresh-ui.test.ts +0 -66
  19. package/src/demo-refresh-ui.ts +0 -65
  20. package/src/demo-refresh.test.ts +0 -140
  21. package/src/demo-refresh.ts +0 -309
  22. package/src/doctor/checks.test.ts +0 -448
  23. package/src/doctor/checks.ts +0 -497
  24. package/src/doctor.test.ts +0 -67
  25. package/src/doctor.ts +0 -118
  26. package/src/embed.ts +0 -102
  27. package/src/inbox.test.ts +0 -257
  28. package/src/inbox.ts +0 -221
  29. package/src/index.tsx +0 -876
  30. package/src/init.ts +0 -26
  31. package/src/open.test.ts +0 -40
  32. package/src/open.ts +0 -186
  33. package/src/org/apply.test.ts +0 -1108
  34. package/src/org/apply.ts +0 -924
  35. package/src/org/branding.test.ts +0 -60
  36. package/src/org/diff.ts +0 -14
  37. package/src/org/load.ts +0 -50
  38. package/src/org/schema.test.ts +0 -256
  39. package/src/org/schema.ts +0 -216
  40. package/src/org.ts +0 -124
  41. package/src/out.test.ts +0 -40
  42. package/src/out.ts +0 -16
  43. package/src/phase-two.test.ts +0 -154
  44. package/src/project.test.ts +0 -232
  45. package/src/project.ts +0 -489
  46. package/src/promote.test.ts +0 -142
  47. package/src/promote.ts +0 -202
  48. package/src/random.ts +0 -3
  49. package/src/refresh.test.ts +0 -86
  50. package/src/refresh.ts +0 -93
  51. package/src/replHelpers.test.ts +0 -80
  52. package/src/replHelpers.ts +0 -45
  53. package/src/revoke.test.ts +0 -29
  54. package/src/revoke.ts +0 -65
  55. package/src/send-template.test.ts +0 -20
  56. package/src/send.test.ts +0 -321
  57. package/src/send.ts +0 -373
  58. package/src/setup-signing.test.ts +0 -62
  59. package/src/setup-signing.ts +0 -185
  60. package/src/snippet-files.ts +0 -16
  61. package/src/status.test.ts +0 -33
  62. package/src/status.ts +0 -94
  63. package/src/token.test.ts +0 -28
  64. package/src/token.ts +0 -139
  65. package/src/types.d.ts +0 -17
  66. package/src/verify.test.ts +0 -35
  67. package/src/verify.ts +0 -66
  68. package/src/webhook.ts +0 -247
  69. package/src/whoami.test.ts +0 -67
  70. package/src/whoami.ts +0 -129
  71. package/tsconfig.json +0 -38
  72. package/vitest.config.ts +0 -8
package/src/verify.ts DELETED
@@ -1,66 +0,0 @@
1
- import fs from 'node:fs/promises';
2
- import { initLearnCard } from '@learncard/init';
3
- import { type VC, type VP, type VerificationCheck, type VerificationItem } from '@learncard/types';
4
-
5
- export type VerifyResult = VerificationCheck | VerificationItem[];
6
-
7
- export const isPresentation = (value: unknown): boolean => {
8
- if (!value || typeof value !== 'object' || !('type' in value)) return false;
9
- const types = Array.isArray(value.type) ? value.type : [value.type];
10
- return types.includes('VerifiablePresentation');
11
- };
12
-
13
- const checkName = (value: string): string => (value === 'signature' ? 'proof' : value);
14
-
15
- export const verificationFailed = (result: VerifyResult): boolean =>
16
- Array.isArray(result)
17
- ? result.some(item => item.status === 'Failed')
18
- : result.errors.length > 0;
19
-
20
- export const formatVerification = (result: VerifyResult): string[] => {
21
- if (Array.isArray(result))
22
- return result.map(item => {
23
- const check = checkName(item.check);
24
- if (item.status === 'Success') return `✓ ${check}`;
25
- return `${item.status === 'Failed' ? '✗' : '!'} ${check}: ${item.details || item.message || 'Check failed'}`;
26
- });
27
- return [
28
- ...result.checks.map(check => `✓ ${checkName(check)}`),
29
- ...result.warnings.map(warning => `! ${warning}`),
30
- ...result.errors.map(error => {
31
- const match = error.match(/^(.+?) error:\s*(.*)$/);
32
- return match ? `✗ ${checkName(match[1]!)}: ${match[2]}` : `✗ ${error}`;
33
- }),
34
- ];
35
- };
36
-
37
- export const runVerify = async (
38
- file: string,
39
- options: { json?: boolean; didkit?: Promise<Buffer> }
40
- ): Promise<void> => {
41
- let text: string;
42
- if (file === '-') {
43
- const chunks: Buffer[] = [];
44
- for await (const chunk of process.stdin) chunks.push(Buffer.from(chunk));
45
- text = Buffer.concat(chunks).toString('utf8');
46
- } else text = await fs.readFile(file, 'utf8');
47
- const input: unknown = JSON.parse(text);
48
- if (!input || typeof input !== 'object' || !('type' in input))
49
- throw new Error('Expected a credential or presentation JSON object with a type.');
50
- const presentation = isPresentation(input);
51
- const types = Array.isArray(input.type) ? input.type : [input.type];
52
- if (!presentation && !types.includes('VerifiableCredential'))
53
- throw new Error('Expected VerifiableCredential or VerifiablePresentation in type.');
54
- const learnCard = await initLearnCard({ ...(options.didkit && { didkit: options.didkit }) });
55
- const result = presentation
56
- ? await learnCard.invoke.verifyPresentation(input as VP)
57
- : options.json
58
- ? await learnCard.invoke.verifyCredential(input as VC)
59
- : await learnCard.invoke.verifyCredential(input as VC, {}, true);
60
- if (options.json) console.log(JSON.stringify(result, null, 2));
61
- else {
62
- for (const line of formatVerification(result)) console.log(line);
63
- console.log('Next: review warnings and issuer trust before accepting this credential.');
64
- }
65
- if (verificationFailed(result)) process.exitCode = 1;
66
- };
package/src/webhook.ts DELETED
@@ -1,247 +0,0 @@
1
- import type { Server } from 'node:http';
2
- import { initLearnCard } from '@learncard/init';
3
- import {
4
- connect,
5
- createPrompts,
6
- ensureIdentity,
7
- ensureProfile,
8
- KEYS,
9
- loadProject,
10
- localizeSnippet,
11
- resolveServices,
12
- saveProject,
13
- type ProjectOptions,
14
- PRODUCTION_NETWORK,
15
- } from './project';
16
- import { DEFAULT_BADGE, templateCredential } from './send';
17
- import { WEBHOOK_MJS } from './generated/snippets';
18
- import { writeSnippet } from './snippet-files';
19
- import { setupSigning } from './setup-signing';
20
- import { out } from './out';
21
-
22
- interface WebhookModule {
23
- extractBearer: (header: unknown) => string | undefined;
24
- webhookDedupeKey: (payload: unknown) => string | undefined;
25
- createWebhookReceiver: (
26
- verifier: {
27
- invoke: {
28
- verifyPresentation: (
29
- token: string,
30
- options: { proofFormat: 'jwt' }
31
- ) => Promise<{ errors: unknown[] }>;
32
- };
33
- },
34
- expectedDid?: string
35
- ) => Server;
36
- }
37
-
38
- export const webhookConfig = (
39
- env: Record<string, string>,
40
- options: { port?: string },
41
- runtime: Record<string, string | undefined> = process.env
42
- ): { port: number; expectedDid: string | undefined } => {
43
- const port = Number(options.port ?? runtime.PORT ?? env.PORT ?? 8787);
44
- if (!Number.isInteger(port) || port < 1 || port > 65535)
45
- throw new Error('Port must be 1–65535.');
46
- return { port, expectedDid: runtime.EXPECTED_NETWORK_DID ?? env.EXPECTED_NETWORK_DID };
47
- };
48
-
49
- export const closeWebhookReceiver = (server: Server): Promise<void> =>
50
- new Promise((resolve, reject) => {
51
- // Verification may be waiting on a remote DID. Do not let it block Ctrl+C indefinitely.
52
- const timer = setTimeout(() => server.closeAllConnections(), 1000);
53
- timer.unref();
54
- server.close(error => {
55
- clearTimeout(timer);
56
- if (error) reject(error);
57
- else resolve();
58
- });
59
- });
60
-
61
- /** Execute the embedded, canonical receiver, never a possibly edited file from the cwd. */
62
- export const loadWebhookModule = async (): Promise<WebhookModule> => {
63
- return import(`data:text/javascript;base64,${Buffer.from(WEBHOOK_MJS).toString('base64')}`);
64
- };
65
-
66
- export interface WebhookEvent {
67
- type: string;
68
- status?: string;
69
- issuanceId?: string;
70
- recipient?: string;
71
- }
72
-
73
- /** The embedded receiver logs one space-separated line per event: type, status, issuanceId, recipient DID. */
74
- export const parseWebhookLogLine = (line: string): WebhookEvent | undefined => {
75
- const [type, status, issuanceId, recipient] = line.trim().split(/\s+/);
76
- if (!type) return undefined;
77
- return {
78
- type,
79
- ...(status && { status }),
80
- ...(issuanceId && { issuanceId }),
81
- ...(recipient && { recipient }),
82
- };
83
- };
84
-
85
- /**
86
- * `--json` mode does not stream: intercept the receiver's own console.log lines (never
87
- * forwarding them to real stdout) and resolve with everything seen once ISSUANCE_DELIVERED
88
- * (and ISSUANCE_CLAIMED, if requested) has arrived, or once the timeout elapses.
89
- */
90
- export const collectWebhookEvents = (
91
- timeoutMs: number,
92
- waitForClaim: boolean,
93
- registerStop?: (stop: () => void) => void
94
- ): Promise<WebhookEvent[]> =>
95
- new Promise(resolve => {
96
- const events: WebhookEvent[] = [];
97
- const originalLog = console.log;
98
- const finish = (): void => {
99
- clearTimeout(timer);
100
- console.log = originalLog;
101
- resolve(events);
102
- };
103
- const timer = setTimeout(finish, Math.max(0, timeoutMs));
104
- registerStop?.(finish);
105
- console.log = (...args: unknown[]): void => {
106
- const [first] = args;
107
- const event = typeof first === 'string' ? parseWebhookLogLine(first) : undefined;
108
- if (!event) return;
109
- events.push(event);
110
- const delivered = events.some(e => e.type === 'ISSUANCE_DELIVERED');
111
- const claimed = events.some(e => e.type === 'ISSUANCE_CLAIMED');
112
- if (delivered && (!waitForClaim || claimed)) finish();
113
- };
114
- });
115
-
116
- export const runWebhook = async (
117
- email: string | undefined,
118
- options: ProjectOptions & {
119
- to?: string;
120
- url?: string;
121
- port?: string;
122
- timeout?: string;
123
- waitForClaim?: boolean;
124
- }
125
- ): Promise<void> => {
126
- const project = await loadProject(process.cwd());
127
- const { port, expectedDid } = webhookConfig(project.env, options);
128
- const production = resolveServices(project.env, options.network).network === PRODUCTION_NETWORK;
129
- if (options.url && production && new URL(options.url).protocol !== 'https:') {
130
- throw new Error('--url must be a public HTTPS URL when using the production network.');
131
- }
132
- const identity = await ensureIdentity(project, options);
133
- const learnCard = await connect(project, { ...options, lca: true });
134
- await ensureProfile(learnCard, identity, project);
135
- const wroteWebhookMjs = await writeSnippet(
136
- 'webhook.mjs',
137
- localizeSnippet(WEBHOOK_MJS, resolveServices(project.env, options.network))
138
- );
139
- const verifier = await initLearnCard({ ...(options.didkit && { didkit: options.didkit }) });
140
- const { createWebhookReceiver } = await loadWebhookModule();
141
- const server = createWebhookReceiver(verifier, expectedDid);
142
- server.requestTimeout = 5000;
143
- await new Promise<void>((resolve, reject) => {
144
- server.once('error', reject);
145
- server.listen(port, () => {
146
- server.removeListener('error', reject);
147
- resolve();
148
- });
149
- });
150
- out.log(`Listening on http://localhost:${port}`);
151
- try {
152
- if (!options.url) {
153
- out.log(
154
- `Next: expose port ${port} with ngrok/cloudflared and re-run with --url <publicUrl>. No credential sent.`
155
- );
156
- out.set({ port, files: wroteWebhookMjs ? ['./webhook.mjs'] : [] });
157
- return;
158
- }
159
- if (!expectedDid) {
160
- out.log(
161
- 'Demo: signatures are verified, but any DID is accepted. Set EXPECTED_NETWORK_DID to your trusted network DID before production.'
162
- );
163
- }
164
- const prompts = createPrompts(options.yes);
165
- let recipient: string;
166
- try {
167
- recipient =
168
- email || options.to || (await prompts.ask('Recipient email (--to <email>)', ''));
169
- } finally {
170
- prompts.close();
171
- }
172
- if (!recipient) throw new Error('Provide an email argument or --to <email>.');
173
- // Template claims need a hosted signer; the demo does not persist signer configuration.
174
- await setupSigning(project, learnCard, undefined, { persist: false });
175
- if (!project.env[KEYS.TEMPLATE_URI]) {
176
- const uri = await learnCard.invoke.createBoost(templateCredential(learnCard.id.did()), {
177
- name: DEFAULT_BADGE.name,
178
- category: 'Achievement',
179
- status: 'LIVE',
180
- });
181
- await saveProject(project, { [KEYS.TEMPLATE_URI]: uri });
182
- }
183
- const templateUri = project.env[KEYS.TEMPLATE_URI]!;
184
- // Start collecting before send() so an ISSUANCE_DELIVERED that arrives mid-call isn't missed.
185
- const timeoutMs = (Number(options.timeout) > 0 ? Number(options.timeout) : 60) * 1000;
186
- let stopCollectingEvents: (() => void) | undefined;
187
- const eventsPromise = out.json
188
- ? collectWebhookEvents(timeoutMs, !!options.waitForClaim, stop => {
189
- stopCollectingEvents = stop;
190
- })
191
- : undefined;
192
- const onServerError = (): void => {};
193
- if (eventsPromise) server.on('error', onServerError);
194
- const result = await learnCard.invoke
195
- .send({
196
- type: 'boost',
197
- recipient,
198
- templateUri,
199
- options: { webhookUrl: options.url },
200
- })
201
- .catch(error => {
202
- if (eventsPromise) {
203
- server.removeListener('error', onServerError);
204
- stopCollectingEvents?.();
205
- }
206
- throw error;
207
- });
208
- out.log(`Sent. Watch for ISSUANCE_DELIVERED ${result.inbox?.status ?? ''}.`);
209
- out.log(
210
- result.inbox?.status === 'PENDING'
211
- ? `Next: click the claim link in your email to see ISSUANCE_CLAIMED. Ctrl+C to stop.`
212
- : 'Next: this recipient already has LearnCard; no claim event is expected. Ctrl+C to stop.'
213
- );
214
- if (eventsPromise) {
215
- const events = await eventsPromise;
216
- server.removeListener('error', onServerError);
217
- out.set({
218
- port,
219
- url: options.url,
220
- templateUri,
221
- issuanceId: result.inbox?.issuanceId,
222
- events,
223
- });
224
- return;
225
- }
226
- await new Promise<void>((resolve, reject) => {
227
- const stop = (): void => {
228
- cleanup();
229
- resolve();
230
- };
231
- const fail = (error: Error): void => {
232
- cleanup();
233
- reject(error);
234
- };
235
- const cleanup = (): void => {
236
- process.removeListener('SIGINT', stop);
237
- process.removeListener('SIGTERM', stop);
238
- server.removeListener('error', fail);
239
- };
240
- process.once('SIGINT', stop);
241
- process.once('SIGTERM', stop);
242
- server.once('error', fail);
243
- });
244
- } finally {
245
- await closeWebhookReceiver(server);
246
- }
247
- };
@@ -1,67 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
- import { Command } from 'commander';
3
-
4
- import { registerWhoamiCommand, summarizeServiceAccounts } from './whoami';
5
- import type { AuthGrantWithActAs } from './auth-grant';
6
-
7
- describe('whoami command', () => {
8
- it('registers with --network and --json only', () => {
9
- const program = new Command();
10
- registerWhoamiCommand(program, async () => {});
11
- const cmd = program.commands.find(c => c.name() === 'whoami');
12
- expect(cmd).toBeDefined();
13
- expect(
14
- program
15
- .createHelp()
16
- .visibleOptions(cmd!)
17
- .map(o => o.long)
18
- .filter(l => l !== '--help')
19
- .sort()
20
- ).toEqual(['--json', '--network']);
21
- });
22
- });
23
-
24
- describe('summarizeServiceAccounts', () => {
25
- it('shapes active grants as { name, scope, actAs } for --json, dropping revoked ones', () => {
26
- const grants: AuthGrantWithActAs[] = [
27
- {
28
- id: 'g1',
29
- name: 'ea-clr-issuer',
30
- status: 'active',
31
- scope: 'inbox:write',
32
- actAs: 'sc-greenville,sc-north',
33
- },
34
- { id: 'g2', name: 'star-issuer', status: 'active', scope: 'inbox:write', actAs: '*' },
35
- { id: 'g3', name: 'no-delegation', status: 'active', scope: 'inbox:write' },
36
- { id: 'g4', name: 'old-issuer', status: 'revoked', scope: 'inbox:write', actAs: '*' },
37
- ];
38
-
39
- expect(summarizeServiceAccounts(grants)).toEqual([
40
- { name: 'ea-clr-issuer', scope: 'inbox:write', actAs: 'sc-greenville,sc-north' },
41
- { name: 'star-issuer', scope: 'inbox:write', actAs: '*' },
42
- { name: 'no-delegation', scope: 'inbox:write', actAs: undefined },
43
- ]);
44
- });
45
-
46
- it('returns an empty array when there are no grants', () => {
47
- expect(summarizeServiceAccounts([])).toEqual([]);
48
- });
49
- });
50
-
51
- describe('LEARNCARD_AS', () => {
52
- it('is the env fallback for --as on inbox list', async () => {
53
- const { registerInboxCommand } = await import('./inbox');
54
- const program = new Command().exitOverride();
55
- let seen: Record<string, unknown> | undefined;
56
- registerInboxCommand(program, async (_cmd, options) => {
57
- seen = options as Record<string, unknown>;
58
- });
59
- process.env.LEARNCARD_AS = 'cs-exampleville';
60
- try {
61
- await program.parseAsync(['node', 'learncard', 'inbox', 'list']);
62
- } finally {
63
- delete process.env.LEARNCARD_AS;
64
- }
65
- expect(seen?.as).toBe('cs-exampleville');
66
- });
67
- });
package/src/whoami.ts DELETED
@@ -1,129 +0,0 @@
1
- import type { Command } from 'commander';
2
- import type { AuthGrantType } from '@learncard/types';
3
-
4
- import {
5
- connect,
6
- connectAsDidWeb,
7
- loadProject,
8
- resolveServices,
9
- type ProjectOptions,
10
- } from './project';
11
- import { out } from './out';
12
- import type { RunCommand } from './doctor';
13
- import { describeActAs, getGrantActAs } from './auth-grant';
14
-
15
- export interface ManagedSummary {
16
- profileId: string;
17
- displayName: string;
18
- did: string;
19
- }
20
-
21
- export interface ServiceAccountSummary {
22
- name: string;
23
- scope: string;
24
- actAs?: string;
25
- }
26
-
27
- /** Only active grants are relevant here; revoked ones are noise for this summary. */
28
- export const summarizeServiceAccounts = (
29
- grants: Array<Partial<AuthGrantType>>
30
- ): ServiceAccountSummary[] =>
31
- grants
32
- .filter(grant => grant.status === 'active')
33
- .map(grant => ({
34
- name: grant.name ?? '',
35
- scope: grant.scope ?? '',
36
- actAs: getGrantActAs(grant),
37
- }));
38
-
39
- export const runWhoami = async (options: ProjectOptions): Promise<void> => {
40
- const project = await loadProject(process.cwd());
41
- if (!project.env.SECURE_SEED) {
42
- throw new Error(
43
- 'No identity in this folder. Run `npx @learncard/cli send you@example.com` or `org apply` first.'
44
- );
45
- }
46
- const services = resolveServices(project.env, options.network);
47
- const learnCard = await connect(project, options);
48
- const profile = await learnCard.invoke.getProfile();
49
-
50
- out.log(
51
- profile
52
- ? `You are "${profile.displayName}" (${profile.profileId}) on ${services.network}`
53
- : `Seed present but no profile on ${services.network} yet (PROFILE_ID=${project.env.PROFILE_ID ?? '?'}).`
54
- );
55
- out.log(` did: ${learnCard.id.did()}`);
56
- if (project.env.SIGNING_AUTHORITY_NAME)
57
- out.log(` signing authority: ${project.env.SIGNING_AUTHORITY_NAME}`);
58
-
59
- const managerDid = project.env.ORG_PROFILE_MANAGER_DID;
60
- const managed: ManagedSummary[] = [];
61
- if (managerDid) {
62
- const manager = await connectAsDidWeb(project, options, managerDid);
63
- let cursor: string | undefined;
64
- do {
65
- const page = await manager.invoke.getManagedProfiles({ limit: 100, cursor });
66
- for (const record of page.records) {
67
- managed.push({
68
- profileId: record.profileId,
69
- displayName: record.displayName,
70
- did: record.did,
71
- });
72
- }
73
- cursor = page.hasMore ? (page.cursor ?? undefined) : undefined;
74
- } while (cursor);
75
-
76
- out.log(` manager: ${managerDid}`);
77
- if (managed.length) {
78
- out.log('You can act as (--as <profileId> or LEARNCARD_AS=<profileId>):');
79
- for (const entry of managed)
80
- out.log(` ${entry.profileId.padEnd(24)} ${entry.displayName}`);
81
- } else {
82
- out.log(
83
- ' no managed profiles yet — add them under profileManager.managed and run `org apply`.'
84
- );
85
- }
86
- }
87
-
88
- const grants = profile ? ((await learnCard.invoke.getAuthGrants()) ?? []) : [];
89
- const serviceAccounts = summarizeServiceAccounts(grants);
90
- if (serviceAccounts.length) {
91
- out.log('Service accounts:');
92
- const nameWidth = Math.max(...serviceAccounts.map(entry => entry.name.length));
93
- const scopeWidth = Math.max(...serviceAccounts.map(entry => entry.scope.length));
94
- for (const entry of serviceAccounts)
95
- out.log(
96
- ` ${entry.name.padEnd(nameWidth)} ${entry.scope.padEnd(scopeWidth)} ${describeActAs(entry.actAs)}`
97
- );
98
- }
99
-
100
- if (process.env.LEARNCARD_AS)
101
- out.log(
102
- `LEARNCARD_AS is set: commands that support --as will act as "${process.env.LEARNCARD_AS}".`
103
- );
104
-
105
- out.set({
106
- network: services.network,
107
- profileId: profile?.profileId ?? project.env.PROFILE_ID,
108
- displayName: profile?.displayName,
109
- did: learnCard.id.did(),
110
- signingAuthority: project.env.SIGNING_AUTHORITY_NAME,
111
- managerDid,
112
- managed,
113
- serviceAccounts,
114
- actingAs: process.env.LEARNCARD_AS,
115
- });
116
- };
117
-
118
- export const registerWhoamiCommand = (program: Command, run: RunCommand): void => {
119
- program
120
- .command('whoami')
121
- .description('Show the identity in this folder and the managed profiles --as can target.')
122
- .option('--network <url>', 'network tRPC URL or staging (default: production)')
123
- .option('--json', 'print a single JSON result on stdout')
124
- .action(options =>
125
- run('whoami', options, async didkit => {
126
- await runWhoami({ ...options, didkit });
127
- })
128
- );
129
- };
package/tsconfig.json DELETED
@@ -1,38 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.library.json",
3
- "compilerOptions": {
4
- "lib": ["es2022", "DOM"],
5
- "module": "esnext",
6
- "moduleResolution": "bundler",
7
- "resolveJsonModule": true,
8
- "removeComments": true,
9
- "preserveConstEnums": true,
10
- "strict": true,
11
- "alwaysStrict": true,
12
- "strictNullChecks": true,
13
- "noUncheckedIndexedAccess": true,
14
- "jsx": "react",
15
-
16
- "noImplicitAny": true,
17
- "noImplicitReturns": true,
18
- "noImplicitThis": true,
19
- "noUnusedLocals": true,
20
- "noUnusedParameters": true,
21
- "allowUnreachableCode": false,
22
- "noFallthroughCasesInSwitch": true,
23
-
24
- "target": "es2017",
25
- "outDir": "dist",
26
- "declaration": true,
27
- "declarationMap": true,
28
- "sourceMap": true,
29
-
30
- "esModuleInterop": true,
31
- "allowSyntheticDefaultImports": true,
32
- "allowJs": false,
33
- "skipLibCheck": true,
34
- "forceConsistentCasingInFileNames": true
35
- },
36
- "include": ["src/**/*", "scripts/**/*.ts"],
37
- "exclude": ["./dist/**/*", "./node_modules/**/*"]
38
- }
package/vitest.config.ts DELETED
@@ -1,8 +0,0 @@
1
- import { createVitestConfig, nodePreset } from '../../vitest.shared';
2
-
3
- export default createVitestConfig(nodePreset, {
4
- test: {
5
- include: ['src/**/*.test.ts'],
6
- exclude: ['src/bundle/**'],
7
- },
8
- });