@jay-framework/jay-stack-cli 0.15.3 → 0.15.5
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/agent-kit-template/contracts-and-plugins.md +1 -0
- package/dist/index.js +127 -1
- package/package.json +10 -10
|
@@ -244,6 +244,7 @@ Schemas use a compact type notation:
|
|
|
244
244
|
| `propName: enum(a \| b \| c)` | Required enum |
|
|
245
245
|
| `propName:` + nested block | Nested object |
|
|
246
246
|
| `propName:` + `- childProp: type` | Array of objects (YAML list) |
|
|
247
|
+
| `propName: record(T)` | Record with typed values (e.g., `record(boolean)`) |
|
|
247
248
|
| `propName: importedName` | Type from `import:` block (references a `.jay-contract`) |
|
|
248
249
|
| `- importedName` | Array of imported type |
|
|
249
250
|
|
package/dist/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import path from "path";
|
|
|
8
8
|
import fs, { promises } from "fs";
|
|
9
9
|
import YAML from "yaml";
|
|
10
10
|
import { getLogger, createDevLogger, setDevLogger } from "@jay-framework/logger";
|
|
11
|
-
import { parseJayFile, JAY_IMPORT_RESOLVER, generateElementDefinitionFile, ContractTagType, parseContract, generateElementFile } from "@jay-framework/compiler-jay-html";
|
|
11
|
+
import { parseJayFile, JAY_IMPORT_RESOLVER, generateElementDefinitionFile, ContractTagType, parseContract, generateElementFile, htmlElementTagNameMap } from "@jay-framework/compiler-jay-html";
|
|
12
12
|
import { JAY_CONTRACT_EXTENSION, JAY_EXTENSION, resolvePluginManifest, LOCAL_PLUGIN_PATH, JayAtomicType, JayEnumType, loadPluginManifest, RuntimeMode, GenerateTarget } from "@jay-framework/compiler-shared";
|
|
13
13
|
import { listContracts, materializeContracts } from "@jay-framework/stack-server-runtime";
|
|
14
14
|
import { listContracts as listContracts2, materializeContracts as materializeContracts2 } from "@jay-framework/stack-server-runtime";
|
|
@@ -3129,6 +3129,128 @@ function analyzeTagCoverage(jayHtml, file) {
|
|
|
3129
3129
|
}
|
|
3130
3130
|
return { file, contracts };
|
|
3131
3131
|
}
|
|
3132
|
+
const htmlTagNameMap = htmlElementTagNameMap;
|
|
3133
|
+
function resolveContractTag(contract, tagPath) {
|
|
3134
|
+
const segments = tagPath.split(".");
|
|
3135
|
+
let tags = contract.tags;
|
|
3136
|
+
for (let i = 0; i < segments.length; i++) {
|
|
3137
|
+
const tag = tags.find((t) => t.tag === segments[i]);
|
|
3138
|
+
if (!tag)
|
|
3139
|
+
return void 0;
|
|
3140
|
+
if (i === segments.length - 1)
|
|
3141
|
+
return tag;
|
|
3142
|
+
if (!tag.tags)
|
|
3143
|
+
return void 0;
|
|
3144
|
+
tags = tag.tags;
|
|
3145
|
+
}
|
|
3146
|
+
return void 0;
|
|
3147
|
+
}
|
|
3148
|
+
function checkRefElementTypes(jayHtml, file) {
|
|
3149
|
+
const imports = jayHtml.headlessImports;
|
|
3150
|
+
const keyMap = /* @__PURE__ */ new Map();
|
|
3151
|
+
for (let i = 0; i < imports.length; i++) {
|
|
3152
|
+
if (imports[i].key) {
|
|
3153
|
+
keyMap.set(imports[i].key, i);
|
|
3154
|
+
}
|
|
3155
|
+
}
|
|
3156
|
+
const warnings = [];
|
|
3157
|
+
function checkRef(ref, scopes) {
|
|
3158
|
+
const refPath = ref.refPath;
|
|
3159
|
+
const dot = refPath.indexOf(".");
|
|
3160
|
+
let importIndex;
|
|
3161
|
+
let tagPath;
|
|
3162
|
+
if (dot !== -1) {
|
|
3163
|
+
const key = refPath.substring(0, dot);
|
|
3164
|
+
const idx = keyMap.get(key);
|
|
3165
|
+
if (idx !== void 0) {
|
|
3166
|
+
importIndex = idx;
|
|
3167
|
+
tagPath = refPath.substring(dot + 1);
|
|
3168
|
+
}
|
|
3169
|
+
}
|
|
3170
|
+
if (importIndex === void 0 && scopes.length > 0) {
|
|
3171
|
+
const scope = scopes[scopes.length - 1];
|
|
3172
|
+
importIndex = scope.importIndex;
|
|
3173
|
+
tagPath = scope.prefix ? `${scope.prefix}.${refPath}` : refPath;
|
|
3174
|
+
}
|
|
3175
|
+
if (importIndex === void 0)
|
|
3176
|
+
return;
|
|
3177
|
+
const imp = imports[importIndex];
|
|
3178
|
+
if (!imp.contract)
|
|
3179
|
+
return;
|
|
3180
|
+
const contractTag = resolveContractTag(imp.contract, tagPath);
|
|
3181
|
+
if (!contractTag || !contractTag.elementType)
|
|
3182
|
+
return;
|
|
3183
|
+
const contractTypes = contractTag.elementType;
|
|
3184
|
+
if (contractTypes.includes("HTMLElement"))
|
|
3185
|
+
return;
|
|
3186
|
+
if (!contractTypes.includes(ref.actualType)) {
|
|
3187
|
+
const label = imp.key ? `${imp.key}.${tagPath}` : tagPath;
|
|
3188
|
+
warnings.push(
|
|
3189
|
+
`Ref "${label}" is on a <${ref.htmlTag}> (${ref.actualType}) but the contract declares ${contractTypes.join(" | ")}`
|
|
3190
|
+
);
|
|
3191
|
+
}
|
|
3192
|
+
}
|
|
3193
|
+
function walkElement(element, scopes) {
|
|
3194
|
+
const tagName = element.rawTagName?.toLowerCase();
|
|
3195
|
+
let childScopes = scopes;
|
|
3196
|
+
if (tagName?.startsWith("jay:")) {
|
|
3197
|
+
const contractName = tagName.substring(4);
|
|
3198
|
+
const idx = imports.findIndex(
|
|
3199
|
+
(imp) => imp.contractName === contractName && imp.contract
|
|
3200
|
+
);
|
|
3201
|
+
if (idx !== -1) {
|
|
3202
|
+
childScopes = [...scopes, { importIndex: idx, prefix: "" }];
|
|
3203
|
+
}
|
|
3204
|
+
}
|
|
3205
|
+
const forEachVal = element.getAttribute?.("forEach");
|
|
3206
|
+
if (forEachVal) {
|
|
3207
|
+
const fePath = extractTagPath(forEachVal);
|
|
3208
|
+
if (fePath) {
|
|
3209
|
+
const dot = fePath.indexOf(".");
|
|
3210
|
+
if (dot !== -1) {
|
|
3211
|
+
const key = fePath.substring(0, dot);
|
|
3212
|
+
const idx = keyMap.get(key);
|
|
3213
|
+
if (idx !== void 0) {
|
|
3214
|
+
childScopes = [
|
|
3215
|
+
...childScopes,
|
|
3216
|
+
{ importIndex: idx, prefix: fePath.substring(dot + 1) }
|
|
3217
|
+
];
|
|
3218
|
+
}
|
|
3219
|
+
} else if (childScopes.length > 0) {
|
|
3220
|
+
const scope = childScopes[childScopes.length - 1];
|
|
3221
|
+
const newPrefix = scope.prefix ? `${scope.prefix}.${fePath}` : fePath;
|
|
3222
|
+
childScopes = [
|
|
3223
|
+
...childScopes,
|
|
3224
|
+
{ importIndex: scope.importIndex, prefix: newPrefix }
|
|
3225
|
+
];
|
|
3226
|
+
}
|
|
3227
|
+
}
|
|
3228
|
+
}
|
|
3229
|
+
if (tagName === "with-data") {
|
|
3230
|
+
const accessor = element.getAttribute?.("accessor");
|
|
3231
|
+
if (accessor && accessor !== "." && childScopes.length > 0) {
|
|
3232
|
+
const scope = childScopes[childScopes.length - 1];
|
|
3233
|
+
const newPrefix = scope.prefix ? `${scope.prefix}.${accessor}` : accessor;
|
|
3234
|
+
childScopes = [
|
|
3235
|
+
...childScopes,
|
|
3236
|
+
{ importIndex: scope.importIndex, prefix: newPrefix }
|
|
3237
|
+
];
|
|
3238
|
+
}
|
|
3239
|
+
}
|
|
3240
|
+
const refVal = element.getAttribute?.("ref");
|
|
3241
|
+
if (refVal && tagName) {
|
|
3242
|
+
const actualType = htmlTagNameMap[tagName] ?? "HTMLElement";
|
|
3243
|
+
checkRef({ refPath: refVal, htmlTag: tagName, actualType }, childScopes);
|
|
3244
|
+
}
|
|
3245
|
+
for (const child of element.childNodes ?? []) {
|
|
3246
|
+
if (child.nodeType === 1) {
|
|
3247
|
+
walkElement(child, childScopes);
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3250
|
+
}
|
|
3251
|
+
walkElement(jayHtml.body, []);
|
|
3252
|
+
return warnings;
|
|
3253
|
+
}
|
|
3132
3254
|
const PARSE_PARAM = /^\[(\[)?(\.\.\.)?([^\]]+)\]?\]$/;
|
|
3133
3255
|
function extractRouteParams(filePath, pagesBase) {
|
|
3134
3256
|
const relative = path.relative(pagesBase, filePath);
|
|
@@ -3282,6 +3404,10 @@ async function validateJayFiles(options = {}) {
|
|
|
3282
3404
|
for (const msg of routeParamWarnings) {
|
|
3283
3405
|
warnings.push({ file: relativePath, message: msg });
|
|
3284
3406
|
}
|
|
3407
|
+
const refTypeErrors = checkRefElementTypes(parsedFile.val, relativePath);
|
|
3408
|
+
for (const msg of refTypeErrors) {
|
|
3409
|
+
errors.push({ file: relativePath, message: msg, stage: "generate" });
|
|
3410
|
+
}
|
|
3285
3411
|
const fileCoverage = analyzeTagCoverage(parsedFile.val, relativePath);
|
|
3286
3412
|
if (fileCoverage) {
|
|
3287
3413
|
coverage.push(fileCoverage);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jay-framework/jay-stack-cli",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.5",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -24,14 +24,14 @@
|
|
|
24
24
|
"test:watch": "vitest"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@jay-framework/compiler-jay-html": "^0.15.
|
|
28
|
-
"@jay-framework/compiler-shared": "^0.15.
|
|
29
|
-
"@jay-framework/dev-server": "^0.15.
|
|
30
|
-
"@jay-framework/editor-server": "^0.15.
|
|
31
|
-
"@jay-framework/fullstack-component": "^0.15.
|
|
32
|
-
"@jay-framework/logger": "^0.15.
|
|
33
|
-
"@jay-framework/plugin-validator": "^0.15.
|
|
34
|
-
"@jay-framework/stack-server-runtime": "^0.15.
|
|
27
|
+
"@jay-framework/compiler-jay-html": "^0.15.5",
|
|
28
|
+
"@jay-framework/compiler-shared": "^0.15.5",
|
|
29
|
+
"@jay-framework/dev-server": "^0.15.5",
|
|
30
|
+
"@jay-framework/editor-server": "^0.15.5",
|
|
31
|
+
"@jay-framework/fullstack-component": "^0.15.5",
|
|
32
|
+
"@jay-framework/logger": "^0.15.5",
|
|
33
|
+
"@jay-framework/plugin-validator": "^0.15.5",
|
|
34
|
+
"@jay-framework/stack-server-runtime": "^0.15.5",
|
|
35
35
|
"chalk": "^4.1.2",
|
|
36
36
|
"commander": "^14.0.0",
|
|
37
37
|
"express": "^5.0.1",
|
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
"yaml": "^2.3.4"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
-
"@jay-framework/dev-environment": "^0.15.
|
|
45
|
+
"@jay-framework/dev-environment": "^0.15.5",
|
|
46
46
|
"@types/express": "^5.0.2",
|
|
47
47
|
"@types/node": "^22.15.21",
|
|
48
48
|
"nodemon": "^3.0.3",
|