@indorania/contracts 0.1.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.
- package/README.md +117 -0
- package/dist/common.d.ts +144 -0
- package/dist/common.d.ts.map +1 -0
- package/dist/common.js +162 -0
- package/dist/common.js.map +1 -0
- package/dist/constitution/index.d.ts +9 -0
- package/dist/constitution/index.d.ts.map +1 -0
- package/dist/constitution/index.js +9 -0
- package/dist/constitution/index.js.map +1 -0
- package/dist/constitution/openapi.d.ts +23 -0
- package/dist/constitution/openapi.d.ts.map +1 -0
- package/dist/constitution/openapi.js +375 -0
- package/dist/constitution/openapi.js.map +1 -0
- package/dist/constitution/report.d.ts +63 -0
- package/dist/constitution/report.d.ts.map +1 -0
- package/dist/constitution/report.js +73 -0
- package/dist/constitution/report.js.map +1 -0
- package/dist/constitution/tables.d.ts +53 -0
- package/dist/constitution/tables.d.ts.map +1 -0
- package/dist/constitution/tables.js +96 -0
- package/dist/constitution/tables.js.map +1 -0
- package/dist/constitution/words.d.ts +39 -0
- package/dist/constitution/words.d.ts.map +1 -0
- package/dist/constitution/words.js +126 -0
- package/dist/constitution/words.js.map +1 -0
- package/dist/document.d.ts +12 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +106 -0
- package/dist/document.js.map +1 -0
- package/dist/domain-error.d.ts +14 -0
- package/dist/domain-error.d.ts.map +1 -0
- package/dist/domain-error.js +23 -0
- package/dist/domain-error.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/op.d.ts +92 -0
- package/dist/op.d.ts.map +1 -0
- package/dist/op.js +113 -0
- package/dist/op.js.map +1 -0
- package/dist/routes/asks.d.ts +77 -0
- package/dist/routes/asks.d.ts.map +1 -0
- package/dist/routes/asks.js +182 -0
- package/dist/routes/asks.js.map +1 -0
- package/dist/routes/backup.d.ts +12 -0
- package/dist/routes/backup.d.ts.map +1 -0
- package/dist/routes/backup.js +63 -0
- package/dist/routes/backup.js.map +1 -0
- package/dist/routes/capabilities.d.ts +67 -0
- package/dist/routes/capabilities.d.ts.map +1 -0
- package/dist/routes/capabilities.js +88 -0
- package/dist/routes/capabilities.js.map +1 -0
- package/dist/routes/entitlements.d.ts +137 -0
- package/dist/routes/entitlements.d.ts.map +1 -0
- package/dist/routes/entitlements.js +101 -0
- package/dist/routes/entitlements.js.map +1 -0
- package/dist/routes/guest.d.ts +57 -0
- package/dist/routes/guest.d.ts.map +1 -0
- package/dist/routes/guest.js +140 -0
- package/dist/routes/guest.js.map +1 -0
- package/dist/routes/integration.d.ts +187 -0
- package/dist/routes/integration.d.ts.map +1 -0
- package/dist/routes/integration.js +243 -0
- package/dist/routes/integration.js.map +1 -0
- package/dist/routes/meta.d.ts +50 -0
- package/dist/routes/meta.d.ts.map +1 -0
- package/dist/routes/meta.js +90 -0
- package/dist/routes/meta.js.map +1 -0
- package/dist/routes/organisations.d.ts +121 -0
- package/dist/routes/organisations.d.ts.map +1 -0
- package/dist/routes/organisations.js +175 -0
- package/dist/routes/organisations.js.map +1 -0
- package/dist/routes/presentations.d.ts +95 -0
- package/dist/routes/presentations.d.ts.map +1 -0
- package/dist/routes/presentations.js +121 -0
- package/dist/routes/presentations.js.map +1 -0
- package/dist/routes/sessions.d.ts +180 -0
- package/dist/routes/sessions.d.ts.map +1 -0
- package/dist/routes/sessions.js +240 -0
- package/dist/routes/sessions.js.map +1 -0
- package/dist/routes/standing.d.ts +24 -0
- package/dist/routes/standing.d.ts.map +1 -0
- package/dist/routes/standing.js +74 -0
- package/dist/routes/standing.js.map +1 -0
- package/dist/routes/thank-yous.d.ts +30 -0
- package/dist/routes/thank-yous.d.ts.map +1 -0
- package/dist/routes/thank-yous.js +139 -0
- package/dist/routes/thank-yous.js.map +1 -0
- package/dist/versions.d.ts +46 -0
- package/dist/versions.d.ts.map +1 -0
- package/dist/versions.js +54 -0
- package/dist/versions.js.map +1 -0
- package/dist/webhooks.d.ts +55 -0
- package/dist/webhooks.d.ts.map +1 -0
- package/dist/webhooks.js +76 -0
- package/dist/webhooks.js.map +1 -0
- package/dist/zod.d.ts +3 -0
- package/dist/zod.d.ts.map +1 -0
- package/dist/zod.js +7 -0
- package/dist/zod.js.map +1 -0
- package/node/kernel-esm.mjs +27 -0
- package/node/register.mjs +5 -0
- package/openapi/2026-09-25.json +6959 -0
- package/openapi/versions.json +10 -0
- package/package.json +49 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The constitution, checked against a database schema — described as plain data, so it works for
|
|
3
|
+
* any ORM. `@indorania/db` builds this model from its Drizzle tables; a member can build one from
|
|
4
|
+
* its own.
|
|
5
|
+
*/
|
|
6
|
+
import { RULES, summarise } from "./report.js";
|
|
7
|
+
import { DECLINE_TOKENS, MEMBER_NAMES, MEMBERSHIP_TOKENS, METER_TOKENS, ORIGIN_TOKENS, PERSON_TOKENS, SCORE_TOKENS, SECRET_TOKENS, hasToken, } from "./words.js";
|
|
8
|
+
/** A person-side column would be one of these; the platform has none (d41, ADR-0001). */
|
|
9
|
+
const PERSON_COLUMN_TOKENS = new Set([...PERSON_TOKENS, "relationship", "relationships"]);
|
|
10
|
+
export const EXPIRY_COLUMN = "expires_at";
|
|
11
|
+
export function checkTables(model) {
|
|
12
|
+
const findings = [];
|
|
13
|
+
const add = (rule, where, why) => findings.push({ rule, where, why });
|
|
14
|
+
const classes = new Map(model.jsonColumns.map((c) => [c.column, c]));
|
|
15
|
+
for (const table of model.tables) {
|
|
16
|
+
const t = `${table.schema}.${table.name}`;
|
|
17
|
+
const structural = [
|
|
18
|
+
{ name: table.schema, where: t, kind: "schema" },
|
|
19
|
+
{ name: table.name, where: t, kind: "table" },
|
|
20
|
+
...table.columns.map((c) => ({ name: c.name, where: `${t}.${c.name}`, kind: "column" })),
|
|
21
|
+
...table.columns.flatMap((c) => (c.enumValues ?? []).map((v) => ({ name: v, where: `${t}.${c.name}`, kind: "enum value" }))),
|
|
22
|
+
];
|
|
23
|
+
for (const s of structural) {
|
|
24
|
+
const origin = hasToken(s.name, ORIGIN_TOKENS);
|
|
25
|
+
if (origin)
|
|
26
|
+
add("no-origin-fields", s.where, `${s.kind} "${s.name}" names ${origin}`);
|
|
27
|
+
const decline = hasToken(s.name, DECLINE_TOKENS);
|
|
28
|
+
if (decline)
|
|
29
|
+
add("no-decline-trace", s.where, `${s.kind} "${s.name}" names ${decline}`);
|
|
30
|
+
const member = hasToken(s.name, MEMBER_NAMES);
|
|
31
|
+
if (member)
|
|
32
|
+
add("no-member-names", s.where, `${s.kind} "${s.name}" names a member (${member})`);
|
|
33
|
+
}
|
|
34
|
+
const tableMembership = hasToken(table.name, MEMBERSHIP_TOKENS);
|
|
35
|
+
if (tableMembership)
|
|
36
|
+
add("no-house-member-list", t, `table "${table.name}" names ${tableMembership}`);
|
|
37
|
+
for (const c of table.columns) {
|
|
38
|
+
const where = `${t}.${c.name}`;
|
|
39
|
+
const person = hasToken(c.name, PERSON_COLUMN_TOKENS);
|
|
40
|
+
if (person)
|
|
41
|
+
add("no-cross-relationship-joins", where, `column "${c.name}" would hold a person-side identifier (${person}); the platform stores none`);
|
|
42
|
+
const membership = hasToken(c.name, MEMBERSHIP_TOKENS);
|
|
43
|
+
if (membership)
|
|
44
|
+
add("no-house-member-list", where, `column "${c.name}" names ${membership}`);
|
|
45
|
+
const score = hasToken(c.name, SCORE_TOKENS);
|
|
46
|
+
if (score)
|
|
47
|
+
add("no-score-or-balance", where, `column "${c.name}" names ${score}`);
|
|
48
|
+
const secret = hasToken(c.name, SECRET_TOKENS);
|
|
49
|
+
if (secret)
|
|
50
|
+
add("no-secret-material", where, `column "${c.name}" names ${secret}`);
|
|
51
|
+
if (table.schema === "entitlements") {
|
|
52
|
+
const meter = hasToken(c.name, METER_TOKENS);
|
|
53
|
+
if (meter)
|
|
54
|
+
add("no-volume-meter", where, `entitlement column "${c.name}" meters ${meter}`);
|
|
55
|
+
}
|
|
56
|
+
if (c.sqlType === "json" || c.sqlType === "jsonb") {
|
|
57
|
+
const cls = classes.get(where);
|
|
58
|
+
if (!cls) {
|
|
59
|
+
add("no-cross-relationship-joins", where, `json column "${c.name}" does not say whether it holds party content`);
|
|
60
|
+
}
|
|
61
|
+
else if (cls.holds === "party-content") {
|
|
62
|
+
const expiry = table.columns.find((x) => x.name === EXPIRY_COLUMN);
|
|
63
|
+
if (!expiry?.notNull)
|
|
64
|
+
add("no-cross-relationship-joins", where, `party content in ${t}, which has no non-null ${EXPIRY_COLUMN}: it would be kept`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
for (const fk of table.foreignKeys) {
|
|
69
|
+
if (fk.foreignSchema !== table.schema) {
|
|
70
|
+
add("no-cross-relationship-joins", `${t}(${fk.columns.join(", ")})`, `a foreign key into ${fk.foreignSchema}.${fk.foreignTable} crosses a schema (architecture §4.3 rules 5–6)`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const known = new Set(model.tables.flatMap((t) => t.columns.map((c) => `${t.schema}.${t.name}.${c.name}`)));
|
|
75
|
+
for (const c of model.jsonColumns) {
|
|
76
|
+
if (!known.has(c.column))
|
|
77
|
+
add("no-cross-relationship-joins", c.column, "classified json column does not exist");
|
|
78
|
+
}
|
|
79
|
+
// Reviewed exceptions: matched by rule and column. One that matches nothing is itself a failure.
|
|
80
|
+
const accepted = model.accepted ?? [];
|
|
81
|
+
const used = new Set();
|
|
82
|
+
const kept = findings.filter((f) => {
|
|
83
|
+
const hit = accepted.find((a) => a.rule === f.rule && a.column === f.where);
|
|
84
|
+
if (hit)
|
|
85
|
+
used.add(hit);
|
|
86
|
+
return hit === undefined;
|
|
87
|
+
});
|
|
88
|
+
for (const a of accepted) {
|
|
89
|
+
if (!used.has(a))
|
|
90
|
+
kept.push({ rule: a.rule, where: a.column, why: "an accepted exception that no longer matches any finding — remove it" });
|
|
91
|
+
}
|
|
92
|
+
const acceptedFindings = [...used].map((a) => ({ rule: a.rule, where: a.column, why: "accepted", reason: a.reason }));
|
|
93
|
+
// Every rule applies to a schema except the list allowlist, which is about reads.
|
|
94
|
+
return summarise(kept, Object.keys(RULES).filter((id) => id !== "collections-allowlisted"), acceptedFindings);
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/constitution/tables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words the constitution forbids in structure — the names of paths, operations, parameters,
|
|
3
|
+
* properties, enum values, schemas, tables and columns. Text (descriptions) is not checked here.
|
|
4
|
+
*
|
|
5
|
+
* Names are compared token by token, after splitting camelCase, snake_case, kebab-case, dots,
|
|
6
|
+
* slashes and braces — so "sectionId" is [section, id] and never matches "sect", and "trace" is
|
|
7
|
+
* never "race". Each list spells its forms out; nothing is matched by prefix.
|
|
8
|
+
*/
|
|
9
|
+
/** Split a name into lower-case tokens. */
|
|
10
|
+
export declare function tokens(name: string): string[];
|
|
11
|
+
export declare function hasToken(name: string, set: ReadonlySet<string>): string | null;
|
|
12
|
+
/** ECOSYSTEM d36 and Indorania content rule 2: no origin, ethnicity, sect, caste or descent field anywhere. */
|
|
13
|
+
export declare const ORIGIN_TOKENS: ReadonlySet<string>;
|
|
14
|
+
/** A field named for a person must be a RelationshipId — never a free-standing identifier (d41, d47(g)). */
|
|
15
|
+
export declare const PERSON_TOKENS: ReadonlySet<string>;
|
|
16
|
+
/** d47(c): membership of a house is a credential in the person's wallet, never a list the platform holds. */
|
|
17
|
+
export declare const MEMBERSHIP_TOKENS: ReadonlySet<string>;
|
|
18
|
+
/** PL-4 edge 7: no client needs to know a member's name — members appear as capabilities. */
|
|
19
|
+
export declare const MEMBER_NAMES: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* d49(a): a decline leaves no trace — no endpoint, state or field for it. "declining" is absent on
|
|
22
|
+
* purpose: it is the ask's own statement that declining costs only what `goodFor` names (d42 §5).
|
|
23
|
+
*/
|
|
24
|
+
export declare const DECLINE_TOKENS: ReadonlySet<string>;
|
|
25
|
+
/** d27, d43, d49: nothing scores, ranks or totals a person; thank-yous never add up. */
|
|
26
|
+
export declare const SCORE_TOKENS: ReadonlySet<string>;
|
|
27
|
+
/** d47(g): no person's private key on a server. No field carries secret key material. */
|
|
28
|
+
export declare const SECRET_TOKENS: ReadonlySet<string>;
|
|
29
|
+
/** d50(b)1: capacity is what costs work; volume is never capacity. Checked on entitlements only. */
|
|
30
|
+
export declare const METER_TOKENS: ReadonlySet<string>;
|
|
31
|
+
/**
|
|
32
|
+
* For values people write (a house's join rule): the door opens on place, craft or goal, never on
|
|
33
|
+
* birth or descent (d27, d36, d47(c)). A floor, not a filter — human review sits above it (PL-7).
|
|
34
|
+
* Word-bounded, so "original" and "insect" pass.
|
|
35
|
+
*/
|
|
36
|
+
export declare const BIRTH_OR_ORIGIN: RegExp;
|
|
37
|
+
/** For labels an integration writes: a section is named by what it does, never by who powers it. */
|
|
38
|
+
export declare const MEMBER_NAME_PATTERN: RegExp;
|
|
39
|
+
//# sourceMappingURL=words.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.d.ts","sourceRoot":"","sources":["../../src/constitution/words.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,2CAA2C;AAC3C,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAO7C;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,IAAI,CAG9E;AAED,+GAA+G;AAC/G,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAe5C,CAAC;AAEH,4GAA4G;AAC5G,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAiB5C,CAAC;AAEH,6GAA6G;AAC7G,eAAO,MAAM,iBAAiB,EAAE,WAAW,CAAC,MAAM,CAOhD,CAAC;AAEH,6FAA6F;AAC7F,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAI3C,CAAC;AAEH;;;GAGG;AACH,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAI7C,CAAC;AAEH,wFAAwF;AACxF,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAS3C,CAAC;AAEH,yFAAyF;AACzF,eAAO,MAAM,aAAa,EAAE,WAAW,CAAC,MAAM,CAE5C,CAAC;AAEH,oGAAoG;AACpG,eAAO,MAAM,YAAY,EAAE,WAAW,CAAC,MAAM,CAiB3C,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,eAAe,QACyM,CAAC;AAEtO,oGAAoG;AACpG,eAAO,MAAM,mBAAmB,QAAmG,CAAC"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The words the constitution forbids in structure — the names of paths, operations, parameters,
|
|
3
|
+
* properties, enum values, schemas, tables and columns. Text (descriptions) is not checked here.
|
|
4
|
+
*
|
|
5
|
+
* Names are compared token by token, after splitting camelCase, snake_case, kebab-case, dots,
|
|
6
|
+
* slashes and braces — so "sectionId" is [section, id] and never matches "sect", and "trace" is
|
|
7
|
+
* never "race". Each list spells its forms out; nothing is matched by prefix.
|
|
8
|
+
*/
|
|
9
|
+
/** Split a name into lower-case tokens. */
|
|
10
|
+
export function tokens(name) {
|
|
11
|
+
return name
|
|
12
|
+
.replace(/([a-z0-9])([A-Z])/g, "$1 $2")
|
|
13
|
+
.replace(/([A-Z]+)([A-Z][a-z])/g, "$1 $2")
|
|
14
|
+
.split(/[^A-Za-z0-9]+/)
|
|
15
|
+
.filter(Boolean)
|
|
16
|
+
.map((t) => t.toLowerCase());
|
|
17
|
+
}
|
|
18
|
+
export function hasToken(name, set) {
|
|
19
|
+
for (const t of tokens(name))
|
|
20
|
+
if (set.has(t))
|
|
21
|
+
return t;
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
/** ECOSYSTEM d36 and Indorania content rule 2: no origin, ethnicity, sect, caste or descent field anywhere. */
|
|
25
|
+
export const ORIGIN_TOKENS = new Set([
|
|
26
|
+
"origin", "origins",
|
|
27
|
+
"ethnic", "ethnicity", "ethnicities",
|
|
28
|
+
"race", "races", "racial",
|
|
29
|
+
"sect", "sects", "sectarian",
|
|
30
|
+
"caste", "castes",
|
|
31
|
+
"tribe", "tribes", "tribal",
|
|
32
|
+
"clan", "clans",
|
|
33
|
+
"lineage", "lineages",
|
|
34
|
+
"ancestry", "ancestries", "ancestral", "ancestor", "ancestors",
|
|
35
|
+
"descent",
|
|
36
|
+
"nationality", "nationalities",
|
|
37
|
+
"religion", "religions", "religious",
|
|
38
|
+
"birth", "births", "birthplace",
|
|
39
|
+
"endonym", "endonyms",
|
|
40
|
+
]);
|
|
41
|
+
/** A field named for a person must be a RelationshipId — never a free-standing identifier (d41, d47(g)). */
|
|
42
|
+
export const PERSON_TOKENS = new Set([
|
|
43
|
+
"person", "persons", "people",
|
|
44
|
+
"holder", "holders",
|
|
45
|
+
"wallet", "wallets",
|
|
46
|
+
"device", "devices",
|
|
47
|
+
"install", "installs", "installation",
|
|
48
|
+
"push",
|
|
49
|
+
"subject", "subjects",
|
|
50
|
+
"user", "users",
|
|
51
|
+
"individual", "individuals",
|
|
52
|
+
"citizen", "citizens",
|
|
53
|
+
"visitor", "visitors",
|
|
54
|
+
"customer", "customers",
|
|
55
|
+
"recipient", "recipients",
|
|
56
|
+
"beneficiary", "beneficiaries",
|
|
57
|
+
"worker", "workers",
|
|
58
|
+
"member", "members",
|
|
59
|
+
]);
|
|
60
|
+
/** d47(c): membership of a house is a credential in the person's wallet, never a list the platform holds. */
|
|
61
|
+
export const MEMBERSHIP_TOKENS = new Set([
|
|
62
|
+
"member", "members", "membership", "memberships",
|
|
63
|
+
"people", "persons",
|
|
64
|
+
"roster", "rosters",
|
|
65
|
+
"follower", "followers",
|
|
66
|
+
"joiner", "joiners",
|
|
67
|
+
"subscriber", "subscribers",
|
|
68
|
+
]);
|
|
69
|
+
/** PL-4 edge 7: no client needs to know a member's name — members appear as capabilities. */
|
|
70
|
+
export const MEMBER_NAMES = new Set([
|
|
71
|
+
"kashscript", "indusland", "duedale", "oreoasis",
|
|
72
|
+
"tehzeeb", "kumak", "industown",
|
|
73
|
+
"sabaat", "safeer", "suroor", "simt",
|
|
74
|
+
]);
|
|
75
|
+
/**
|
|
76
|
+
* d49(a): a decline leaves no trace — no endpoint, state or field for it. "declining" is absent on
|
|
77
|
+
* purpose: it is the ask's own statement that declining costs only what `goodFor` names (d42 §5).
|
|
78
|
+
*/
|
|
79
|
+
export const DECLINE_TOKENS = new Set([
|
|
80
|
+
"decline", "declines", "declined", "declination",
|
|
81
|
+
"refuse", "refuses", "refused", "refusal", "refusals", "refuser", "refusers",
|
|
82
|
+
"optout", "opted",
|
|
83
|
+
]);
|
|
84
|
+
/** d27, d43, d49: nothing scores, ranks or totals a person; thank-yous never add up. */
|
|
85
|
+
export const SCORE_TOKENS = new Set([
|
|
86
|
+
"score", "scores", "scoring",
|
|
87
|
+
"rank", "ranks", "ranking", "rankings",
|
|
88
|
+
"percent", "percentage", "percentages", "percentile", "percentiles",
|
|
89
|
+
"balance", "balances",
|
|
90
|
+
"points",
|
|
91
|
+
"leaderboard", "leaderboards",
|
|
92
|
+
"rating", "ratings",
|
|
93
|
+
"tier", "tiers",
|
|
94
|
+
]);
|
|
95
|
+
/** d47(g): no person's private key on a server. No field carries secret key material. */
|
|
96
|
+
export const SECRET_TOKENS = new Set([
|
|
97
|
+
"private", "secret", "secrets", "seed", "seeds", "mnemonic", "mnemonics", "passphrase", "password", "passwords",
|
|
98
|
+
]);
|
|
99
|
+
/** d50(b)1: capacity is what costs work; volume is never capacity. Checked on entitlements only. */
|
|
100
|
+
export const METER_TOKENS = new Set([
|
|
101
|
+
"price", "prices", "pricing",
|
|
102
|
+
"amount", "amounts",
|
|
103
|
+
"cost", "costs",
|
|
104
|
+
"fee", "fees",
|
|
105
|
+
"charge", "charges",
|
|
106
|
+
"meter", "meters", "metered", "metering",
|
|
107
|
+
"usage",
|
|
108
|
+
"count", "counts",
|
|
109
|
+
"volume", "volumes",
|
|
110
|
+
"record", "records",
|
|
111
|
+
"confirmation", "confirmations",
|
|
112
|
+
"check", "checks",
|
|
113
|
+
"presentation", "presentations",
|
|
114
|
+
"session", "sessions",
|
|
115
|
+
"answer", "answers",
|
|
116
|
+
"thank",
|
|
117
|
+
]);
|
|
118
|
+
/**
|
|
119
|
+
* For values people write (a house's join rule): the door opens on place, craft or goal, never on
|
|
120
|
+
* birth or descent (d27, d36, d47(c)). A floor, not a filter — human review sits above it (PL-7).
|
|
121
|
+
* Word-bounded, so "original" and "insect" pass.
|
|
122
|
+
*/
|
|
123
|
+
export const BIRTH_OR_ORIGIN = /\b(born|births?|birthplace|descent|descend(?:s|ed|ants?)?|lineages?|ancestr(?:y|ies|al)|ancestors?|bloodlines?|ethnic(?:ity|ities)?|races?|racial|sects?|sectarian|castes?|tribes?|tribal|clans?|origins?|nationalit(?:y|ies))\b/i;
|
|
124
|
+
/** For labels an integration writes: a section is named by what it does, never by who powers it. */
|
|
125
|
+
export const MEMBER_NAME_PATTERN = /\b(kashscript|indusland|duedale|oreoasis|tehzeeb|kumak|industown|sabaat|safeer|suroor|simt)\b/i;
|
|
126
|
+
//# sourceMappingURL=words.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.js","sourceRoot":"","sources":["../../src/constitution/words.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/** Every operation and webhook of the contract, and the OpenAPI 3.1 document generated from them. */
|
|
2
|
+
import { OpenApiGeneratorV31 } from "@asteasolutions/zod-to-openapi";
|
|
3
|
+
import { type Operation } from "./op.ts";
|
|
4
|
+
import { type ApiVersion } from "./versions.ts";
|
|
5
|
+
/** Every operation this API serves. apps/api registers exactly these, and nothing else. */
|
|
6
|
+
export declare const OPERATIONS: readonly Operation[];
|
|
7
|
+
/** What the platform sends to integrations. */
|
|
8
|
+
export declare const WEBHOOKS: readonly Operation[];
|
|
9
|
+
/** An OpenAPI 3.1 document, as the generator types it. */
|
|
10
|
+
export type GeneratedDocument = ReturnType<OpenApiGeneratorV31["generateDocument"]>;
|
|
11
|
+
export declare function generateDocument(version?: ApiVersion): GeneratedDocument;
|
|
12
|
+
//# sourceMappingURL=document.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.d.ts","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"AAAA,qGAAqG;AACrG,OAAO,EAAmB,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,SAAS,CAAC;AAa/C,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,eAAe,CAAC;AAE/D,2FAA2F;AAC3F,eAAO,MAAM,UAAU,EAAE,SAAS,SAAS,EAa1C,CAAC;AAEF,+CAA+C;AAC/C,eAAO,MAAM,QAAQ,EAAE,SAAS,SAAS,EAAwB,CAAC;AA2DlE,0DAA0D;AAC1D,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAEpF,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,UAA4B,GAAG,iBAAiB,CAgBzF"}
|
package/dist/document.js
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/** Every operation and webhook of the contract, and the OpenAPI 3.1 document generated from them. */
|
|
2
|
+
import { OpenAPIRegistry, OpenApiGeneratorV31 } from "@asteasolutions/zod-to-openapi";
|
|
3
|
+
import { TAGS } from "./op.js";
|
|
4
|
+
import { askOperations } from "./routes/asks.js";
|
|
5
|
+
import { backupOperations } from "./routes/backup.js";
|
|
6
|
+
import { capabilityOperations } from "./routes/capabilities.js";
|
|
7
|
+
import { entitlementOperations } from "./routes/entitlements.js";
|
|
8
|
+
import { guestOperations } from "./routes/guest.js";
|
|
9
|
+
import { integrationOperations, integrationWebhooks } from "./routes/integration.js";
|
|
10
|
+
import { metaOperations } from "./routes/meta.js";
|
|
11
|
+
import { organisationOperations } from "./routes/organisations.js";
|
|
12
|
+
import { presentationOperations } from "./routes/presentations.js";
|
|
13
|
+
import { sessionOperations } from "./routes/sessions.js";
|
|
14
|
+
import { standingOperations } from "./routes/standing.js";
|
|
15
|
+
import { thankYouOperations } from "./routes/thank-yous.js";
|
|
16
|
+
import { latestVersion } from "./versions.js";
|
|
17
|
+
/** Every operation this API serves. apps/api registers exactly these, and nothing else. */
|
|
18
|
+
export const OPERATIONS = [
|
|
19
|
+
...metaOperations,
|
|
20
|
+
...backupOperations,
|
|
21
|
+
...organisationOperations,
|
|
22
|
+
...guestOperations,
|
|
23
|
+
...capabilityOperations,
|
|
24
|
+
...entitlementOperations,
|
|
25
|
+
...askOperations,
|
|
26
|
+
...presentationOperations,
|
|
27
|
+
...standingOperations,
|
|
28
|
+
...sessionOperations,
|
|
29
|
+
...thankYouOperations,
|
|
30
|
+
...integrationOperations,
|
|
31
|
+
];
|
|
32
|
+
/** What the platform sends to integrations. */
|
|
33
|
+
export const WEBHOOKS = integrationWebhooks;
|
|
34
|
+
const SECURITY_SCHEMES = {
|
|
35
|
+
seat: {
|
|
36
|
+
type: "http",
|
|
37
|
+
scheme: "bearer",
|
|
38
|
+
bearerFormat: "JWT",
|
|
39
|
+
description: "A staff login's access token, from the platform's OIDC boundary (PL-7). It acts through the seats its login holds.",
|
|
40
|
+
},
|
|
41
|
+
integration: {
|
|
42
|
+
type: "http",
|
|
43
|
+
scheme: "bearer",
|
|
44
|
+
bearerFormat: "JWT",
|
|
45
|
+
description: "An integration's access token: the client-credentials grant, authenticated with a private_key_jwt assertion (RFC 7523) signed by one of its registered Ed25519 keys (PL-7).",
|
|
46
|
+
},
|
|
47
|
+
personAccount: {
|
|
48
|
+
type: "http",
|
|
49
|
+
scheme: "bearer",
|
|
50
|
+
bearerFormat: "JWT",
|
|
51
|
+
description: "A person's optional account, signed in with a passkey. It reaches /v1/backup and nothing else (ADR-0001). People need no account for anything else.",
|
|
52
|
+
},
|
|
53
|
+
relationshipProof: {
|
|
54
|
+
type: "apiKey",
|
|
55
|
+
in: "header",
|
|
56
|
+
name: "DPoP",
|
|
57
|
+
description: "A DPoP proof JWT (RFC 9449) signed by the person's relationship key, over this method and URL. It proves which party is calling without any account; its key is the person's identifier in that relationship only.",
|
|
58
|
+
},
|
|
59
|
+
webhookSignature: {
|
|
60
|
+
type: "apiKey",
|
|
61
|
+
in: "header",
|
|
62
|
+
name: "webhook-signature",
|
|
63
|
+
description: "Standard Webhooks 1.0.0, v1a (Ed25519) over webhook-id.webhook-timestamp.body. The platform signs with the keys at /v1/webhook-keys; an integration signs with a key it registered.",
|
|
64
|
+
},
|
|
65
|
+
issuanceToken: {
|
|
66
|
+
type: "http",
|
|
67
|
+
scheme: "bearer",
|
|
68
|
+
description: "The access token /v1/issuance/token returned for a pre-authorized code (OpenID4VCI 1.0).",
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
const DESCRIPTION = `The platform contract that every member, and any outside issuer, builds against (ECOSYSTEM decision 47). A member integrates exactly as a stranger would.
|
|
72
|
+
|
|
73
|
+
**Versions.** The URL carries the major version (\`/v1\`). Every request speaks a dated version: send \`Indorania-Version: YYYY-MM-DD\`, or your organisation's or integration's pinned version applies; with neither, the request is refused. Inside a released version, changes are additive only — new operations, new optional fields, new enum values, new problem codes — so treat anything unknown gracefully. Any other change is a new dated version, and the platform translates between the two. A version is a **preview** until its first release, and may still change in place.
|
|
74
|
+
|
|
75
|
+
**Exempt from dated versions:** the OpenID4VCI and OpenID4VP endpoints, which their standards version, and documents that describe themselves: the trust list, the webhook keys, the version list, and these documents.
|
|
76
|
+
|
|
77
|
+
**Errors** are RFC 9457 problem details (\`application/problem+json\`), each with a stable \`code\`.
|
|
78
|
+
|
|
79
|
+
**Idempotency.** Every change made through this API carries an \`Idempotency-Key\` (IETF draft-07). Without one it is refused (400). The same key and body get the first answer again for 24 hours; the same key with another body is refused (422); a key still running is refused (409). Protocol endpoints rely on their own single-use code or nonce, and webhooks on \`webhook-id\`.
|
|
80
|
+
|
|
81
|
+
**Webhooks,** in both directions: Standard Webhooks 1.0.0, v1a (Ed25519), with a 300-second tolerance.
|
|
82
|
+
|
|
83
|
+
**What it never does.** No endpoint lists a house's members, answers "everything matching X", records a decline, meters records, scores a person, or joins a person across relationships: person-side identifiers are relationship identifiers, one at a time. Lints check this document for all of it.
|
|
84
|
+
|
|
85
|
+
**Status.** Every operation marked \`x-indorania-pending\` is wired but not built, and answers 501 \`not_built\`. No host serves this API yet, and nothing it serves reaches real society before ECOSYSTEM decision 30's gate.`;
|
|
86
|
+
export function generateDocument(version = latestVersion()) {
|
|
87
|
+
const registry = new OpenAPIRegistry();
|
|
88
|
+
for (const [name, scheme] of Object.entries(SECURITY_SCHEMES))
|
|
89
|
+
registry.registerComponent("securitySchemes", name, scheme);
|
|
90
|
+
for (const op of OPERATIONS)
|
|
91
|
+
registry.registerPath(op.route);
|
|
92
|
+
for (const op of WEBHOOKS)
|
|
93
|
+
registry.registerWebhook(op.route);
|
|
94
|
+
return new OpenApiGeneratorV31(registry.definitions).generateDocument({
|
|
95
|
+
openapi: "3.1.0",
|
|
96
|
+
info: {
|
|
97
|
+
title: "Indorania platform API",
|
|
98
|
+
version: version.id,
|
|
99
|
+
description: DESCRIPTION,
|
|
100
|
+
license: { name: "Apache-2.0", identifier: "Apache-2.0" },
|
|
101
|
+
"x-indorania-version-status": version.status,
|
|
102
|
+
},
|
|
103
|
+
tags: Object.entries(TAGS).map(([name, description]) => ({ name, description })),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
//# sourceMappingURL=document.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"document.js","sourceRoot":"","sources":["../src/document.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a platform implementation throws when a request is refused for a reason the contract names.
|
|
3
|
+
* The API turns it into the one error envelope (RFC 9457 plus `code`); nothing else in the platform
|
|
4
|
+
* knows about HTTP. The codes are the contract's own, so a refusal can only be one the document lists.
|
|
5
|
+
*/
|
|
6
|
+
import { type ProblemCode, type ProblemDetail } from "./common.ts";
|
|
7
|
+
export declare class DomainError extends Error {
|
|
8
|
+
readonly code: ProblemCode;
|
|
9
|
+
readonly errors: readonly ProblemDetail[];
|
|
10
|
+
constructor(code: ProblemCode, detail: string, errors?: readonly ProblemDetail[]);
|
|
11
|
+
get status(): number;
|
|
12
|
+
}
|
|
13
|
+
export declare const refuse: (code: ProblemCode, detail: string, errors?: readonly ProblemDetail[]) => never;
|
|
14
|
+
//# sourceMappingURL=domain-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-error.d.ts","sourceRoot":"","sources":["../src/domain-error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAY,KAAK,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAE7E,qBAAa,WAAY,SAAQ,KAAK;IACpC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;gBAE9B,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAE,SAAS,aAAa,EAAO;IAOpF,IAAI,MAAM,IAAI,MAAM,CAEnB;CACF;AAED,eAAO,MAAM,MAAM,GAAI,MAAM,WAAW,EAAE,QAAQ,MAAM,EAAE,SAAQ,SAAS,aAAa,EAAO,KAAG,KAEjG,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What a platform implementation throws when a request is refused for a reason the contract names.
|
|
3
|
+
* The API turns it into the one error envelope (RFC 9457 plus `code`); nothing else in the platform
|
|
4
|
+
* knows about HTTP. The codes are the contract's own, so a refusal can only be one the document lists.
|
|
5
|
+
*/
|
|
6
|
+
import { PROBLEMS } from "./common.js";
|
|
7
|
+
export class DomainError extends Error {
|
|
8
|
+
code;
|
|
9
|
+
errors;
|
|
10
|
+
constructor(code, detail, errors = []) {
|
|
11
|
+
super(detail);
|
|
12
|
+
this.name = "DomainError";
|
|
13
|
+
this.code = code;
|
|
14
|
+
this.errors = errors;
|
|
15
|
+
}
|
|
16
|
+
get status() {
|
|
17
|
+
return PROBLEMS[this.code].status;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export const refuse = (code, detail, errors = []) => {
|
|
21
|
+
throw new DomainError(code, detail, errors);
|
|
22
|
+
};
|
|
23
|
+
//# sourceMappingURL=domain-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-error.js","sourceRoot":"","sources":["../src/domain-error.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,OAAO,EAAE,QAAQ,EAAwC,MAAM,aAAa,CAAC;AAE7E,MAAM,OAAO,WAAY,SAAQ,KAAK;IAC3B,IAAI,CAAc;IAClB,MAAM,CAA2B;IAE1C,YAAY,IAAiB,EAAE,MAAc,EAAE,SAAmC,EAAE;QAClF,KAAK,CAAC,MAAM,CAAC,CAAC;QACd,IAAI,CAAC,IAAI,GAAG,aAAa,CAAC;QAC1B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,IAAI,MAAM;QACR,OAAO,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACpC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,IAAiB,EAAE,MAAc,EAAE,SAAmC,EAAE,EAAS,EAAE;IACxG,MAAM,IAAI,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAC9C,CAAC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@indorania/contracts` — the platform contract (ECOSYSTEM decision 47; PLATFORM-SESSIONS PL-4).
|
|
3
|
+
* Zod schemas are the source; the OpenAPI 3.1 document in `openapi/` is generated from them and
|
|
4
|
+
* committed. Also: `@indorania/contracts/constitution` (the lints) and `/webhooks` (signing).
|
|
5
|
+
*/
|
|
6
|
+
export * from "./common.ts";
|
|
7
|
+
export * from "./domain-error.ts";
|
|
8
|
+
export * from "./versions.ts";
|
|
9
|
+
export { IdempotencyKeyHeader, TAGS, VersionHeader, WebhookHeaders, operation, type Idempotency, type Method, type Operation, type OperationMeta, type OperationSpec, type Pending, type Scheme, type Tag, } from "./op.ts";
|
|
10
|
+
export { OPERATIONS, WEBHOOKS, generateDocument, type GeneratedDocument } from "./document.ts";
|
|
11
|
+
export * from "./routes/meta.ts";
|
|
12
|
+
export * from "./routes/backup.ts";
|
|
13
|
+
export * from "./routes/organisations.ts";
|
|
14
|
+
export * from "./routes/guest.ts";
|
|
15
|
+
export * from "./routes/capabilities.ts";
|
|
16
|
+
export * from "./routes/entitlements.ts";
|
|
17
|
+
export * from "./routes/asks.ts";
|
|
18
|
+
export * from "./routes/presentations.ts";
|
|
19
|
+
export * from "./routes/standing.ts";
|
|
20
|
+
export * from "./routes/sessions.ts";
|
|
21
|
+
export * from "./routes/thank-yous.ts";
|
|
22
|
+
export * from "./routes/integration.ts";
|
|
23
|
+
export { BIRTH_OR_ORIGIN } from "./constitution/words.ts";
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,IAAI,EACJ,aAAa,EACb,cAAc,EACd,SAAS,EACT,KAAK,WAAW,EAChB,KAAK,MAAM,EACX,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,OAAO,EACZ,KAAK,MAAM,EACX,KAAK,GAAG,GACT,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC/F,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@indorania/contracts` — the platform contract (ECOSYSTEM decision 47; PLATFORM-SESSIONS PL-4).
|
|
3
|
+
* Zod schemas are the source; the OpenAPI 3.1 document in `openapi/` is generated from them and
|
|
4
|
+
* committed. Also: `@indorania/contracts/constitution` (the lints) and `/webhooks` (signing).
|
|
5
|
+
*/
|
|
6
|
+
export * from "./common.js";
|
|
7
|
+
export * from "./domain-error.js";
|
|
8
|
+
export * from "./versions.js";
|
|
9
|
+
export { IdempotencyKeyHeader, TAGS, VersionHeader, WebhookHeaders, operation, } from "./op.js";
|
|
10
|
+
export { OPERATIONS, WEBHOOKS, generateDocument } from "./document.js";
|
|
11
|
+
export * from "./routes/meta.js";
|
|
12
|
+
export * from "./routes/backup.js";
|
|
13
|
+
export * from "./routes/organisations.js";
|
|
14
|
+
export * from "./routes/guest.js";
|
|
15
|
+
export * from "./routes/capabilities.js";
|
|
16
|
+
export * from "./routes/entitlements.js";
|
|
17
|
+
export * from "./routes/asks.js";
|
|
18
|
+
export * from "./routes/presentations.js";
|
|
19
|
+
export * from "./routes/standing.js";
|
|
20
|
+
export * from "./routes/sessions.js";
|
|
21
|
+
export * from "./routes/thank-yous.js";
|
|
22
|
+
export * from "./routes/integration.js";
|
|
23
|
+
export { BIRTH_OR_ORIGIN } from "./constitution/words.js";
|
|
24
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,cAAc,aAAa,CAAC;AAC5B,cAAc,mBAAmB,CAAC;AAClC,cAAc,eAAe,CAAC;AAC9B,OAAO,EACL,oBAAoB,EACpB,IAAI,EACJ,aAAa,EACb,cAAc,EACd,SAAS,GASV,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,gBAAgB,EAA0B,MAAM,eAAe,CAAC;AAC/F,cAAc,kBAAkB,CAAC;AACjC,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,mBAAmB,CAAC;AAClC,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/op.d.ts
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One builder for every operation, so the conventions live in one place:
|
|
3
|
+
* - the version header on every dated operation;
|
|
4
|
+
* - an Idempotency-Key on every mutation of this API, or the protocol's own single-use value, or
|
|
5
|
+
* the webhook's `webhook-id` — declared as `x-indorania-idempotency`;
|
|
6
|
+
* - the one error envelope as every operation's `default` response;
|
|
7
|
+
* - `x-indorania-pending` naming the session that builds the operation, while it answers 501;
|
|
8
|
+
* - `x-indorania-collection` on the few GETs allowed to return a list, with the reason.
|
|
9
|
+
*/
|
|
10
|
+
import type { RouteConfig } from "@asteasolutions/zod-to-openapi";
|
|
11
|
+
import { z } from "./zod.ts";
|
|
12
|
+
export declare const TAGS: {
|
|
13
|
+
readonly meta: "The contract describing itself: its dated versions, its OpenAPI documents, and the keys Indorania signs webhooks with.";
|
|
14
|
+
readonly trust: "The trust list: which issuers a wallet shows as listed (holder contract §3). A policy, never the format (ECOSYSTEM d47(e)).";
|
|
15
|
+
readonly backup: "A person's optional account holds one encrypted blob and nothing else (ADR-0001, d47(f)).";
|
|
16
|
+
readonly organisations: "Businesses, institutes and houses. A house is an organisation whose door opens on place, craft or goal — never on birth (d47(c)).";
|
|
17
|
+
readonly seats: "Staff logins and their roles in one organisation. For a house, its stewards — never its members, whom the platform never lists.";
|
|
18
|
+
readonly "guest-links": "A counterparty with no account countersigns through a link: one click, no install, no password (d26, d47(f)).";
|
|
19
|
+
readonly capabilities: "What an establishment does — visits, money in and out, work and jobs — and the portal sections integrations register for each (architecture §7.2, without brands).";
|
|
20
|
+
readonly entitlements: "Which capabilities an organisation runs, at which capacity. Granted by payment, sponsorship, trial or the simulation, and never read from billing (d50(f)).";
|
|
21
|
+
readonly asks: "The public ask library (d42 §5): requests for evidence, answered with a yes and never with the data.";
|
|
22
|
+
readonly presentations: "One presentation request per encounter, answered by a wallet over OpenID for Verifiable Presentations. A decline sends nothing and leaves no trace (d49(a)).";
|
|
23
|
+
readonly standing: "Standing is derived on request from presented predicates, signed and expiring; nothing that links is kept (d42 §2, d47(d)).";
|
|
24
|
+
readonly sessions: "One encounter, both signatures on every line. Indorania relays and anchors, and never signs as a party (d47(d)).";
|
|
25
|
+
readonly "thank-yous": "A counterparty's promise to a person who answered — never Indorania's, never a balance (d49(b)).";
|
|
26
|
+
readonly issuance: "OpenID for Verifiable Credential Issuance 1.0 endpoints for credentials the platform issues on an organisation's behalf, such as thank-yous. Standard, so exempt from dated versions.";
|
|
27
|
+
readonly integration: "How a member's or an outside issuer's system joins: its issuer, its predicate-answer and session-event webhooks, and its portal sections — the same contract for everyone (d47(a)).";
|
|
28
|
+
};
|
|
29
|
+
export type Tag = keyof typeof TAGS;
|
|
30
|
+
export type Scheme = "seat" | "integration" | "personAccount" | "relationshipProof" | "webhookSignature" | "issuanceToken";
|
|
31
|
+
export type Pending = "PL-7" | "PL-8" | null;
|
|
32
|
+
export type Idempotency = "key" | "protocol" | "webhook-id";
|
|
33
|
+
export type Method = "get" | "post" | "put" | "patch" | "delete";
|
|
34
|
+
type Media = "application/json" | "application/x-www-form-urlencoded";
|
|
35
|
+
export interface OperationSpec {
|
|
36
|
+
readonly operationId: string;
|
|
37
|
+
readonly method: Method;
|
|
38
|
+
readonly path: string;
|
|
39
|
+
readonly tag: Tag;
|
|
40
|
+
readonly summary: string;
|
|
41
|
+
readonly description?: string;
|
|
42
|
+
/** Alternatives: any one scheme suffices. Empty means public. */
|
|
43
|
+
readonly auth: readonly Scheme[];
|
|
44
|
+
/** The session that builds it; null once built. */
|
|
45
|
+
readonly pending: Pending;
|
|
46
|
+
/** Dated by default. Exempt only for standard protocols and self-describing documents. */
|
|
47
|
+
readonly versioning?: "dated" | "exempt";
|
|
48
|
+
/** Required on every mutation, absent on reads. */
|
|
49
|
+
readonly idempotency?: Idempotency;
|
|
50
|
+
/** Collection reads only: why listing here is allowed. */
|
|
51
|
+
readonly collection?: string;
|
|
52
|
+
readonly params?: z.ZodObject;
|
|
53
|
+
readonly query?: z.ZodObject;
|
|
54
|
+
readonly headers?: Readonly<Record<string, z.ZodType>>;
|
|
55
|
+
readonly body?: {
|
|
56
|
+
readonly schema: z.ZodType;
|
|
57
|
+
readonly type?: Media;
|
|
58
|
+
readonly description?: string;
|
|
59
|
+
};
|
|
60
|
+
readonly responses: Readonly<Record<number, {
|
|
61
|
+
readonly description: string;
|
|
62
|
+
readonly schema?: z.ZodType;
|
|
63
|
+
readonly type?: string;
|
|
64
|
+
}>>;
|
|
65
|
+
}
|
|
66
|
+
/** What apps/api reads back from a built operation. */
|
|
67
|
+
export interface OperationMeta {
|
|
68
|
+
readonly operationId: string;
|
|
69
|
+
readonly method: Method;
|
|
70
|
+
readonly path: string;
|
|
71
|
+
readonly pending: Pending;
|
|
72
|
+
readonly versioning: "dated" | "exempt";
|
|
73
|
+
readonly idempotency: Idempotency | null;
|
|
74
|
+
/** Alternatives: any one scheme suffices. Empty means public. */
|
|
75
|
+
readonly auth: readonly Scheme[];
|
|
76
|
+
}
|
|
77
|
+
/** The route as the generator and Hono take it, and what this contract says about it. */
|
|
78
|
+
export interface Operation {
|
|
79
|
+
readonly route: RouteConfig;
|
|
80
|
+
readonly meta: OperationMeta;
|
|
81
|
+
}
|
|
82
|
+
export declare const VersionHeader: z.ZodOptional<z.ZodString>;
|
|
83
|
+
/** IETF draft-ietf-httpapi-idempotency-key-header-07: a quoted Structured-Field string. The bare form is also accepted. */
|
|
84
|
+
export declare const IdempotencyKeyHeader: z.ZodString;
|
|
85
|
+
export declare const WebhookHeaders: {
|
|
86
|
+
readonly "webhook-id": z.ZodString;
|
|
87
|
+
readonly "webhook-timestamp": z.ZodString;
|
|
88
|
+
readonly "webhook-signature": z.ZodString;
|
|
89
|
+
};
|
|
90
|
+
export declare function operation(spec: OperationSpec): Operation;
|
|
91
|
+
export {};
|
|
92
|
+
//# sourceMappingURL=op.d.ts.map
|
package/dist/op.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"op.d.ts","sourceRoot":"","sources":["../src/op.ts"],"names":[],"mappings":"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"}
|