@civitai/app-sdk 0.46.0 → 0.48.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 +120 -33
- package/dist/blocks/appStorageLimits.d.ts +113 -0
- package/dist/blocks/appStorageLimits.d.ts.map +1 -0
- package/dist/blocks/appStorageLimits.js +113 -0
- package/dist/blocks/appStorageLimits.js.map +1 -0
- package/dist/blocks/index.d.ts +26 -7
- package/dist/blocks/index.d.ts.map +1 -1
- package/dist/blocks/index.js +25 -5
- package/dist/blocks/index.js.map +1 -1
- package/dist/blocks/manifestError.d.ts +20 -0
- package/dist/blocks/manifestError.d.ts.map +1 -0
- package/dist/blocks/manifestError.js +22 -0
- package/dist/blocks/manifestError.js.map +1 -0
- package/dist/blocks/messages.d.ts.map +1 -1
- package/dist/blocks/messages.js.map +1 -1
- package/dist/blocks/scopes.d.ts +7 -3
- package/dist/blocks/scopes.d.ts.map +1 -1
- package/dist/blocks/scopes.js +7 -3
- package/dist/blocks/scopes.js.map +1 -1
- package/dist/blocks/types.d.ts +197 -50
- package/dist/blocks/types.d.ts.map +1 -1
- package/dist/blocks/types.js +56 -0
- package/dist/blocks/types.js.map +1 -1
- package/dist/manifest/defineBlock.d.ts +145 -0
- package/dist/manifest/defineBlock.d.ts.map +1 -0
- package/dist/manifest/defineBlock.js +390 -0
- package/dist/manifest/defineBlock.js.map +1 -0
- package/dist/manifest/index.d.ts +19 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +17 -0
- package/dist/manifest/index.js.map +1 -0
- package/dist/oauth/token.d.ts +34 -3
- package/dist/oauth/token.d.ts.map +1 -1
- package/dist/oauth/token.js +116 -4
- package/dist/oauth/token.js.map +1 -1
- package/dist/vite/index.d.ts +14 -0
- package/dist/vite/index.d.ts.map +1 -0
- package/dist/vite/index.js +61 -0
- package/dist/vite/index.js.map +1 -0
- package/package.json +42 -2
- package/dist/blocks/defineBlock.d.ts +0 -53
- package/dist/blocks/defineBlock.d.ts.map +0 -1
- package/dist/blocks/defineBlock.js +0 -338
- package/dist/blocks/defineBlock.js.map +0 -1
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time validation for a `block.manifest.json`, DERIVED FROM THE CANONICAL
|
|
3
|
+
* SCHEMA rather than hand-mirrored.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT IS SHAPED THIS WAY. #330's proposed fix, item 1, verbatim: "Derive the
|
|
6
|
+
* rules from the schema, not by hand. […] A hand-written mirror of an external
|
|
7
|
+
* schema regenerates this bug every time the schema moves." The previous
|
|
8
|
+
* implementation was that hand-written mirror — 11 required fields against the
|
|
9
|
+
* canonical's 5, `appId` required though the canonical does not declare it, and
|
|
10
|
+
* `iframe.src` required though the platform REFUSES it. It rejected all seven
|
|
11
|
+
* `block.manifest.json` files this repo ships.
|
|
12
|
+
*
|
|
13
|
+
* So the machine-checkable rules are not written down here at all. They are
|
|
14
|
+
* read from `schemas/app-block/v1.json` — a byte-identical vendored copy of
|
|
15
|
+
* https://civitai.com/schemas/app-block/v1.json, kept in lockstep by
|
|
16
|
+
* `scripts/check-canonical-schema.sh` (CI job `schema-drift`) — and compiled
|
|
17
|
+
* with Ajv. Every `required`, `enum`, `pattern`, bound, `additionalProperties`
|
|
18
|
+
* and `allOf` in the canonical is therefore enforced here for free, and moves
|
|
19
|
+
* when the canonical moves.
|
|
20
|
+
*
|
|
21
|
+
* WHY THIS SUBPATH IS NODE-ONLY. Reading the schema needs `node:fs`, and Ajv is
|
|
22
|
+
* a runtime dependency. `@civitai/app-sdk`'s `dependencies` are empty on purpose
|
|
23
|
+
* — it ships into sandboxed browser iframes and every app inherits its install
|
|
24
|
+
* graph — so Ajv is an OPTIONAL PEER (the `@civitai/client` precedent) consumed
|
|
25
|
+
* only from `@civitai/app-sdk/manifest` and `@civitai/app-sdk/vite`. The only
|
|
26
|
+
* real caller is the Vite plugin, which runs in Node at build time. The
|
|
27
|
+
* browser-facing `./blocks` subpath keeps zero runtime dependencies.
|
|
28
|
+
*
|
|
29
|
+
* THE CLAIM YOU CAN CHECK:
|
|
30
|
+
*
|
|
31
|
+
* 1. `defineBlock` REJECTS everything the canonical schema rejects. This holds
|
|
32
|
+
* BY CONSTRUCTION, not by a fixture corpus: Ajv runs first and any error it
|
|
33
|
+
* reports is thrown. There is no relaxation carve-out anywhere below.
|
|
34
|
+
* 2. Beyond that it rejects exactly the rules in {@link SCHEMA_DIVERGENCES} —
|
|
35
|
+
* each one a server rejection the canonical states only in PROSE, each
|
|
36
|
+
* carrying the prose it mirrors.
|
|
37
|
+
* 3. Nothing else.
|
|
38
|
+
*
|
|
39
|
+
* PASSING IS NECESSARY, NOT SUFFICIENT for `civitai app submit` — see
|
|
40
|
+
* {@link KNOWN_GAPS}. And it is not a replacement for `civitai app validate`,
|
|
41
|
+
* the Go CLI's own local pre-check; this exists so a mistake surfaces during
|
|
42
|
+
* `pnpm dev` / `pnpm build` rather than at submit time.
|
|
43
|
+
*/
|
|
44
|
+
import type { BlockManifest } from '../blocks/types.js';
|
|
45
|
+
/**
|
|
46
|
+
* Rules `defineBlock` applies that the canonical schema does NOT express in
|
|
47
|
+
* machine-checkable form.
|
|
48
|
+
*
|
|
49
|
+
* EVERY ENTRY IS STRICTLY ADDITIVE — it can only ever REJECT a manifest Ajv
|
|
50
|
+
* accepted. None of them relaxes a canonical rule. That is what makes claim (1)
|
|
51
|
+
* in the module docblock structural rather than a promise, and it is asserted
|
|
52
|
+
* per-entry by `test/manifest/divergences.test.ts`: each entry must name a
|
|
53
|
+
* fixture the canonical schema ACCEPTS and `defineBlock` REJECTS on that
|
|
54
|
+
* entry's own field path. An entry with no such fixture fails the suite.
|
|
55
|
+
*
|
|
56
|
+
* Each `canonical` field quotes the schema text the rule mirrors, so the next
|
|
57
|
+
* person can check the mirror against its source without leaving this file.
|
|
58
|
+
*/
|
|
59
|
+
export declare const SCHEMA_DIVERGENCES: {
|
|
60
|
+
readonly 'iframe.src': {
|
|
61
|
+
readonly rule: "REJECTED when present.";
|
|
62
|
+
readonly canonical: string;
|
|
63
|
+
readonly reason: string;
|
|
64
|
+
};
|
|
65
|
+
readonly trustTier: {
|
|
66
|
+
readonly rule: "REJECTED when present.";
|
|
67
|
+
readonly canonical: string;
|
|
68
|
+
readonly reason: "Mirrors a server rejection the canonical states in prose.";
|
|
69
|
+
};
|
|
70
|
+
readonly 'iframe.sandbox': {
|
|
71
|
+
readonly rule: "Rejects `allow-same-origin` and every `allow-top-navigation*` token.";
|
|
72
|
+
readonly canonical: string;
|
|
73
|
+
readonly reason: string;
|
|
74
|
+
};
|
|
75
|
+
readonly scopeJustifications: {
|
|
76
|
+
readonly rule: "Every key must name a scope also present in `scopes`.";
|
|
77
|
+
readonly canonical: string;
|
|
78
|
+
readonly reason: string;
|
|
79
|
+
};
|
|
80
|
+
readonly settings: {
|
|
81
|
+
readonly rule: "Validated against the W3 settings meta-schema (scope/type/label/description, snake_case keys, max 32).";
|
|
82
|
+
readonly canonical: "Not a declared property. The canonical top level is not `additionalProperties: false`, so it passes.";
|
|
83
|
+
readonly reason: string;
|
|
84
|
+
};
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Rules the server applies that `defineBlock` deliberately does NOT — stated so
|
|
88
|
+
* nobody reads a green `defineBlock` as "submit will succeed". Run
|
|
89
|
+
* `civitai app validate` (the Go CLI) before `civitai app submit`; it checks
|
|
90
|
+
* against the same canonical and knows things this cannot.
|
|
91
|
+
*/
|
|
92
|
+
export declare const KNOWN_GAPS: {
|
|
93
|
+
readonly 'scopeJustifications-required-for-sensitive-scopes': string;
|
|
94
|
+
readonly 'repository-per-segment-rules': string;
|
|
95
|
+
readonly 'tier-dependent-sandbox-allowlist': string;
|
|
96
|
+
readonly 'review-granted-scope-subset': "Which of the requested `scopes` review actually grants has no schema expression at all.";
|
|
97
|
+
readonly 'slotId-registry': string;
|
|
98
|
+
readonly 'settings-meta-schema-not-vendored': string;
|
|
99
|
+
readonly 'format-uri-not-enforced': string;
|
|
100
|
+
};
|
|
101
|
+
/** The canonical schema object, parsed once. Exported for tests and tooling. */
|
|
102
|
+
export declare function loadCanonicalSchema(): Record<string, unknown>;
|
|
103
|
+
export interface DefineBlockConfig {
|
|
104
|
+
manifest: BlockManifest;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Validates the manifest against the canonical schema and returns it unchanged.
|
|
108
|
+
* Acts as a typed identity function — call it from the build (see
|
|
109
|
+
* `@civitai/app-sdk/vite`) so violations throw before anything ships. Throws
|
|
110
|
+
* {@link BlockManifestError} (with a `.field` dot-path).
|
|
111
|
+
*
|
|
112
|
+
* Enforces every rule the canonical `block.manifest.json` schema expresses,
|
|
113
|
+
* plus the prose-only server rejections in {@link SCHEMA_DIVERGENCES}. See
|
|
114
|
+
* {@link KNOWN_GAPS} for what only the server can check.
|
|
115
|
+
*
|
|
116
|
+
* The example below is kept byte-identical to `test/manifest/defineBlock.example.ts`,
|
|
117
|
+
* which is compiled and executed by the suite — a guard fails if they drift, so
|
|
118
|
+
* this snippet both type-checks and runs.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* import { defineBlock } from '@civitai/app-sdk/manifest';
|
|
122
|
+
*
|
|
123
|
+
* export const manifest = defineBlock({
|
|
124
|
+
* manifest: {
|
|
125
|
+
* $schema: 'https://civitai.com/schemas/app-block/v1.json',
|
|
126
|
+
* blockId: 'my-block',
|
|
127
|
+
* version: '0.1.0',
|
|
128
|
+
* name: 'My Block',
|
|
129
|
+
* type: 'block',
|
|
130
|
+
* targets: [{ slotId: 'model.sidebar_top', priority: 100 }],
|
|
131
|
+
* scopes: ['models:read:self'],
|
|
132
|
+
* // NOTE: no `iframe.src` — the platform stamps it at build/approve time.
|
|
133
|
+
* iframe: {
|
|
134
|
+
* minHeight: 200,
|
|
135
|
+
* maxHeight: 600,
|
|
136
|
+
* resizable: true,
|
|
137
|
+
* sandbox: 'allow-scripts allow-forms',
|
|
138
|
+
* },
|
|
139
|
+
* contentRating: 'pg',
|
|
140
|
+
* minApiVersion: '1.0',
|
|
141
|
+
* },
|
|
142
|
+
* });
|
|
143
|
+
*/
|
|
144
|
+
export declare function defineBlock(config: DefineBlockConfig): BlockManifest;
|
|
145
|
+
//# sourceMappingURL=defineBlock.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineBlock.d.ts","sourceRoot":"","sources":["../../src/manifest/defineBlock.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AAQH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;CAgErB,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,UAAU;;;;;;;;CA8Bb,CAAC;AAUX,gFAAgF;AAChF,wBAAgB,mBAAmB,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAE7D;AAmFD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,aAAa,CAAC;CAIzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,aAAa,CA0BpE"}
|
|
@@ -0,0 +1,390 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time validation for a `block.manifest.json`, DERIVED FROM THE CANONICAL
|
|
3
|
+
* SCHEMA rather than hand-mirrored.
|
|
4
|
+
*
|
|
5
|
+
* WHY IT IS SHAPED THIS WAY. #330's proposed fix, item 1, verbatim: "Derive the
|
|
6
|
+
* rules from the schema, not by hand. […] A hand-written mirror of an external
|
|
7
|
+
* schema regenerates this bug every time the schema moves." The previous
|
|
8
|
+
* implementation was that hand-written mirror — 11 required fields against the
|
|
9
|
+
* canonical's 5, `appId` required though the canonical does not declare it, and
|
|
10
|
+
* `iframe.src` required though the platform REFUSES it. It rejected all seven
|
|
11
|
+
* `block.manifest.json` files this repo ships.
|
|
12
|
+
*
|
|
13
|
+
* So the machine-checkable rules are not written down here at all. They are
|
|
14
|
+
* read from `schemas/app-block/v1.json` — a byte-identical vendored copy of
|
|
15
|
+
* https://civitai.com/schemas/app-block/v1.json, kept in lockstep by
|
|
16
|
+
* `scripts/check-canonical-schema.sh` (CI job `schema-drift`) — and compiled
|
|
17
|
+
* with Ajv. Every `required`, `enum`, `pattern`, bound, `additionalProperties`
|
|
18
|
+
* and `allOf` in the canonical is therefore enforced here for free, and moves
|
|
19
|
+
* when the canonical moves.
|
|
20
|
+
*
|
|
21
|
+
* WHY THIS SUBPATH IS NODE-ONLY. Reading the schema needs `node:fs`, and Ajv is
|
|
22
|
+
* a runtime dependency. `@civitai/app-sdk`'s `dependencies` are empty on purpose
|
|
23
|
+
* — it ships into sandboxed browser iframes and every app inherits its install
|
|
24
|
+
* graph — so Ajv is an OPTIONAL PEER (the `@civitai/client` precedent) consumed
|
|
25
|
+
* only from `@civitai/app-sdk/manifest` and `@civitai/app-sdk/vite`. The only
|
|
26
|
+
* real caller is the Vite plugin, which runs in Node at build time. The
|
|
27
|
+
* browser-facing `./blocks` subpath keeps zero runtime dependencies.
|
|
28
|
+
*
|
|
29
|
+
* THE CLAIM YOU CAN CHECK:
|
|
30
|
+
*
|
|
31
|
+
* 1. `defineBlock` REJECTS everything the canonical schema rejects. This holds
|
|
32
|
+
* BY CONSTRUCTION, not by a fixture corpus: Ajv runs first and any error it
|
|
33
|
+
* reports is thrown. There is no relaxation carve-out anywhere below.
|
|
34
|
+
* 2. Beyond that it rejects exactly the rules in {@link SCHEMA_DIVERGENCES} —
|
|
35
|
+
* each one a server rejection the canonical states only in PROSE, each
|
|
36
|
+
* carrying the prose it mirrors.
|
|
37
|
+
* 3. Nothing else.
|
|
38
|
+
*
|
|
39
|
+
* PASSING IS NECESSARY, NOT SUFFICIENT for `civitai app submit` — see
|
|
40
|
+
* {@link KNOWN_GAPS}. And it is not a replacement for `civitai app validate`,
|
|
41
|
+
* the Go CLI's own local pre-check; this exists so a mistake surfaces during
|
|
42
|
+
* `pnpm dev` / `pnpm build` rather than at submit time.
|
|
43
|
+
*/
|
|
44
|
+
import { readFileSync } from 'node:fs';
|
|
45
|
+
import Ajv2020 from 'ajv/dist/2020.js';
|
|
46
|
+
import { BlockManifestError } from '../blocks/manifestError.js';
|
|
47
|
+
import { BLOCK_SCOPES } from '../blocks/scopes.js';
|
|
48
|
+
/**
|
|
49
|
+
* Rules `defineBlock` applies that the canonical schema does NOT express in
|
|
50
|
+
* machine-checkable form.
|
|
51
|
+
*
|
|
52
|
+
* EVERY ENTRY IS STRICTLY ADDITIVE — it can only ever REJECT a manifest Ajv
|
|
53
|
+
* accepted. None of them relaxes a canonical rule. That is what makes claim (1)
|
|
54
|
+
* in the module docblock structural rather than a promise, and it is asserted
|
|
55
|
+
* per-entry by `test/manifest/divergences.test.ts`: each entry must name a
|
|
56
|
+
* fixture the canonical schema ACCEPTS and `defineBlock` REJECTS on that
|
|
57
|
+
* entry's own field path. An entry with no such fixture fails the suite.
|
|
58
|
+
*
|
|
59
|
+
* Each `canonical` field quotes the schema text the rule mirrors, so the next
|
|
60
|
+
* person can check the mirror against its source without leaving this file.
|
|
61
|
+
*/
|
|
62
|
+
export const SCHEMA_DIVERGENCES = {
|
|
63
|
+
'iframe.src': {
|
|
64
|
+
rule: 'REJECTED when present.',
|
|
65
|
+
canonical: 'Declared under `iframe.properties` with the description "SERVER-OWNED. Do NOT set ' +
|
|
66
|
+
"iframe.src — the platform assigns it. Present here only so the schema can reject dev-set " +
|
|
67
|
+
'values." The JSON-Schema `not` is deliberately absent; the top-level `allOf` $comment says ' +
|
|
68
|
+
'the platform validator and the Go CLI reject it "with clearer error messages than JSON ' +
|
|
69
|
+
"Schema's `not`\".",
|
|
70
|
+
reason: 'Mirrors a server rejection the canonical states in prose and deliberately does not encode. ' +
|
|
71
|
+
'This is the #330 headline inverted: the old validator REQUIRED `iframe.src`, demanding the ' +
|
|
72
|
+
'exact value submit refuses.',
|
|
73
|
+
},
|
|
74
|
+
trustTier: {
|
|
75
|
+
rule: 'REJECTED when present.',
|
|
76
|
+
canonical: 'Declared with the description "SERVER-OWNED. Do NOT set this in your manifest — the ' +
|
|
77
|
+
'platform assigns the trust tier during review. Present here only to reject dev-set values." ' +
|
|
78
|
+
'Same deliberately-absent `not` as `iframe.src`, per the same `allOf` $comment.',
|
|
79
|
+
reason: 'Mirrors a server rejection the canonical states in prose.',
|
|
80
|
+
},
|
|
81
|
+
'iframe.sandbox': {
|
|
82
|
+
rule: 'Rejects `allow-same-origin` and every `allow-top-navigation*` token.',
|
|
83
|
+
canonical: 'Only `minLength: 1`. The description carries two separate prose rules: a TIER ALLOWLIST ' +
|
|
84
|
+
'("Unverified tier allows only: allow-scripts, allow-forms") and a flat prohibition ' +
|
|
85
|
+
'("Never combine allow-same-origin with allow-scripts").',
|
|
86
|
+
reason: 'Mirrors the flat prohibition, plus top-navigation (including the -by-user-activation and ' +
|
|
87
|
+
'-to-custom-protocols variants), which lets a block navigate the host frame instead of ' +
|
|
88
|
+
'routing through the NAVIGATE postMessage. ' +
|
|
89
|
+
'🔴 THE TIER ALLOWLIST IS DELIBERATELY NOT MIRRORED, AND THAT MAKES THIS GATE LOOSER THAN ' +
|
|
90
|
+
'REVIEW IN THE OTHER DIRECTION: `allow-popups`, `allow-modals`, `allow-downloads` and any ' +
|
|
91
|
+
'other token outside {allow-scripts, allow-forms} PASS HERE and may be refused at review. ' +
|
|
92
|
+
'They are not rejected because the tier is assigned server-side during review and is ' +
|
|
93
|
+
'unknowable locally — `starters/civitai-block-starter` itself ships ' +
|
|
94
|
+
'"allow-scripts allow-forms allow-popups allow-popups-to-escape-sandbox". See ' +
|
|
95
|
+
'KNOWN_GAPS["tier-dependent-sandbox-allowlist"].',
|
|
96
|
+
},
|
|
97
|
+
scopeJustifications: {
|
|
98
|
+
rule: 'Every key must name a scope also present in `scopes`.',
|
|
99
|
+
canonical: '`additionalProperties: { type: string, minLength: 1, maxLength: 500 }` — any key passes. ' +
|
|
100
|
+
'The canonical says so itself: "The requirement is enforced imperatively by the manifest ' +
|
|
101
|
+
'validator (not expressed as JSON-Schema conditionals here)."',
|
|
102
|
+
reason: 'Mirrors a server rejection the canonical states in prose. The OTHER half of that server ' +
|
|
103
|
+
'rule — justifications being REQUIRED for sensitive scopes — is NOT mirrored; see ' +
|
|
104
|
+
'KNOWN_GAPS["scopeJustifications-required-for-sensitive-scopes"].',
|
|
105
|
+
},
|
|
106
|
+
settings: {
|
|
107
|
+
rule: 'Validated against the W3 settings meta-schema (scope/type/label/description, snake_case keys, max 32).',
|
|
108
|
+
canonical: 'Not a declared property. The canonical top level is not `additionalProperties: false`, so it passes.',
|
|
109
|
+
reason: "Manifest settings ARE validated server-side, by civitai/civitai's " +
|
|
110
|
+
'`manifest-settings.meta.schema.ts` rather than by the app-block schema, and two of the ' +
|
|
111
|
+
'seven shipped manifests declare `settings`. ' +
|
|
112
|
+
'🔴 THIS IS THE ONE REMAINING HAND-WRITTEN MIRROR OF AN EXTERNAL SCHEMA IN THIS FILE, i.e. ' +
|
|
113
|
+
'exactly the construct #330 was filed about — it is here only because that meta-schema is ' +
|
|
114
|
+
'NOT published at a URL and NOT vendored, so there is nothing to derive from. The fix is ' +
|
|
115
|
+
'upstream: publish it and vendor it beside `app-block/v1.json` with the same drift-check, ' +
|
|
116
|
+
'then delete this. See KNOWN_GAPS["settings-meta-schema-not-vendored"].',
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Rules the server applies that `defineBlock` deliberately does NOT — stated so
|
|
121
|
+
* nobody reads a green `defineBlock` as "submit will succeed". Run
|
|
122
|
+
* `civitai app validate` (the Go CLI) before `civitai app submit`; it checks
|
|
123
|
+
* against the same canonical and knows things this cannot.
|
|
124
|
+
*/
|
|
125
|
+
export const KNOWN_GAPS = {
|
|
126
|
+
'scopeJustifications-required-for-sensitive-scopes': 'The canonical names the sensitive scope set only in a prose description, not in a ' +
|
|
127
|
+
'machine-readable form. Hand-mirroring that list would regenerate the #330 drift bug, so ' +
|
|
128
|
+
'only the SHAPE is checked here (keys must be declared scopes; the canonical checks the ' +
|
|
129
|
+
'1..500-char values). The requirement itself is server-side.',
|
|
130
|
+
'repository-per-segment-rules': 'The canonical\'s `repository` pattern is documented as "a coarse SHAPE check and NOT the ' +
|
|
131
|
+
'whole rule"; the server additionally constrains each path segment. Ajv enforces the ' +
|
|
132
|
+
'canonical pattern exactly, and is therefore necessary-not-sufficient BY THE CANONICAL\'S ' +
|
|
133
|
+
'OWN DESIGN.',
|
|
134
|
+
'tier-dependent-sandbox-allowlist': 'The canonical\'s sandbox description is an ALLOWLIST ("Unverified tier allows only: ' +
|
|
135
|
+
'allow-scripts, allow-forms"), but the tier is assigned server-side during review, so the ' +
|
|
136
|
+
'applicable allowlist is unknowable at build time. Tokens outside that set pass here and may ' +
|
|
137
|
+
'be refused at review. See SCHEMA_DIVERGENCES["iframe.sandbox"].',
|
|
138
|
+
'review-granted-scope-subset': 'Which of the requested `scopes` review actually grants has no schema expression at all.',
|
|
139
|
+
'slotId-registry': 'Whether a `targets[].slotId` names a slot the host has registered has no schema expression; ' +
|
|
140
|
+
'the canonical only requires a non-empty string.',
|
|
141
|
+
'settings-meta-schema-not-vendored': "civitai/civitai's `manifest-settings.meta.schema.ts` is not published at a URL and not " +
|
|
142
|
+
'vendored here, so `settings` is the one surface still checked by a hand-written mirror. ' +
|
|
143
|
+
'See SCHEMA_DIVERGENCES.settings.',
|
|
144
|
+
'format-uri-not-enforced': '`assetBundleUrl` carries `format: "uri"` in addition to `pattern: "^https://"`. Ajv ignores ' +
|
|
145
|
+
'unknown formats unless `ajv-formats` is installed, which would be a second optional peer for ' +
|
|
146
|
+
'one field whose pattern is already enforced. The pattern IS enforced; the `uri` format is ' +
|
|
147
|
+
'not, so a value like "https://" passes here.',
|
|
148
|
+
};
|
|
149
|
+
/**
|
|
150
|
+
* The vendored canonical, resolved relative to THIS module so the same
|
|
151
|
+
* specifier works from `src/` (vitest) and from `dist/` (published):
|
|
152
|
+
* `src/manifest/` -> `../../schemas/`, `dist/manifest/` -> `../../schemas/`.
|
|
153
|
+
* `schemas` is in package.json `files`, so it ships.
|
|
154
|
+
*/
|
|
155
|
+
const CANONICAL_SCHEMA_PATH = new URL('../../schemas/app-block/v1.json', import.meta.url);
|
|
156
|
+
/** The canonical schema object, parsed once. Exported for tests and tooling. */
|
|
157
|
+
export function loadCanonicalSchema() {
|
|
158
|
+
return JSON.parse(readFileSync(CANONICAL_SCHEMA_PATH, 'utf8'));
|
|
159
|
+
}
|
|
160
|
+
let compiled;
|
|
161
|
+
function canonicalValidator() {
|
|
162
|
+
if (compiled)
|
|
163
|
+
return compiled;
|
|
164
|
+
// `strict: false` because the canonical uses `$comment` and a `format` Ajv
|
|
165
|
+
// does not know (see KNOWN_GAPS['format-uri-not-enforced']); strict mode would
|
|
166
|
+
// turn those into compile-time throws over a schema this package does not own
|
|
167
|
+
// and must not edit.
|
|
168
|
+
//
|
|
169
|
+
// `logger: false` because that same unknown format makes Ajv log
|
|
170
|
+
// `unknown format "uri" ignored…` to the console AT COMPILE TIME — which, via
|
|
171
|
+
// the Vite plugin, would print on every `pnpm dev` and `pnpm build` in every
|
|
172
|
+
// scaffold. The gap is recorded in KNOWN_GAPS, not shouted at the author on
|
|
173
|
+
// every boot. NOTE this silences Ajv's own diagnostics only; validation
|
|
174
|
+
// errors are returned in `validate.errors`, never logged.
|
|
175
|
+
const ajv = new Ajv2020({ allErrors: true, strict: false, logger: false });
|
|
176
|
+
compiled = ajv.compile(loadCanonicalSchema());
|
|
177
|
+
return compiled;
|
|
178
|
+
}
|
|
179
|
+
/** `/iframe/minHeight` -> `iframe.minHeight`; `/targets/0/slotId` -> `targets[0].slotId`. */
|
|
180
|
+
function toDotPath(instancePath) {
|
|
181
|
+
if (instancePath === '')
|
|
182
|
+
return '';
|
|
183
|
+
return instancePath
|
|
184
|
+
.slice(1)
|
|
185
|
+
.split('/')
|
|
186
|
+
.reduce((acc, segment) => {
|
|
187
|
+
// JSON Pointer escapes: ~1 is '/', ~0 is '~'.
|
|
188
|
+
const key = segment.replace(/~1/g, '/').replace(/~0/g, '~');
|
|
189
|
+
if (/^\d+$/.test(key))
|
|
190
|
+
return `${acc}[${key}]`;
|
|
191
|
+
return acc === '' ? key : `${acc}.${key}`;
|
|
192
|
+
}, '');
|
|
193
|
+
}
|
|
194
|
+
const PASCAL_CASE_PATTERN = /^[A-Z][A-Za-z0-9]*$/;
|
|
195
|
+
/**
|
|
196
|
+
* Turns the FIRST Ajv error into a `BlockManifestError`. Ajv's own wording is
|
|
197
|
+
* kept (it is derived from the schema, so it cannot drift); only the field path
|
|
198
|
+
* is reshaped, and one case gets an extra hint because it is the mistake the
|
|
199
|
+
* docs see most.
|
|
200
|
+
*/
|
|
201
|
+
function toManifestError(error, manifest) {
|
|
202
|
+
const base = toDotPath(error.instancePath);
|
|
203
|
+
if (error.keyword === 'required') {
|
|
204
|
+
const missing = error.params.missingProperty;
|
|
205
|
+
const field = base === '' ? missing : `${base}.${missing}`;
|
|
206
|
+
return new BlockManifestError(`manifest.${field} is required`, field);
|
|
207
|
+
}
|
|
208
|
+
const field = base;
|
|
209
|
+
const shown = field === '' ? 'manifest' : `manifest.${field}`;
|
|
210
|
+
let message = `${shown} ${error.message ?? 'is invalid'}`;
|
|
211
|
+
if (error.keyword === 'enum') {
|
|
212
|
+
const allowed = error.params.allowedValues;
|
|
213
|
+
if (allowed)
|
|
214
|
+
message += ` (${allowed.map((v) => JSON.stringify(v)).join(', ')})`;
|
|
215
|
+
}
|
|
216
|
+
if (error.keyword === 'additionalProperties') {
|
|
217
|
+
const extra = error.params.additionalProperty;
|
|
218
|
+
message = `${shown}.${extra} is not a known property here`;
|
|
219
|
+
return new BlockManifestError(message, field === '' ? extra : `${field}.${extra}`);
|
|
220
|
+
}
|
|
221
|
+
// The one hint worth adding: block scopes are colon-separated lowercase, and
|
|
222
|
+
// the OAuth scopes elsewhere in this SDK are PascalCase bitmask names, so
|
|
223
|
+
// authors reach for the wrong spelling.
|
|
224
|
+
if (/^scopes\[\d+\]$/.test(field)) {
|
|
225
|
+
const index = Number(field.slice(field.indexOf('[') + 1, -1));
|
|
226
|
+
const value = manifest?.scopes?.[index];
|
|
227
|
+
if (typeof value === 'string' && PASCAL_CASE_PATTERN.test(value)) {
|
|
228
|
+
message +=
|
|
229
|
+
'. Block scope strings are colon-separated lowercase (e.g. "models:read:self"), ' +
|
|
230
|
+
'not the PascalCase OAuth bitmask names';
|
|
231
|
+
}
|
|
232
|
+
message += `. Must be one of: ${Object.values(BLOCK_SCOPES).join(', ')}`;
|
|
233
|
+
}
|
|
234
|
+
return new BlockManifestError(message, field);
|
|
235
|
+
}
|
|
236
|
+
/**
|
|
237
|
+
* Validates the manifest against the canonical schema and returns it unchanged.
|
|
238
|
+
* Acts as a typed identity function — call it from the build (see
|
|
239
|
+
* `@civitai/app-sdk/vite`) so violations throw before anything ships. Throws
|
|
240
|
+
* {@link BlockManifestError} (with a `.field` dot-path).
|
|
241
|
+
*
|
|
242
|
+
* Enforces every rule the canonical `block.manifest.json` schema expresses,
|
|
243
|
+
* plus the prose-only server rejections in {@link SCHEMA_DIVERGENCES}. See
|
|
244
|
+
* {@link KNOWN_GAPS} for what only the server can check.
|
|
245
|
+
*
|
|
246
|
+
* The example below is kept byte-identical to `test/manifest/defineBlock.example.ts`,
|
|
247
|
+
* which is compiled and executed by the suite — a guard fails if they drift, so
|
|
248
|
+
* this snippet both type-checks and runs.
|
|
249
|
+
*
|
|
250
|
+
* @example
|
|
251
|
+
* import { defineBlock } from '@civitai/app-sdk/manifest';
|
|
252
|
+
*
|
|
253
|
+
* export const manifest = defineBlock({
|
|
254
|
+
* manifest: {
|
|
255
|
+
* $schema: 'https://civitai.com/schemas/app-block/v1.json',
|
|
256
|
+
* blockId: 'my-block',
|
|
257
|
+
* version: '0.1.0',
|
|
258
|
+
* name: 'My Block',
|
|
259
|
+
* type: 'block',
|
|
260
|
+
* targets: [{ slotId: 'model.sidebar_top', priority: 100 }],
|
|
261
|
+
* scopes: ['models:read:self'],
|
|
262
|
+
* // NOTE: no `iframe.src` — the platform stamps it at build/approve time.
|
|
263
|
+
* iframe: {
|
|
264
|
+
* minHeight: 200,
|
|
265
|
+
* maxHeight: 600,
|
|
266
|
+
* resizable: true,
|
|
267
|
+
* sandbox: 'allow-scripts allow-forms',
|
|
268
|
+
* },
|
|
269
|
+
* contentRating: 'pg',
|
|
270
|
+
* minApiVersion: '1.0',
|
|
271
|
+
* },
|
|
272
|
+
* });
|
|
273
|
+
*/
|
|
274
|
+
export function defineBlock(config) {
|
|
275
|
+
const { manifest } = config;
|
|
276
|
+
if (manifest == null || typeof manifest !== 'object' || Array.isArray(manifest)) {
|
|
277
|
+
throw new BlockManifestError('manifest must be an object');
|
|
278
|
+
}
|
|
279
|
+
// (1) Everything the canonical expresses. No carve-outs, no suppression:
|
|
280
|
+
// whatever Ajv rejects, this rejects.
|
|
281
|
+
const validate = canonicalValidator();
|
|
282
|
+
if (!validate(manifest)) {
|
|
283
|
+
const errors = validate.errors ?? [];
|
|
284
|
+
const first = errors[0];
|
|
285
|
+
/* c8 ignore next */
|
|
286
|
+
if (!first)
|
|
287
|
+
throw new BlockManifestError('manifest failed schema validation');
|
|
288
|
+
throw toManifestError(first, manifest);
|
|
289
|
+
}
|
|
290
|
+
// (2) The prose-only server rejections. Strictly additive, one per
|
|
291
|
+
// SCHEMA_DIVERGENCES entry, in the table's order.
|
|
292
|
+
rejectServerOwned(manifest);
|
|
293
|
+
rejectDangerousSandboxTokens(manifest);
|
|
294
|
+
rejectUndeclaredScopeJustifications(manifest);
|
|
295
|
+
if (manifest.settings !== undefined)
|
|
296
|
+
validateSettings(manifest.settings);
|
|
297
|
+
return manifest;
|
|
298
|
+
}
|
|
299
|
+
const SERVER_OWNED_MESSAGE = 'is SERVER-OWNED — the platform assigns it during build/approve. Remove it from the manifest.';
|
|
300
|
+
/** SCHEMA_DIVERGENCES['iframe.src'] and SCHEMA_DIVERGENCES.trustTier. */
|
|
301
|
+
function rejectServerOwned(manifest) {
|
|
302
|
+
if (manifest.trustTier !== undefined) {
|
|
303
|
+
throw new BlockManifestError(`manifest.trustTier ${SERVER_OWNED_MESSAGE}`, 'trustTier');
|
|
304
|
+
}
|
|
305
|
+
const iframe = manifest.iframe;
|
|
306
|
+
if (iframe != null && iframe.src !== undefined) {
|
|
307
|
+
throw new BlockManifestError(`manifest.iframe.src ${SERVER_OWNED_MESSAGE}`, 'iframe.src');
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* SCHEMA_DIVERGENCES['iframe.sandbox']. A DENYLIST, not the canonical's tier
|
|
312
|
+
* allowlist — see that entry and KNOWN_GAPS['tier-dependent-sandbox-allowlist']
|
|
313
|
+
* for why, and for what therefore passes here and fails at review.
|
|
314
|
+
*/
|
|
315
|
+
const BANNED_SANDBOX_TOKENS = new Set([
|
|
316
|
+
'allow-same-origin',
|
|
317
|
+
'allow-top-navigation',
|
|
318
|
+
'allow-top-navigation-by-user-activation',
|
|
319
|
+
'allow-top-navigation-to-custom-protocols',
|
|
320
|
+
]);
|
|
321
|
+
function rejectDangerousSandboxTokens(manifest) {
|
|
322
|
+
const sandbox = manifest.iframe?.sandbox;
|
|
323
|
+
if (typeof sandbox !== 'string')
|
|
324
|
+
return;
|
|
325
|
+
const tokens = new Set(sandbox.split(/\s+/).filter(Boolean));
|
|
326
|
+
for (const banned of BANNED_SANDBOX_TOKENS) {
|
|
327
|
+
if (tokens.has(banned)) {
|
|
328
|
+
throw new BlockManifestError(`manifest.iframe.sandbox must not contain "${banned}". ` +
|
|
329
|
+
(banned === 'allow-same-origin'
|
|
330
|
+
? 'Combined with "allow-scripts" it defeats the sandbox entirely.'
|
|
331
|
+
: 'Blocks must route navigation through the NAVIGATE postMessage so the host can mediate.'), 'iframe.sandbox');
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
/** SCHEMA_DIVERGENCES.scopeJustifications. */
|
|
336
|
+
function rejectUndeclaredScopeJustifications(manifest) {
|
|
337
|
+
const justifications = manifest.scopeJustifications;
|
|
338
|
+
if (justifications == null)
|
|
339
|
+
return;
|
|
340
|
+
const declared = new Set(manifest.scopes ?? []);
|
|
341
|
+
for (const scope of Object.keys(justifications)) {
|
|
342
|
+
if (!declared.has(scope)) {
|
|
343
|
+
const path = `scopeJustifications.${scope}`;
|
|
344
|
+
throw new BlockManifestError(`manifest.${path} justifies a scope that is not in manifest.scopes. ` +
|
|
345
|
+
'Every justification key must be a scope the manifest actually requests.', path);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* SCHEMA_DIVERGENCES.settings — the one hand-written mirror left, of
|
|
351
|
+
* civitai/civitai's `manifest-settings.meta.schema.ts`. Keep both sides aligned
|
|
352
|
+
* until that meta-schema is published and vendored; see
|
|
353
|
+
* KNOWN_GAPS['settings-meta-schema-not-vendored'].
|
|
354
|
+
*/
|
|
355
|
+
const SETTING_TYPES = ['number', 'string', 'boolean'];
|
|
356
|
+
const SETTING_SCOPES = ['publisher', 'viewer'];
|
|
357
|
+
const SETTING_KEY_PATTERN = /^[a-z][a-z0-9_]{0,40}$/;
|
|
358
|
+
const MAX_SETTINGS_PER_BLOCK = 32;
|
|
359
|
+
function validateSettings(settings) {
|
|
360
|
+
if (settings == null || typeof settings !== 'object' || Array.isArray(settings)) {
|
|
361
|
+
throw new BlockManifestError('manifest.settings must be an object (record keyed by snake_case field name)', 'settings');
|
|
362
|
+
}
|
|
363
|
+
const entries = Object.entries(settings);
|
|
364
|
+
if (entries.length > MAX_SETTINGS_PER_BLOCK) {
|
|
365
|
+
throw new BlockManifestError(`manifest.settings has ${entries.length} entries (max ${MAX_SETTINGS_PER_BLOCK})`, 'settings');
|
|
366
|
+
}
|
|
367
|
+
for (const [key, raw] of entries) {
|
|
368
|
+
const path = `settings.${key}`;
|
|
369
|
+
if (!SETTING_KEY_PATTERN.test(key)) {
|
|
370
|
+
throw new BlockManifestError(`manifest.${path}: key must match ${SETTING_KEY_PATTERN} (snake_case, must start with a letter)`, path);
|
|
371
|
+
}
|
|
372
|
+
if (raw == null || typeof raw !== 'object') {
|
|
373
|
+
throw new BlockManifestError(`manifest.${path} must be an object`, path);
|
|
374
|
+
}
|
|
375
|
+
const s = raw;
|
|
376
|
+
if (typeof s.scope !== 'string' || !SETTING_SCOPES.includes(s.scope)) {
|
|
377
|
+
throw new BlockManifestError(`manifest.${path}.scope must be one of ${SETTING_SCOPES.join(', ')}. Got: ${JSON.stringify(s.scope)}`, `${path}.scope`);
|
|
378
|
+
}
|
|
379
|
+
if (typeof s.type !== 'string' || !SETTING_TYPES.includes(s.type)) {
|
|
380
|
+
throw new BlockManifestError(`manifest.${path}.type must be one of ${SETTING_TYPES.join(', ')}. Got: ${JSON.stringify(s.type)}`, `${path}.type`);
|
|
381
|
+
}
|
|
382
|
+
if (typeof s.label !== 'string' || s.label.length === 0) {
|
|
383
|
+
throw new BlockManifestError(`manifest.${path}.label must be a non-empty string`, `${path}.label`);
|
|
384
|
+
}
|
|
385
|
+
if (typeof s.description !== 'string' || s.description.length === 0) {
|
|
386
|
+
throw new BlockManifestError(`manifest.${path}.description must be a non-empty string`, `${path}.description`);
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
//# sourceMappingURL=defineBlock.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defineBlock.js","sourceRoot":"","sources":["../../src/manifest/defineBlock.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@civitai/app-sdk/manifest` — NODE-ONLY build-time manifest validation.
|
|
3
|
+
*
|
|
4
|
+
* Separate from `./blocks` on purpose. `./blocks` is the browser contract and
|
|
5
|
+
* carries ZERO runtime dependencies (it ships into sandboxed iframes and every
|
|
6
|
+
* app inherits its install graph). This subpath reads the vendored canonical
|
|
7
|
+
* schema off disk with `node:fs` and compiles it with Ajv, which is an OPTIONAL
|
|
8
|
+
* PEER — install it where you use this:
|
|
9
|
+
*
|
|
10
|
+
* pnpm add -D ajv
|
|
11
|
+
*
|
|
12
|
+
* Most callers want `@civitai/app-sdk/vite` instead, which wraps `defineBlock`
|
|
13
|
+
* in a Vite plugin that runs on every dev-server boot and every build.
|
|
14
|
+
*/
|
|
15
|
+
export { defineBlock, SCHEMA_DIVERGENCES, KNOWN_GAPS, loadCanonicalSchema } from './defineBlock.js';
|
|
16
|
+
export type { DefineBlockConfig } from './defineBlock.js';
|
|
17
|
+
export { BlockManifestError } from '../blocks/manifestError.js';
|
|
18
|
+
export type { BlockManifest, BlockManifestV1 } from '../blocks/types.js';
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACpG,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAChE,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@civitai/app-sdk/manifest` — NODE-ONLY build-time manifest validation.
|
|
3
|
+
*
|
|
4
|
+
* Separate from `./blocks` on purpose. `./blocks` is the browser contract and
|
|
5
|
+
* carries ZERO runtime dependencies (it ships into sandboxed iframes and every
|
|
6
|
+
* app inherits its install graph). This subpath reads the vendored canonical
|
|
7
|
+
* schema off disk with `node:fs` and compiles it with Ajv, which is an OPTIONAL
|
|
8
|
+
* PEER — install it where you use this:
|
|
9
|
+
*
|
|
10
|
+
* pnpm add -D ajv
|
|
11
|
+
*
|
|
12
|
+
* Most callers want `@civitai/app-sdk/vite` instead, which wraps `defineBlock`
|
|
13
|
+
* in a Vite plugin that runs on every dev-server boot and every build.
|
|
14
|
+
*/
|
|
15
|
+
export { defineBlock, SCHEMA_DIVERGENCES, KNOWN_GAPS, loadCanonicalSchema } from './defineBlock.js';
|
|
16
|
+
export { BlockManifestError } from '../blocks/manifestError.js';
|
|
17
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/manifest/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEpG,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC"}
|