create-kerf-component 5.0.0-beta.5 → 5.0.0-beta.50

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.
@@ -0,0 +1,298 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/brianwestphal/kerf/main/ui/ai/component-catalog-v2.schema.json",
4
+ "title": "Kerf UI composition catalog v2",
5
+ "type": "object",
6
+ "required": ["schemaVersion", "package", "compatibility", "entries"],
7
+ "properties": {
8
+ "$schema": { "type": "string" },
9
+ "schemaVersion": { "const": 2 },
10
+ "package": { "type": "string", "minLength": 1 },
11
+ "compatibility": {
12
+ "type": "object",
13
+ "required": ["v1Catalog", "identity"],
14
+ "properties": {
15
+ "v1Catalog": { "type": "string", "minLength": 1 },
16
+ "identity": { "const": "package:id" }
17
+ },
18
+ "additionalProperties": false
19
+ },
20
+ "entries": { "type": "array", "items": { "$ref": "#/$defs/entry" } }
21
+ },
22
+ "additionalProperties": false,
23
+ "$defs": {
24
+ "stringList": {
25
+ "type": "array",
26
+ "items": { "type": "string", "minLength": 1 },
27
+ "uniqueItems": true
28
+ },
29
+ "cardinality": {
30
+ "type": "object",
31
+ "required": ["min", "max"],
32
+ "properties": {
33
+ "min": { "type": "integer", "minimum": 0 },
34
+ "max": {
35
+ "anyOf": [
36
+ { "type": "integer", "minimum": 1 },
37
+ { "const": "unbounded" }
38
+ ]
39
+ }
40
+ },
41
+ "additionalProperties": false
42
+ },
43
+ "zone": {
44
+ "type": "object",
45
+ "required": ["id", "accepts", "cardinality", "exclusiveWith"],
46
+ "properties": {
47
+ "id": { "type": "string", "minLength": 1 },
48
+ "jsx": {
49
+ "type": "object",
50
+ "required": ["prop"],
51
+ "properties": {
52
+ "prop": { "type": "string", "minLength": 1 }
53
+ },
54
+ "additionalProperties": false
55
+ },
56
+ "accepts": { "$ref": "#/$defs/stringList" },
57
+ "cardinality": { "$ref": "#/$defs/cardinality" },
58
+ "exclusiveWith": { "$ref": "#/$defs/stringList" }
59
+ },
60
+ "additionalProperties": false
61
+ },
62
+ "state": {
63
+ "type": "object",
64
+ "required": ["id", "owner", "required"],
65
+ "properties": {
66
+ "id": { "type": "string", "minLength": 1 },
67
+ "owner": { "enum": ["application", "controlled", "component"] },
68
+ "required": { "type": "boolean" }
69
+ },
70
+ "additionalProperties": false
71
+ },
72
+ "diagnostic": {
73
+ "type": "object",
74
+ "required": ["id", "severity", "when", "message"],
75
+ "properties": {
76
+ "id": { "type": "string", "pattern": "^KUI-C[0-9]{3}$" },
77
+ "severity": { "enum": ["error", "warning"] },
78
+ "when": { "type": "string", "minLength": 1 },
79
+ "message": { "type": "string", "minLength": 1 }
80
+ },
81
+ "additionalProperties": false
82
+ },
83
+ "entry": {
84
+ "type": "object",
85
+ "required": [
86
+ "key",
87
+ "package",
88
+ "id",
89
+ "name",
90
+ "kind",
91
+ "source",
92
+ "parents",
93
+ "contexts",
94
+ "zones",
95
+ "children",
96
+ "state",
97
+ "wiring",
98
+ "responsive",
99
+ "layout",
100
+ "accessibility",
101
+ "boundaries",
102
+ "diagnostics",
103
+ "provenance"
104
+ ],
105
+ "properties": {
106
+ "key": { "type": "string", "minLength": 3 },
107
+ "package": { "type": "string", "minLength": 1 },
108
+ "id": { "type": "string", "minLength": 1 },
109
+ "name": { "type": "string", "minLength": 1 },
110
+ "kind": { "enum": ["component", "composition", "recipe"] },
111
+ "purpose": { "type": "string", "minLength": 1 },
112
+ "publicExports": {
113
+ "type": "array",
114
+ "items": {
115
+ "type": "object",
116
+ "required": ["name", "subpath"],
117
+ "properties": {
118
+ "name": { "type": "string", "minLength": 1 },
119
+ "subpath": { "type": "string", "pattern": "^\\." }
120
+ },
121
+ "additionalProperties": false
122
+ },
123
+ "minItems": 1
124
+ },
125
+ "sourceLinks": { "$ref": "#/$defs/stringList" },
126
+ "source": { "type": "string", "minLength": 1 },
127
+ "parents": {
128
+ "type": "object",
129
+ "required": ["mode", "entries"],
130
+ "properties": {
131
+ "mode": { "enum": ["any", "root", "listed"] },
132
+ "entries": { "$ref": "#/$defs/stringList" }
133
+ },
134
+ "additionalProperties": false
135
+ },
136
+ "contexts": { "$ref": "#/$defs/stringList" },
137
+ "zones": { "type": "array", "items": { "$ref": "#/$defs/zone" } },
138
+ "children": {
139
+ "type": "object",
140
+ "required": ["mode", "concepts", "requiredConcepts"],
141
+ "properties": {
142
+ "mode": { "enum": ["any", "none", "listed"] },
143
+ "concepts": { "$ref": "#/$defs/stringList" },
144
+ "requiredConcepts": { "$ref": "#/$defs/stringList" }
145
+ },
146
+ "additionalProperties": false
147
+ },
148
+ "state": { "type": "array", "items": { "$ref": "#/$defs/state" } },
149
+ "wiring": {
150
+ "type": "object",
151
+ "required": ["required", "helpers", "obligations"],
152
+ "properties": {
153
+ "required": { "type": "boolean" },
154
+ "helpers": { "$ref": "#/$defs/stringList" },
155
+ "obligations": { "$ref": "#/$defs/stringList" }
156
+ },
157
+ "additionalProperties": false
158
+ },
159
+ "responsive": {
160
+ "type": "object",
161
+ "required": ["owner", "behaviors"],
162
+ "properties": {
163
+ "owner": {
164
+ "enum": ["application", "component", "shared", "not-applicable"]
165
+ },
166
+ "behaviors": { "$ref": "#/$defs/stringList" }
167
+ },
168
+ "additionalProperties": false
169
+ },
170
+ "layout": {
171
+ "type": "object",
172
+ "required": ["roles", "geometry"],
173
+ "properties": {
174
+ "roles": { "$ref": "#/$defs/stringList" },
175
+ "geometry": {
176
+ "type": "object",
177
+ "required": ["margin", "border", "padding"],
178
+ "properties": {
179
+ "margin": {
180
+ "enum": [
181
+ "self",
182
+ "parent",
183
+ "child",
184
+ "none",
185
+ "conditional",
186
+ "composed"
187
+ ]
188
+ },
189
+ "border": {
190
+ "enum": [
191
+ "self",
192
+ "parent",
193
+ "child",
194
+ "none",
195
+ "conditional",
196
+ "composed"
197
+ ]
198
+ },
199
+ "padding": {
200
+ "enum": [
201
+ "self",
202
+ "parent",
203
+ "child",
204
+ "none",
205
+ "conditional",
206
+ "composed"
207
+ ]
208
+ },
209
+ "notes": { "$ref": "#/$defs/stringList" }
210
+ },
211
+ "additionalProperties": false
212
+ }
213
+ },
214
+ "additionalProperties": false
215
+ },
216
+ "accessibility": {
217
+ "type": "object",
218
+ "required": ["obligations"],
219
+ "properties": { "obligations": { "$ref": "#/$defs/stringList" } },
220
+ "additionalProperties": false
221
+ },
222
+ "cssValueProps": {
223
+ "type": "array",
224
+ "items": { "$ref": "#/$defs/cssValueProp" }
225
+ },
226
+ "boundaries": {
227
+ "type": "object",
228
+ "required": ["rootClass", "publicClasses", "publicTokens"],
229
+ "properties": {
230
+ "rootClass": {
231
+ "oneOf": [
232
+ { "type": "string", "minLength": 1 },
233
+ { "type": "null" }
234
+ ]
235
+ },
236
+ "publicClasses": { "$ref": "#/$defs/stringList" },
237
+ "publicTokens": { "$ref": "#/$defs/stringList" },
238
+ "publicParts": { "$ref": "#/$defs/stringList" }
239
+ },
240
+ "additionalProperties": false
241
+ },
242
+ "diagnostics": {
243
+ "type": "array",
244
+ "items": { "$ref": "#/$defs/diagnostic" }
245
+ },
246
+ "provenance": {
247
+ "type": "object",
248
+ "required": ["selection", "composition"],
249
+ "properties": {
250
+ "selection": { "type": "string", "minLength": 1 },
251
+ "composition": { "type": "string", "minLength": 1 }
252
+ },
253
+ "additionalProperties": false
254
+ }
255
+ },
256
+ "additionalProperties": false
257
+ },
258
+ "cssValueProp": {
259
+ "type": "object",
260
+ "required": [
261
+ "path",
262
+ "grammar",
263
+ "helpers",
264
+ "shorthands",
265
+ "canonicalShorthands",
266
+ "exceptionalShorthands",
267
+ "rawPolicy",
268
+ "examples"
269
+ ],
270
+ "properties": {
271
+ "path": {
272
+ "type": "string",
273
+ "pattern": "^[A-Za-z][A-Za-z0-9]*(?:\\[\\]\\.[A-Za-z][A-Za-z0-9]*)?$"
274
+ },
275
+ "grammar": {
276
+ "enum": [
277
+ "length",
278
+ "size",
279
+ "flex",
280
+ "color",
281
+ "declarations",
282
+ "media-query",
283
+ "pixels"
284
+ ]
285
+ },
286
+ "helpers": { "$ref": "#/$defs/stringList" },
287
+ "nonStandaloneHelpers": { "$ref": "#/$defs/stringList" },
288
+ "shorthands": { "$ref": "#/$defs/stringList" },
289
+ "canonicalShorthands": { "$ref": "#/$defs/stringList" },
290
+ "exceptionalShorthands": { "$ref": "#/$defs/stringList" },
291
+ "rawPolicy": { "enum": ["forbid", "allow", "unsafe-only"] },
292
+ "unsafeHelper": { "type": "string", "minLength": 1 },
293
+ "examples": { "$ref": "#/$defs/stringList" }
294
+ },
295
+ "additionalProperties": false
296
+ }
297
+ }
298
+ }
@@ -0,0 +1,229 @@
1
+ {
2
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
3
+ "$id": "https://raw.githubusercontent.com/brianwestphal/kerf/main/create-kerf-component/component-metadata.schema.json",
4
+ "title": "Kerf consumer component metadata source",
5
+ "type": "object",
6
+ "required": ["schemaVersion", "components"],
7
+ "properties": {
8
+ "$schema": { "type": "string" },
9
+ "schemaVersion": { "const": 1 },
10
+ "v1Catalog": { "type": "string", "minLength": 1 },
11
+ "components": {
12
+ "type": "array",
13
+ "items": { "$ref": "#/$defs/component" }
14
+ }
15
+ },
16
+ "additionalProperties": false,
17
+ "$defs": {
18
+ "stringList": {
19
+ "type": "array",
20
+ "items": { "type": "string", "minLength": 1 },
21
+ "uniqueItems": true
22
+ },
23
+ "cardinality": {
24
+ "type": "object",
25
+ "required": ["min", "max"],
26
+ "properties": {
27
+ "min": { "type": "integer", "minimum": 0 },
28
+ "max": {
29
+ "anyOf": [
30
+ { "type": "integer", "minimum": 1 },
31
+ { "const": "unbounded" }
32
+ ]
33
+ }
34
+ },
35
+ "additionalProperties": false
36
+ },
37
+ "diagnostic": {
38
+ "type": "object",
39
+ "required": ["id", "severity", "when", "message"],
40
+ "properties": {
41
+ "id": { "type": "string", "pattern": "^KUI-C[0-9]{3}$" },
42
+ "severity": { "enum": ["error", "warning"] },
43
+ "when": { "type": "string", "minLength": 1 },
44
+ "message": { "type": "string", "minLength": 1 }
45
+ },
46
+ "additionalProperties": false
47
+ },
48
+ "component": {
49
+ "type": "object",
50
+ "required": [
51
+ "id",
52
+ "name",
53
+ "kind",
54
+ "purpose",
55
+ "source",
56
+ "publicExports",
57
+ "sourceLinks",
58
+ "composition",
59
+ "boundaries",
60
+ "accessibility",
61
+ "diagnostics",
62
+ "provenance"
63
+ ],
64
+ "properties": {
65
+ "id": { "type": "string", "minLength": 1 },
66
+ "name": { "type": "string", "minLength": 1 },
67
+ "kind": { "enum": ["component", "composition", "recipe"] },
68
+ "purpose": { "type": "string", "minLength": 1 },
69
+ "source": { "type": "string", "minLength": 1 },
70
+ "publicExports": {
71
+ "type": "array",
72
+ "minItems": 1,
73
+ "items": {
74
+ "type": "object",
75
+ "required": ["name", "subpath"],
76
+ "properties": {
77
+ "name": { "type": "string", "minLength": 1 },
78
+ "subpath": { "type": "string", "pattern": "^\\." }
79
+ },
80
+ "additionalProperties": false
81
+ }
82
+ },
83
+ "sourceLinks": { "$ref": "#/$defs/stringList" },
84
+ "composition": { "$ref": "#/$defs/composition" },
85
+ "boundaries": {
86
+ "type": "object",
87
+ "required": ["rootClass", "publicClasses", "publicTokens"],
88
+ "properties": {
89
+ "rootClass": {
90
+ "oneOf": [
91
+ { "type": "string", "minLength": 1 },
92
+ { "type": "null" }
93
+ ]
94
+ },
95
+ "publicClasses": { "$ref": "#/$defs/stringList" },
96
+ "publicTokens": { "$ref": "#/$defs/stringList" }
97
+ },
98
+ "additionalProperties": false
99
+ },
100
+ "accessibility": {
101
+ "type": "object",
102
+ "required": ["obligations"],
103
+ "properties": { "obligations": { "$ref": "#/$defs/stringList" } },
104
+ "additionalProperties": false
105
+ },
106
+ "diagnostics": {
107
+ "type": "array",
108
+ "items": { "$ref": "#/$defs/diagnostic" }
109
+ },
110
+ "provenance": {
111
+ "type": "object",
112
+ "required": ["selection", "composition"],
113
+ "properties": {
114
+ "selection": { "type": "string", "minLength": 1 },
115
+ "composition": { "type": "string", "minLength": 1 }
116
+ },
117
+ "additionalProperties": false
118
+ }
119
+ },
120
+ "additionalProperties": false
121
+ },
122
+ "composition": {
123
+ "type": "object",
124
+ "required": [
125
+ "parents",
126
+ "contexts",
127
+ "zones",
128
+ "children",
129
+ "state",
130
+ "wiring",
131
+ "responsive",
132
+ "layout"
133
+ ],
134
+ "properties": {
135
+ "parents": {
136
+ "type": "object",
137
+ "required": ["mode", "entries"],
138
+ "properties": {
139
+ "mode": { "enum": ["any", "root", "listed"] },
140
+ "entries": { "$ref": "#/$defs/stringList" }
141
+ },
142
+ "additionalProperties": false
143
+ },
144
+ "contexts": { "$ref": "#/$defs/stringList" },
145
+ "zones": {
146
+ "type": "array",
147
+ "items": {
148
+ "type": "object",
149
+ "required": ["id", "accepts", "cardinality", "exclusiveWith"],
150
+ "properties": {
151
+ "id": { "type": "string", "minLength": 1 },
152
+ "accepts": { "$ref": "#/$defs/stringList" },
153
+ "cardinality": { "$ref": "#/$defs/cardinality" },
154
+ "exclusiveWith": { "$ref": "#/$defs/stringList" }
155
+ },
156
+ "additionalProperties": false
157
+ }
158
+ },
159
+ "children": {
160
+ "type": "object",
161
+ "required": ["mode", "concepts", "requiredConcepts"],
162
+ "properties": {
163
+ "mode": { "enum": ["any", "none", "listed"] },
164
+ "concepts": { "$ref": "#/$defs/stringList" },
165
+ "requiredConcepts": { "$ref": "#/$defs/stringList" }
166
+ },
167
+ "additionalProperties": false
168
+ },
169
+ "state": {
170
+ "type": "array",
171
+ "items": {
172
+ "type": "object",
173
+ "required": ["id", "owner", "required"],
174
+ "properties": {
175
+ "id": { "type": "string", "minLength": 1 },
176
+ "owner": { "enum": ["application", "controlled", "component"] },
177
+ "required": { "type": "boolean" }
178
+ },
179
+ "additionalProperties": false
180
+ }
181
+ },
182
+ "wiring": {
183
+ "type": "object",
184
+ "required": ["required", "helpers", "obligations"],
185
+ "properties": {
186
+ "required": { "type": "boolean" },
187
+ "helpers": { "$ref": "#/$defs/stringList" },
188
+ "obligations": { "$ref": "#/$defs/stringList" }
189
+ },
190
+ "additionalProperties": false
191
+ },
192
+ "responsive": {
193
+ "type": "object",
194
+ "required": ["owner", "behaviors"],
195
+ "properties": {
196
+ "owner": {
197
+ "enum": ["application", "component", "shared", "not-applicable"]
198
+ },
199
+ "behaviors": { "$ref": "#/$defs/stringList" }
200
+ },
201
+ "additionalProperties": false
202
+ },
203
+ "layout": {
204
+ "type": "object",
205
+ "required": ["roles", "geometry"],
206
+ "properties": {
207
+ "roles": { "$ref": "#/$defs/stringList" },
208
+ "geometry": {
209
+ "type": "object",
210
+ "required": ["margin", "border", "padding"],
211
+ "properties": {
212
+ "margin": { "$ref": "#/$defs/geometryOwner" },
213
+ "border": { "$ref": "#/$defs/geometryOwner" },
214
+ "padding": { "$ref": "#/$defs/geometryOwner" },
215
+ "notes": { "$ref": "#/$defs/stringList" }
216
+ },
217
+ "additionalProperties": false
218
+ }
219
+ },
220
+ "additionalProperties": false
221
+ }
222
+ },
223
+ "additionalProperties": false
224
+ },
225
+ "geometryOwner": {
226
+ "enum": ["self", "parent", "child", "none", "conditional", "composed"]
227
+ }
228
+ }
229
+ }
package/index.js CHANGED
@@ -17,8 +17,18 @@
17
17
  // kerf-component` alone just works. No third-party dependencies — the
18
18
  // initializer is plain Node so `npm create` runs it with zero install latency.
19
19
 
20
- import { cpSync, existsSync, mkdirSync, readdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
20
+ import {
21
+ copyFileSync,
22
+ cpSync,
23
+ existsSync,
24
+ mkdirSync,
25
+ readdirSync,
26
+ readFileSync,
27
+ renameSync,
28
+ writeFileSync,
29
+ } from 'node:fs';
21
30
  import { basename, dirname, join, resolve } from 'node:path';
31
+ import process from 'node:process';
22
32
  import { createInterface } from 'node:readline/promises';
23
33
  import { fileURLToPath } from 'node:url';
24
34
 
@@ -41,7 +51,9 @@ const USAGE =
41
51
  async function promptForTarget() {
42
52
  const rl = createInterface({ input: process.stdin, output: process.stdout });
43
53
  try {
44
- const answer = await rl.question(`Directory (\`.\` for current) [${DEFAULT_NAME}]: `);
54
+ const answer = await rl.question(
55
+ `Directory (\`.\` for current) [${DEFAULT_NAME}]: `,
56
+ );
45
57
  return answer.trim() || DEFAULT_NAME;
46
58
  } finally {
47
59
  rl.close();
@@ -117,6 +129,19 @@ async function main(argv) {
117
129
  // verbatim (`_gitignore` → `.gitignore`).
118
130
  mkdirSync(targetDir, { recursive: true });
119
131
  cpSync(TEMPLATE_DIR, targetDir, { recursive: true });
132
+ mkdirSync(join(targetDir, 'scripts'), { recursive: true });
133
+ copyFileSync(
134
+ join(dirname(fileURLToPath(import.meta.url)), 'catalog.js'),
135
+ join(targetDir, 'scripts', 'kerf-component-catalog.mjs'),
136
+ );
137
+ for (const schema of [
138
+ 'component-metadata.schema.json',
139
+ 'component-catalog-v2.schema.json',
140
+ ])
141
+ copyFileSync(
142
+ join(dirname(fileURLToPath(import.meta.url)), schema),
143
+ join(targetDir, 'scripts', schema),
144
+ );
120
145
 
121
146
  for (const file of walk(targetDir)) {
122
147
  const text = readFileSync(file, 'utf8');
@@ -136,8 +161,9 @@ async function main(argv) {
136
161
  cdHint +
137
162
  ' npm install\n' +
138
163
  ' npm run build # tsup → ESM + .d.ts (kerfjs stays external)\n' +
164
+ ' npm run catalog:check # verify AI metadata and public exports\n' +
139
165
  ' npm run typecheck\n\n' +
140
- 'Edit src/counter.tsx, then publish with `npm publish --access public`.\n',
166
+ 'Edit src/counter.tsx and kerf.components.json, then publish with `npm publish --access public`.\n',
141
167
  );
142
168
  }
143
169
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kerf-component",
3
- "version": "5.0.0-beta.5",
3
+ "version": "5.0.0-beta.50",
4
4
  "description": "Scaffold a publishable kerf component package that already follows kerf's hard packaging rules.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -26,15 +26,22 @@
26
26
  "node": ">=18.0.0"
27
27
  },
28
28
  "bin": {
29
- "create-kerf-component": "index.js"
29
+ "create-kerf-component": "index.js",
30
+ "kerf-component-catalog": "catalog.js"
30
31
  },
31
32
  "files": [
32
33
  "index.js",
34
+ "catalog.js",
35
+ "component-metadata.schema.json",
36
+ "component-catalog-v2.schema.json",
33
37
  "template",
34
38
  "README.md",
35
39
  "LICENSE"
36
40
  ],
37
41
  "scripts": {
38
42
  "test": "node --test tests/*.test.js"
43
+ },
44
+ "dependencies": {
45
+ "typescript": "^5.0.0 || ^6.0.0"
39
46
  }
40
47
  }