@singi-labs/sifa-sdk 0.19.37 → 0.19.38
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/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{network-map-DUm6FBXt.d.cts → network-map-B0bp4-ex.d.cts} +47 -1
- package/dist/{network-map-DzVNvC9g.d.ts → network-map-C-y5XxLI.d.ts} +47 -1
- package/dist/query/fetchers/index.cjs +30 -0
- package/dist/query/fetchers/index.cjs.map +1 -1
- package/dist/query/fetchers/index.d.cts +1 -1
- package/dist/query/fetchers/index.d.ts +1 -1
- package/dist/query/fetchers/index.js +28 -1
- package/dist/query/fetchers/index.js.map +1 -1
- package/dist/query/index.cjs +30 -0
- package/dist/query/index.cjs.map +1 -1
- package/dist/query/index.d.cts +2 -2
- package/dist/query/index.d.ts +2 -2
- package/dist/query/index.js +28 -1
- package/dist/query/index.js.map +1 -1
- package/dist/rpg/index.cjs +122 -0
- package/dist/rpg/index.cjs.map +1 -0
- package/dist/rpg/index.d.cts +74 -0
- package/dist/rpg/index.d.ts +74 -0
- package/dist/rpg/index.js +117 -0
- package/dist/rpg/index.js.map +1 -0
- package/package.json +11 -1
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var zod = require('zod');
|
|
4
|
+
|
|
5
|
+
// src/rpg/catalog.ts
|
|
6
|
+
var RpgUnlockSchema = zod.z.discriminatedUnion("kind", [
|
|
7
|
+
zod.z.object({
|
|
8
|
+
kind: zod.z.literal("hasRecord"),
|
|
9
|
+
collection: zod.z.enum([
|
|
10
|
+
"id.sifa.profile.position",
|
|
11
|
+
"id.sifa.profile.volunteering",
|
|
12
|
+
"id.sifa.profile.presentation",
|
|
13
|
+
"id.sifa.profile.education"
|
|
14
|
+
])
|
|
15
|
+
}),
|
|
16
|
+
zod.z.object({ kind: zod.z.literal("hasExternalAccount"), platforms: zod.z.array(zod.z.string()).min(1) }),
|
|
17
|
+
zod.z.object({ kind: zod.z.literal("usesApp"), appId: zod.z.string().min(1) }),
|
|
18
|
+
zod.z.object({ kind: zod.z.literal("hasDoctorate") })
|
|
19
|
+
]);
|
|
20
|
+
var RpgItemSchema = zod.z.object({
|
|
21
|
+
/** Lowercase `[a-z0-9_]` only: the id is embedded in an AT Protocol record key. */
|
|
22
|
+
id: zod.z.string().min(1).max(50).regex(/^[a-z0-9_]+$/),
|
|
23
|
+
title: zod.z.string().max(100),
|
|
24
|
+
description: zod.z.string().max(500),
|
|
25
|
+
kind: zod.z.enum(["layer", "held"]),
|
|
26
|
+
category: zod.z.string().max(30),
|
|
27
|
+
unlock: zod.z.array(RpgUnlockSchema).min(1),
|
|
28
|
+
// ANY of these unlocks the item
|
|
29
|
+
enabled: zod.z.boolean()
|
|
30
|
+
});
|
|
31
|
+
var RPG_ITEMS = [
|
|
32
|
+
{
|
|
33
|
+
id: "sifa_power_suit",
|
|
34
|
+
title: "Power Suit",
|
|
35
|
+
description: "",
|
|
36
|
+
kind: "layer",
|
|
37
|
+
category: "tops",
|
|
38
|
+
enabled: true,
|
|
39
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.position" }]
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "sifa_weekend_shirt",
|
|
43
|
+
title: "Weekend Shirt",
|
|
44
|
+
description: "",
|
|
45
|
+
kind: "layer",
|
|
46
|
+
category: "tops",
|
|
47
|
+
enabled: true,
|
|
48
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.volunteering" }]
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
id: "sifa_speaker_mic",
|
|
52
|
+
title: "Speaker Mic",
|
|
53
|
+
description: "",
|
|
54
|
+
kind: "held",
|
|
55
|
+
category: "righthand",
|
|
56
|
+
enabled: true,
|
|
57
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.presentation" }]
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
id: "sifa_school_books",
|
|
61
|
+
title: "School Books",
|
|
62
|
+
description: "",
|
|
63
|
+
kind: "held",
|
|
64
|
+
category: "lefthand",
|
|
65
|
+
enabled: true,
|
|
66
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.education" }]
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: "sifa_doctoral_cap",
|
|
70
|
+
title: "Doctoral Cap",
|
|
71
|
+
description: "",
|
|
72
|
+
kind: "layer",
|
|
73
|
+
category: "headwear",
|
|
74
|
+
enabled: false,
|
|
75
|
+
unlock: [{ kind: "hasDoctorate" }]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
id: "sifa_lab_coat",
|
|
79
|
+
title: "Lab Coat",
|
|
80
|
+
description: "",
|
|
81
|
+
kind: "layer",
|
|
82
|
+
category: "tops",
|
|
83
|
+
enabled: true,
|
|
84
|
+
unlock: [{ kind: "hasExternalAccount", platforms: ["orcid"] }]
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: "sifa_dev_hoodie",
|
|
88
|
+
title: "Dev Hoodie",
|
|
89
|
+
description: "",
|
|
90
|
+
kind: "layer",
|
|
91
|
+
category: "tops",
|
|
92
|
+
enabled: true,
|
|
93
|
+
unlock: [
|
|
94
|
+
{ kind: "hasExternalAccount", platforms: ["github"] },
|
|
95
|
+
{ kind: "usesApp", appId: "tangled" }
|
|
96
|
+
]
|
|
97
|
+
}
|
|
98
|
+
];
|
|
99
|
+
|
|
100
|
+
// src/rpg/unlocks.ts
|
|
101
|
+
function matches(u, s) {
|
|
102
|
+
switch (u.kind) {
|
|
103
|
+
case "hasRecord":
|
|
104
|
+
return s.collections.includes(u.collection);
|
|
105
|
+
case "hasExternalAccount":
|
|
106
|
+
return u.platforms.some((p) => s.externalPlatforms.includes(p));
|
|
107
|
+
case "usesApp":
|
|
108
|
+
return s.activeAppIds.includes(u.appId);
|
|
109
|
+
case "hasDoctorate":
|
|
110
|
+
return s.hasDoctorate;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
function evaluateRpgUnlocks(signals, items = RPG_ITEMS) {
|
|
114
|
+
return items.filter((item) => item.enabled).map((item) => ({ item, earned: item.unlock.some((u) => matches(u, signals)) }));
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
exports.RPG_ITEMS = RPG_ITEMS;
|
|
118
|
+
exports.RpgItemSchema = RpgItemSchema;
|
|
119
|
+
exports.RpgUnlockSchema = RpgUnlockSchema;
|
|
120
|
+
exports.evaluateRpgUnlocks = evaluateRpgUnlocks;
|
|
121
|
+
//# sourceMappingURL=index.cjs.map
|
|
122
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/rpg/catalog.ts","../../src/rpg/unlocks.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["import { z } from 'zod';\n\nexport const RpgUnlockSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('hasRecord'),\n collection: z.enum([\n 'id.sifa.profile.position',\n 'id.sifa.profile.volunteering',\n 'id.sifa.profile.presentation',\n 'id.sifa.profile.education',\n ]),\n }),\n z.object({ kind: z.literal('hasExternalAccount'), platforms: z.array(z.string()).min(1) }),\n z.object({ kind: z.literal('usesApp'), appId: z.string().min(1) }),\n z.object({ kind: z.literal('hasDoctorate') }),\n]);\n\nexport const RpgItemSchema = z.object({\n /** Lowercase `[a-z0-9_]` only: the id is embedded in an AT Protocol record key. */\n id: z\n .string()\n .min(1)\n .max(50)\n .regex(/^[a-z0-9_]+$/),\n title: z.string().max(100),\n description: z.string().max(500),\n kind: z.enum(['layer', 'held']),\n category: z.string().max(30),\n unlock: z.array(RpgUnlockSchema).min(1), // ANY of these unlocks the item\n enabled: z.boolean(),\n});\nexport type RpgItem = z.infer<typeof RpgItemSchema>;\nexport type RpgUnlock = z.infer<typeof RpgUnlockSchema>;\n\n/**\n * The Sifa item catalog for rpg.actor. PLACEHOLDER titles/categories until\n * rpg.actor transfers the real item cores.\n */\nexport const RPG_ITEMS: readonly RpgItem[] = [\n {\n id: 'sifa_power_suit',\n title: 'Power Suit',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.position' }],\n },\n {\n id: 'sifa_weekend_shirt',\n title: 'Weekend Shirt',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.volunteering' }],\n },\n {\n id: 'sifa_speaker_mic',\n title: 'Speaker Mic',\n description: '',\n kind: 'held',\n category: 'righthand',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.presentation' }],\n },\n {\n id: 'sifa_school_books',\n title: 'School Books',\n description: '',\n kind: 'held',\n category: 'lefthand',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.education' }],\n },\n {\n id: 'sifa_doctoral_cap',\n title: 'Doctoral Cap',\n description: '',\n kind: 'layer',\n category: 'headwear',\n enabled: false,\n unlock: [{ kind: 'hasDoctorate' }],\n },\n {\n id: 'sifa_lab_coat',\n title: 'Lab Coat',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasExternalAccount', platforms: ['orcid'] }],\n },\n {\n id: 'sifa_dev_hoodie',\n title: 'Dev Hoodie',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [\n { kind: 'hasExternalAccount', platforms: ['github'] },\n { kind: 'usesApp', appId: 'tangled' },\n ],\n },\n];\n","import { RPG_ITEMS, type RpgItem, type RpgUnlock } from './catalog.js';\n\n/**\n * Profile signals the unlock rules are checked against. Callers must pass\n * lowercase platform codes (e.g. 'github', 'orcid') and registry app ids (e.g. 'tangled').\n */\nexport interface RpgUnlockSignals {\n collections: readonly string[];\n externalPlatforms: readonly string[];\n activeAppIds: readonly string[];\n hasDoctorate: boolean;\n}\n\n/** One enabled catalog item and whether the signals earn it. */\nexport interface RpgUnlockResult {\n item: RpgItem;\n earned: boolean;\n}\n\nfunction matches(u: RpgUnlock, s: RpgUnlockSignals): boolean {\n switch (u.kind) {\n case 'hasRecord':\n return s.collections.includes(u.collection);\n case 'hasExternalAccount':\n return u.platforms.some((p) => s.externalPlatforms.includes(p));\n case 'usesApp':\n return s.activeAppIds.includes(u.appId);\n case 'hasDoctorate':\n return s.hasDoctorate;\n }\n}\n\n/** Evaluate every enabled item (ANY matching unlock earns it); disabled items are omitted. */\nexport function evaluateRpgUnlocks(\n signals: RpgUnlockSignals,\n items: readonly RpgItem[] = RPG_ITEMS,\n): RpgUnlockResult[] {\n return items\n .filter((item) => item.enabled)\n .map((item) => ({ item, earned: item.unlock.some((u) => matches(u, signals)) }));\n}\n"]}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const RpgUnlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
kind: z.ZodLiteral<"hasRecord">;
|
|
5
|
+
collection: z.ZodEnum<{
|
|
6
|
+
"id.sifa.profile.position": "id.sifa.profile.position";
|
|
7
|
+
"id.sifa.profile.volunteering": "id.sifa.profile.volunteering";
|
|
8
|
+
"id.sifa.profile.presentation": "id.sifa.profile.presentation";
|
|
9
|
+
"id.sifa.profile.education": "id.sifa.profile.education";
|
|
10
|
+
}>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
kind: z.ZodLiteral<"hasExternalAccount">;
|
|
13
|
+
platforms: z.ZodArray<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"usesApp">;
|
|
16
|
+
appId: z.ZodString;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
kind: z.ZodLiteral<"hasDoctorate">;
|
|
19
|
+
}, z.core.$strip>], "kind">;
|
|
20
|
+
declare const RpgItemSchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
title: z.ZodString;
|
|
23
|
+
description: z.ZodString;
|
|
24
|
+
kind: z.ZodEnum<{
|
|
25
|
+
layer: "layer";
|
|
26
|
+
held: "held";
|
|
27
|
+
}>;
|
|
28
|
+
category: z.ZodString;
|
|
29
|
+
unlock: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
30
|
+
kind: z.ZodLiteral<"hasRecord">;
|
|
31
|
+
collection: z.ZodEnum<{
|
|
32
|
+
"id.sifa.profile.position": "id.sifa.profile.position";
|
|
33
|
+
"id.sifa.profile.volunteering": "id.sifa.profile.volunteering";
|
|
34
|
+
"id.sifa.profile.presentation": "id.sifa.profile.presentation";
|
|
35
|
+
"id.sifa.profile.education": "id.sifa.profile.education";
|
|
36
|
+
}>;
|
|
37
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
38
|
+
kind: z.ZodLiteral<"hasExternalAccount">;
|
|
39
|
+
platforms: z.ZodArray<z.ZodString>;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
kind: z.ZodLiteral<"usesApp">;
|
|
42
|
+
appId: z.ZodString;
|
|
43
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
44
|
+
kind: z.ZodLiteral<"hasDoctorate">;
|
|
45
|
+
}, z.core.$strip>], "kind">>;
|
|
46
|
+
enabled: z.ZodBoolean;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
type RpgItem = z.infer<typeof RpgItemSchema>;
|
|
49
|
+
type RpgUnlock = z.infer<typeof RpgUnlockSchema>;
|
|
50
|
+
/**
|
|
51
|
+
* The Sifa item catalog for rpg.actor. PLACEHOLDER titles/categories until
|
|
52
|
+
* rpg.actor transfers the real item cores.
|
|
53
|
+
*/
|
|
54
|
+
declare const RPG_ITEMS: readonly RpgItem[];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Profile signals the unlock rules are checked against. Callers must pass
|
|
58
|
+
* lowercase platform codes (e.g. 'github', 'orcid') and registry app ids (e.g. 'tangled').
|
|
59
|
+
*/
|
|
60
|
+
interface RpgUnlockSignals {
|
|
61
|
+
collections: readonly string[];
|
|
62
|
+
externalPlatforms: readonly string[];
|
|
63
|
+
activeAppIds: readonly string[];
|
|
64
|
+
hasDoctorate: boolean;
|
|
65
|
+
}
|
|
66
|
+
/** One enabled catalog item and whether the signals earn it. */
|
|
67
|
+
interface RpgUnlockResult {
|
|
68
|
+
item: RpgItem;
|
|
69
|
+
earned: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** Evaluate every enabled item (ANY matching unlock earns it); disabled items are omitted. */
|
|
72
|
+
declare function evaluateRpgUnlocks(signals: RpgUnlockSignals, items?: readonly RpgItem[]): RpgUnlockResult[];
|
|
73
|
+
|
|
74
|
+
export { RPG_ITEMS, type RpgItem, RpgItemSchema, type RpgUnlock, type RpgUnlockResult, RpgUnlockSchema, type RpgUnlockSignals, evaluateRpgUnlocks };
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
declare const RpgUnlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
kind: z.ZodLiteral<"hasRecord">;
|
|
5
|
+
collection: z.ZodEnum<{
|
|
6
|
+
"id.sifa.profile.position": "id.sifa.profile.position";
|
|
7
|
+
"id.sifa.profile.volunteering": "id.sifa.profile.volunteering";
|
|
8
|
+
"id.sifa.profile.presentation": "id.sifa.profile.presentation";
|
|
9
|
+
"id.sifa.profile.education": "id.sifa.profile.education";
|
|
10
|
+
}>;
|
|
11
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
12
|
+
kind: z.ZodLiteral<"hasExternalAccount">;
|
|
13
|
+
platforms: z.ZodArray<z.ZodString>;
|
|
14
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
15
|
+
kind: z.ZodLiteral<"usesApp">;
|
|
16
|
+
appId: z.ZodString;
|
|
17
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
18
|
+
kind: z.ZodLiteral<"hasDoctorate">;
|
|
19
|
+
}, z.core.$strip>], "kind">;
|
|
20
|
+
declare const RpgItemSchema: z.ZodObject<{
|
|
21
|
+
id: z.ZodString;
|
|
22
|
+
title: z.ZodString;
|
|
23
|
+
description: z.ZodString;
|
|
24
|
+
kind: z.ZodEnum<{
|
|
25
|
+
layer: "layer";
|
|
26
|
+
held: "held";
|
|
27
|
+
}>;
|
|
28
|
+
category: z.ZodString;
|
|
29
|
+
unlock: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
30
|
+
kind: z.ZodLiteral<"hasRecord">;
|
|
31
|
+
collection: z.ZodEnum<{
|
|
32
|
+
"id.sifa.profile.position": "id.sifa.profile.position";
|
|
33
|
+
"id.sifa.profile.volunteering": "id.sifa.profile.volunteering";
|
|
34
|
+
"id.sifa.profile.presentation": "id.sifa.profile.presentation";
|
|
35
|
+
"id.sifa.profile.education": "id.sifa.profile.education";
|
|
36
|
+
}>;
|
|
37
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
38
|
+
kind: z.ZodLiteral<"hasExternalAccount">;
|
|
39
|
+
platforms: z.ZodArray<z.ZodString>;
|
|
40
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
41
|
+
kind: z.ZodLiteral<"usesApp">;
|
|
42
|
+
appId: z.ZodString;
|
|
43
|
+
}, z.core.$strip>, z.ZodObject<{
|
|
44
|
+
kind: z.ZodLiteral<"hasDoctorate">;
|
|
45
|
+
}, z.core.$strip>], "kind">>;
|
|
46
|
+
enabled: z.ZodBoolean;
|
|
47
|
+
}, z.core.$strip>;
|
|
48
|
+
type RpgItem = z.infer<typeof RpgItemSchema>;
|
|
49
|
+
type RpgUnlock = z.infer<typeof RpgUnlockSchema>;
|
|
50
|
+
/**
|
|
51
|
+
* The Sifa item catalog for rpg.actor. PLACEHOLDER titles/categories until
|
|
52
|
+
* rpg.actor transfers the real item cores.
|
|
53
|
+
*/
|
|
54
|
+
declare const RPG_ITEMS: readonly RpgItem[];
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Profile signals the unlock rules are checked against. Callers must pass
|
|
58
|
+
* lowercase platform codes (e.g. 'github', 'orcid') and registry app ids (e.g. 'tangled').
|
|
59
|
+
*/
|
|
60
|
+
interface RpgUnlockSignals {
|
|
61
|
+
collections: readonly string[];
|
|
62
|
+
externalPlatforms: readonly string[];
|
|
63
|
+
activeAppIds: readonly string[];
|
|
64
|
+
hasDoctorate: boolean;
|
|
65
|
+
}
|
|
66
|
+
/** One enabled catalog item and whether the signals earn it. */
|
|
67
|
+
interface RpgUnlockResult {
|
|
68
|
+
item: RpgItem;
|
|
69
|
+
earned: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** Evaluate every enabled item (ANY matching unlock earns it); disabled items are omitted. */
|
|
72
|
+
declare function evaluateRpgUnlocks(signals: RpgUnlockSignals, items?: readonly RpgItem[]): RpgUnlockResult[];
|
|
73
|
+
|
|
74
|
+
export { RPG_ITEMS, type RpgItem, RpgItemSchema, type RpgUnlock, type RpgUnlockResult, RpgUnlockSchema, type RpgUnlockSignals, evaluateRpgUnlocks };
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
|
|
3
|
+
// src/rpg/catalog.ts
|
|
4
|
+
var RpgUnlockSchema = z.discriminatedUnion("kind", [
|
|
5
|
+
z.object({
|
|
6
|
+
kind: z.literal("hasRecord"),
|
|
7
|
+
collection: z.enum([
|
|
8
|
+
"id.sifa.profile.position",
|
|
9
|
+
"id.sifa.profile.volunteering",
|
|
10
|
+
"id.sifa.profile.presentation",
|
|
11
|
+
"id.sifa.profile.education"
|
|
12
|
+
])
|
|
13
|
+
}),
|
|
14
|
+
z.object({ kind: z.literal("hasExternalAccount"), platforms: z.array(z.string()).min(1) }),
|
|
15
|
+
z.object({ kind: z.literal("usesApp"), appId: z.string().min(1) }),
|
|
16
|
+
z.object({ kind: z.literal("hasDoctorate") })
|
|
17
|
+
]);
|
|
18
|
+
var RpgItemSchema = z.object({
|
|
19
|
+
/** Lowercase `[a-z0-9_]` only: the id is embedded in an AT Protocol record key. */
|
|
20
|
+
id: z.string().min(1).max(50).regex(/^[a-z0-9_]+$/),
|
|
21
|
+
title: z.string().max(100),
|
|
22
|
+
description: z.string().max(500),
|
|
23
|
+
kind: z.enum(["layer", "held"]),
|
|
24
|
+
category: z.string().max(30),
|
|
25
|
+
unlock: z.array(RpgUnlockSchema).min(1),
|
|
26
|
+
// ANY of these unlocks the item
|
|
27
|
+
enabled: z.boolean()
|
|
28
|
+
});
|
|
29
|
+
var RPG_ITEMS = [
|
|
30
|
+
{
|
|
31
|
+
id: "sifa_power_suit",
|
|
32
|
+
title: "Power Suit",
|
|
33
|
+
description: "",
|
|
34
|
+
kind: "layer",
|
|
35
|
+
category: "tops",
|
|
36
|
+
enabled: true,
|
|
37
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.position" }]
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
id: "sifa_weekend_shirt",
|
|
41
|
+
title: "Weekend Shirt",
|
|
42
|
+
description: "",
|
|
43
|
+
kind: "layer",
|
|
44
|
+
category: "tops",
|
|
45
|
+
enabled: true,
|
|
46
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.volunteering" }]
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
id: "sifa_speaker_mic",
|
|
50
|
+
title: "Speaker Mic",
|
|
51
|
+
description: "",
|
|
52
|
+
kind: "held",
|
|
53
|
+
category: "righthand",
|
|
54
|
+
enabled: true,
|
|
55
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.presentation" }]
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "sifa_school_books",
|
|
59
|
+
title: "School Books",
|
|
60
|
+
description: "",
|
|
61
|
+
kind: "held",
|
|
62
|
+
category: "lefthand",
|
|
63
|
+
enabled: true,
|
|
64
|
+
unlock: [{ kind: "hasRecord", collection: "id.sifa.profile.education" }]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
id: "sifa_doctoral_cap",
|
|
68
|
+
title: "Doctoral Cap",
|
|
69
|
+
description: "",
|
|
70
|
+
kind: "layer",
|
|
71
|
+
category: "headwear",
|
|
72
|
+
enabled: false,
|
|
73
|
+
unlock: [{ kind: "hasDoctorate" }]
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
id: "sifa_lab_coat",
|
|
77
|
+
title: "Lab Coat",
|
|
78
|
+
description: "",
|
|
79
|
+
kind: "layer",
|
|
80
|
+
category: "tops",
|
|
81
|
+
enabled: true,
|
|
82
|
+
unlock: [{ kind: "hasExternalAccount", platforms: ["orcid"] }]
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
id: "sifa_dev_hoodie",
|
|
86
|
+
title: "Dev Hoodie",
|
|
87
|
+
description: "",
|
|
88
|
+
kind: "layer",
|
|
89
|
+
category: "tops",
|
|
90
|
+
enabled: true,
|
|
91
|
+
unlock: [
|
|
92
|
+
{ kind: "hasExternalAccount", platforms: ["github"] },
|
|
93
|
+
{ kind: "usesApp", appId: "tangled" }
|
|
94
|
+
]
|
|
95
|
+
}
|
|
96
|
+
];
|
|
97
|
+
|
|
98
|
+
// src/rpg/unlocks.ts
|
|
99
|
+
function matches(u, s) {
|
|
100
|
+
switch (u.kind) {
|
|
101
|
+
case "hasRecord":
|
|
102
|
+
return s.collections.includes(u.collection);
|
|
103
|
+
case "hasExternalAccount":
|
|
104
|
+
return u.platforms.some((p) => s.externalPlatforms.includes(p));
|
|
105
|
+
case "usesApp":
|
|
106
|
+
return s.activeAppIds.includes(u.appId);
|
|
107
|
+
case "hasDoctorate":
|
|
108
|
+
return s.hasDoctorate;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
function evaluateRpgUnlocks(signals, items = RPG_ITEMS) {
|
|
112
|
+
return items.filter((item) => item.enabled).map((item) => ({ item, earned: item.unlock.some((u) => matches(u, signals)) }));
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export { RPG_ITEMS, RpgItemSchema, RpgUnlockSchema, evaluateRpgUnlocks };
|
|
116
|
+
//# sourceMappingURL=index.js.map
|
|
117
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/rpg/catalog.ts","../../src/rpg/unlocks.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import { z } from 'zod';\n\nexport const RpgUnlockSchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal('hasRecord'),\n collection: z.enum([\n 'id.sifa.profile.position',\n 'id.sifa.profile.volunteering',\n 'id.sifa.profile.presentation',\n 'id.sifa.profile.education',\n ]),\n }),\n z.object({ kind: z.literal('hasExternalAccount'), platforms: z.array(z.string()).min(1) }),\n z.object({ kind: z.literal('usesApp'), appId: z.string().min(1) }),\n z.object({ kind: z.literal('hasDoctorate') }),\n]);\n\nexport const RpgItemSchema = z.object({\n /** Lowercase `[a-z0-9_]` only: the id is embedded in an AT Protocol record key. */\n id: z\n .string()\n .min(1)\n .max(50)\n .regex(/^[a-z0-9_]+$/),\n title: z.string().max(100),\n description: z.string().max(500),\n kind: z.enum(['layer', 'held']),\n category: z.string().max(30),\n unlock: z.array(RpgUnlockSchema).min(1), // ANY of these unlocks the item\n enabled: z.boolean(),\n});\nexport type RpgItem = z.infer<typeof RpgItemSchema>;\nexport type RpgUnlock = z.infer<typeof RpgUnlockSchema>;\n\n/**\n * The Sifa item catalog for rpg.actor. PLACEHOLDER titles/categories until\n * rpg.actor transfers the real item cores.\n */\nexport const RPG_ITEMS: readonly RpgItem[] = [\n {\n id: 'sifa_power_suit',\n title: 'Power Suit',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.position' }],\n },\n {\n id: 'sifa_weekend_shirt',\n title: 'Weekend Shirt',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.volunteering' }],\n },\n {\n id: 'sifa_speaker_mic',\n title: 'Speaker Mic',\n description: '',\n kind: 'held',\n category: 'righthand',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.presentation' }],\n },\n {\n id: 'sifa_school_books',\n title: 'School Books',\n description: '',\n kind: 'held',\n category: 'lefthand',\n enabled: true,\n unlock: [{ kind: 'hasRecord', collection: 'id.sifa.profile.education' }],\n },\n {\n id: 'sifa_doctoral_cap',\n title: 'Doctoral Cap',\n description: '',\n kind: 'layer',\n category: 'headwear',\n enabled: false,\n unlock: [{ kind: 'hasDoctorate' }],\n },\n {\n id: 'sifa_lab_coat',\n title: 'Lab Coat',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [{ kind: 'hasExternalAccount', platforms: ['orcid'] }],\n },\n {\n id: 'sifa_dev_hoodie',\n title: 'Dev Hoodie',\n description: '',\n kind: 'layer',\n category: 'tops',\n enabled: true,\n unlock: [\n { kind: 'hasExternalAccount', platforms: ['github'] },\n { kind: 'usesApp', appId: 'tangled' },\n ],\n },\n];\n","import { RPG_ITEMS, type RpgItem, type RpgUnlock } from './catalog.js';\n\n/**\n * Profile signals the unlock rules are checked against. Callers must pass\n * lowercase platform codes (e.g. 'github', 'orcid') and registry app ids (e.g. 'tangled').\n */\nexport interface RpgUnlockSignals {\n collections: readonly string[];\n externalPlatforms: readonly string[];\n activeAppIds: readonly string[];\n hasDoctorate: boolean;\n}\n\n/** One enabled catalog item and whether the signals earn it. */\nexport interface RpgUnlockResult {\n item: RpgItem;\n earned: boolean;\n}\n\nfunction matches(u: RpgUnlock, s: RpgUnlockSignals): boolean {\n switch (u.kind) {\n case 'hasRecord':\n return s.collections.includes(u.collection);\n case 'hasExternalAccount':\n return u.platforms.some((p) => s.externalPlatforms.includes(p));\n case 'usesApp':\n return s.activeAppIds.includes(u.appId);\n case 'hasDoctorate':\n return s.hasDoctorate;\n }\n}\n\n/** Evaluate every enabled item (ANY matching unlock earns it); disabled items are omitted. */\nexport function evaluateRpgUnlocks(\n signals: RpgUnlockSignals,\n items: readonly RpgItem[] = RPG_ITEMS,\n): RpgUnlockResult[] {\n return items\n .filter((item) => item.enabled)\n .map((item) => ({ item, earned: item.unlock.some((u) => matches(u, signals)) }));\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@singi-labs/sifa-sdk",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.38",
|
|
4
4
|
"description": "Sifa SDK — public client library for the Sifa AppView on AT Protocol. Shared by sifa-web and sifa-app.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -172,6 +172,16 @@
|
|
|
172
172
|
"default": "./dist/jev/index.cjs"
|
|
173
173
|
}
|
|
174
174
|
},
|
|
175
|
+
"./rpg": {
|
|
176
|
+
"import": {
|
|
177
|
+
"types": "./dist/rpg/index.d.ts",
|
|
178
|
+
"default": "./dist/rpg/index.js"
|
|
179
|
+
},
|
|
180
|
+
"require": {
|
|
181
|
+
"types": "./dist/rpg/index.d.cts",
|
|
182
|
+
"default": "./dist/rpg/index.cjs"
|
|
183
|
+
}
|
|
184
|
+
},
|
|
175
185
|
"./package.json": "./package.json"
|
|
176
186
|
},
|
|
177
187
|
"main": "./dist/index.cjs",
|