@learncard/network-plugin 3.1.3 → 3.2.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.
@@ -560,6 +560,41 @@ describe('unified send with refresh: true (managed branch)', () => {
560
560
  expect(client.credentialRefresh.sendRefreshableCredential.mutate).not.toHaveBeenCalled();
561
561
  });
562
562
 
563
+ it('materializes standard spreadsheet fields before ordinary local profile signing', async () => {
564
+ const client = getMockClient();
565
+ client.boost.getBoost.query.mockResolvedValue({
566
+ boost: getUnsignedBoostTemplate({
567
+ '@context': [
568
+ 'https://www.w3.org/ns/credentials/v2',
569
+ 'https://purl.imsglobal.org/spec/ob/v3p0/context-3.0.3.json',
570
+ ],
571
+ type: ['VerifiableCredential', 'OpenBadgeCredential'],
572
+ awardedDate: '{{award_date}}',
573
+ credentialSubject: {
574
+ id: 'did:example:subject',
575
+ creditsEarned: '{{credits}}',
576
+ result: [{ type: ['Result'], value: '{{grade}}' }],
577
+ },
578
+ }),
579
+ });
580
+ const learnCard = getMockIssuingLearnCard();
581
+ const plugin = await getPlugin(learnCard, client);
582
+ await plugin.methods?.send(learnCard, {
583
+ type: 'boost',
584
+ recipient: 'userb',
585
+ templateUri: 'did:web:network.example:boost:1',
586
+ templateData: { credits: '0', grade: 'A-', award_date: '2024-02-29' },
587
+ });
588
+ const signed = learnCard.invoke.issueCredential.mock.calls[0][0];
589
+ expect(signed.credentialSubject).toMatchObject({
590
+ creditsEarned: 0,
591
+ result: [{ value: 'A-' }],
592
+ });
593
+ expect(signed.awardedDate).toBe('2024-02-29T00:00:00.000Z');
594
+ expect(signed.validFrom).not.toBe(signed.awardedDate);
595
+ expect(signed.type).not.toContain('BoostCredential');
596
+ });
597
+
563
598
  it('keeps absent-refresh sends on their existing local branch with no allocation', async () => {
564
599
  const client = getMockClient();
565
600
  const learnCard = getMockIssuingLearnCard();
package/src/types.ts CHANGED
@@ -1,5 +1,20 @@
1
1
  import type { SendContractRequest, ConsentFlowContractRequestForProfile } from '@learncard/types';
2
2
  import type { LCNClient } from '@learncard/network-brain-client';
3
+ import type {
4
+ Campaign,
5
+ CampaignAudienceInput,
6
+ CampaignEvent,
7
+ CampaignStats,
8
+ CampaignStatus,
9
+ CreateCampaignInput,
10
+ UpdateCampaignInput,
11
+ ListCampaignsInput,
12
+ MyCampaign,
13
+ PageCampaignAudienceInput,
14
+ PaginatedCampaigns,
15
+ PaginatedCampaignAudience,
16
+ PublishCredentialSharePreview,
17
+ } from '@learncard/types';
3
18
  import {
4
19
  LCNProfile,
5
20
  LCNVisibleProfile,
@@ -213,6 +228,15 @@ export type LearnCardNetworkPluginDependentMethods = {
213
228
 
214
229
  /** @group LearnCardNetwork Plugin */
215
230
  export type LearnCardNetworkPluginMethods = {
231
+ /**
232
+ * Publish opted-in, publisher-supplied metadata bound to an encrypted presentation URI.
233
+ * Provide an owned preview ID and the same URI to refresh it; its URI cannot be rebound.
234
+ * A missing or mismatched refresh returns NOT_FOUND. This does not verify the credential or issuer.
235
+ * Returns an opaque UUID; public lookup also requires the matching share URI.
236
+ */
237
+ publishCredentialSharePreview: (preview: PublishCredentialSharePreview) => Promise<string>;
238
+ /** Remove an owned preview; returns false if absent/unowned. Social copies may persist. */
239
+ deleteCredentialSharePreview: (id: string) => Promise<boolean>;
216
240
  createProfile: (
217
241
  profile: Omit<LCNProfile, 'did' | 'isServiceProfile'> & { authToken?: string }
218
242
  ) => Promise<string>;
@@ -1106,6 +1130,20 @@ export type LearnCardNetworkPluginMethods = {
1106
1130
  }>;
1107
1131
 
1108
1132
  isAppStoreAdmin: () => Promise<boolean>;
1133
+ campaignsIsAdmin: () => Promise<boolean>;
1134
+ campaignsCreate: (input: CreateCampaignInput) => Promise<Campaign>;
1135
+ campaignsUpdate: (input: UpdateCampaignInput) => Promise<Campaign>;
1136
+ campaignsGet: (campaignId: string) => Promise<Campaign>;
1137
+ campaignsList: (input?: ListCampaignsInput) => Promise<PaginatedCampaigns>;
1138
+ campaignsDelete: (campaignId: string) => Promise<boolean>;
1139
+ campaignsSetStatus: (campaignId: string, status: CampaignStatus) => Promise<Campaign>;
1140
+ campaignsPreviewAudience: (input: CampaignAudienceInput) => Promise<{ count: number }>;
1141
+ campaignsAddAudience: (input: CampaignAudienceInput) => Promise<{ count: number }>;
1142
+ campaignsPageAudience: (input: PageCampaignAudienceInput) => Promise<PaginatedCampaignAudience>;
1143
+ campaignsGetStats: (campaignId: string) => Promise<CampaignStats>;
1144
+ getMyCampaigns: () => Promise<MyCampaign[]>;
1145
+ recordCampaignEvent: (campaignId: string, event: CampaignEvent) => Promise<boolean>;
1146
+ enrollInCampaign: (campaignId: string) => Promise<boolean>;
1109
1147
  adminUpdateListingStatus: (listingId: string, status: AppListingStatus) => Promise<boolean>;
1110
1148
  adminUpdatePromotionLevel: (
1111
1149
  listingId: string,