siteplane 0.1.48 → 0.1.49

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 CHANGED
@@ -43,6 +43,10 @@ For a direct field ID, put `siteplane.attrs(fieldId, { routeKey })` on the visib
43
43
  element using the same canonical route pattern as its value call. The value call
44
44
  does not attach DOM metadata. Missing or mismatched DOM routes block apply and
45
45
  the Next build; dynamic pages use their pattern, such as `/services/[slug]`.
46
+ Direct attrs defaults to `fieldType: "text"`; for longText, link and image,
47
+ pass the matching `fieldType` explicitly. The value call does not infer it for attrs.
48
+ `setup apply` reports `field_scan.attrs_field_type_mismatch` before any contract write.
49
+ This type diagnostic remains a scanner warning for normal website builds.
46
50
 
47
51
  ```bash
48
52
  siteplane setup apply --definition editor-definition.json --selection-summary-file selection.txt
@@ -4337,6 +4337,14 @@ function scanSourceFacts(files) {
4337
4337
  }
4338
4338
  for (const attr of directAttrs) {
4339
4339
  const field = fields.find((candidate) => candidate.fieldId === attr.fieldId);
4340
+ if (field && attr.fieldType !== field.fieldType) {
4341
+ warnings.push({
4342
+ code: "field_scan.attrs_field_type_mismatch",
4343
+ message: `DOM attrs for ${attr.fieldId} declare ${attr.fieldType}, but its value call returns ${field.fieldType}. Pass fieldType: "${field.fieldType}" with the matching routeKey to siteplane.attrs on the visible element. This affects editor preview, not the website build.`,
4344
+ fieldId: attr.fieldId,
4345
+ filePath: attr.filePath
4346
+ });
4347
+ }
4340
4348
  const expectedRoute = field?.technicalRouteKey ?? field?.routeHint;
4341
4349
  if (!attr.routeKey || expectedRoute && attr.routeKey !== expectedRoute) {
4342
4350
  hardErrors.push({
@@ -4618,6 +4626,7 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
4618
4626
  directAttrs.push({
4619
4627
  fieldId: directFieldId,
4620
4628
  routeKey: secondArg && typeof secondArg === "object" && "routeKey" in secondArg ? stringValue2(secondArg.routeKey) : void 0,
4629
+ fieldType: secondArg && typeof secondArg === "object" && "fieldType" in secondArg ? stringValue2(secondArg.fieldType) ?? "text" : "text",
4621
4630
  filePath: file.filePath
4622
4631
  });
4623
4632
  if (hasEventPreviewStrategy(secondArg)) {
@@ -4979,6 +4988,14 @@ async function siteSetupApplyCommand(input) {
4979
4988
  sourceText: await readSourceFile(filePath)
4980
4989
  })));
4981
4990
  const scan = scanSourceFiles(files, { projectRoot: input.projectDir });
4991
+ const invalidDomTypes = scan.warnings.filter((issue) => issue.code === "field_scan.attrs_field_type_mismatch");
4992
+ if (invalidDomTypes.length > 0) {
4993
+ return {
4994
+ status: "action_required",
4995
+ code: "field_scan.attrs_field_type_mismatch",
4996
+ message: invalidDomTypes.map((issue) => issue.message).join("\n")
4997
+ };
4998
+ }
4982
4999
  if (scan.hardErrors.length > 0) {
4983
5000
  return {
4984
5001
  status: "action_required",
package/dist/next.js CHANGED
@@ -3082,6 +3082,14 @@ function scanSourceFacts(files) {
3082
3082
  }
3083
3083
  for (const attr of directAttrs) {
3084
3084
  const field = fields.find((candidate) => candidate.fieldId === attr.fieldId);
3085
+ if (field && attr.fieldType !== field.fieldType) {
3086
+ warnings.push({
3087
+ code: "field_scan.attrs_field_type_mismatch",
3088
+ message: `DOM attrs for ${attr.fieldId} declare ${attr.fieldType}, but its value call returns ${field.fieldType}. Pass fieldType: "${field.fieldType}" with the matching routeKey to siteplane.attrs on the visible element. This affects editor preview, not the website build.`,
3089
+ fieldId: attr.fieldId,
3090
+ filePath: attr.filePath
3091
+ });
3092
+ }
3085
3093
  const expectedRoute = field?.technicalRouteKey ?? field?.routeHint;
3086
3094
  if (!attr.routeKey || expectedRoute && attr.routeKey !== expectedRoute) {
3087
3095
  hardErrors.push({
@@ -3363,6 +3371,7 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
3363
3371
  directAttrs.push({
3364
3372
  fieldId: directFieldId,
3365
3373
  routeKey: secondArg && typeof secondArg === "object" && "routeKey" in secondArg ? stringValue(secondArg.routeKey) : void 0,
3374
+ fieldType: secondArg && typeof secondArg === "object" && "fieldType" in secondArg ? stringValue(secondArg.fieldType) ?? "text" : "text",
3366
3375
  filePath: file.filePath
3367
3376
  });
3368
3377
  if (hasEventPreviewStrategy(secondArg)) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "siteplane",
3
3
  "private": false,
4
- "version": "0.1.48",
4
+ "version": "0.1.49",
5
5
  "type": "module",
6
6
  "license": "SEE LICENSE IN LICENSE",
7
7
  "publishConfig": {