@formfeed/devkit 0.3.12 → 0.3.13
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/index.cjs +62 -3
- package/index.js +67 -2
- package/package.json +3 -3
- package/types/index.d.cts +2 -0
- package/types/index.d.ts +2 -0
- package/types/lib/accessibility.d.cts +21 -0
- package/types/lib/accessibility.d.ts +21 -0
package/index.cjs
CHANGED
|
@@ -31,6 +31,7 @@ __export(index_exports, {
|
|
|
31
31
|
defaultProjectConfig: () => defaultProjectConfig,
|
|
32
32
|
defaultTypesFile: () => defaultTypesFile,
|
|
33
33
|
diagnose: () => diagnose,
|
|
34
|
+
diagnoseAccessibility: () => diagnoseAccessibility,
|
|
34
35
|
diagnoseEinvoice: () => diagnoseEinvoice,
|
|
35
36
|
findProject: () => findProject,
|
|
36
37
|
generateTypes: () => generateTypes,
|
|
@@ -809,7 +810,8 @@ function previewDocument(tpl, rendered, mode, pagedScriptUrl) {
|
|
|
809
810
|
settings: rendered.settings,
|
|
810
811
|
kind
|
|
811
812
|
};
|
|
812
|
-
|
|
813
|
+
const audit = kind === "pdf" && (0, import_engine4.resolveUa)(rendered.settings.pdf?.ua) !== null;
|
|
814
|
+
return mode === "paged" && kind === "pdf" ? (0, import_engine4.pagedDocument)(draft, { pagedScriptUrl, audit }) : (0, import_engine4.flowDocument)(draft, { audit });
|
|
813
815
|
}
|
|
814
816
|
|
|
815
817
|
// packages/devkit/src/lib/einvoice.ts
|
|
@@ -905,6 +907,62 @@ function localEinvoiceXml(tpl, data, override) {
|
|
|
905
907
|
return { xml: result.xml, invoice: result.invoice, options };
|
|
906
908
|
}
|
|
907
909
|
|
|
910
|
+
// packages/devkit/src/lib/accessibility.ts
|
|
911
|
+
var import_engine6 = require("@formfeed/engine");
|
|
912
|
+
var nowhere3 = { start: { line: 1, column: 1 }, end: { line: 1, column: 1 } };
|
|
913
|
+
var about = (severity, code, message) => ({
|
|
914
|
+
file: "settings.json",
|
|
915
|
+
diagnostics: [{ severity, code, message, range: nowhere3 }]
|
|
916
|
+
});
|
|
917
|
+
function diagnoseAccessibility(tpl) {
|
|
918
|
+
const declared = tpl.settings.pdf?.ua;
|
|
919
|
+
if (declared !== void 0 && !(0, import_engine6.isUaSetting)(declared))
|
|
920
|
+
return [
|
|
921
|
+
about(
|
|
922
|
+
"error",
|
|
923
|
+
"accessibility-setting",
|
|
924
|
+
'pdf.ua is true, false or { "check": "strict" | "report" }'
|
|
925
|
+
)
|
|
926
|
+
];
|
|
927
|
+
const ua = (0, import_engine6.resolveUa)(declared);
|
|
928
|
+
if (!ua) return [];
|
|
929
|
+
if (tpl.meta.kind === "image")
|
|
930
|
+
return [
|
|
931
|
+
about(
|
|
932
|
+
"warning",
|
|
933
|
+
"accessibility-image",
|
|
934
|
+
"settings.json declares pdf.ua, which an image template never produces: PDF/UA is a format of PDF"
|
|
935
|
+
)
|
|
936
|
+
];
|
|
937
|
+
if ((0, import_engine6.isOfficeKind)(tpl.meta.kind))
|
|
938
|
+
return [about("error", "accessibility-office", import_engine6.UA_REFUSALS.office)];
|
|
939
|
+
const out = [];
|
|
940
|
+
const body = [];
|
|
941
|
+
for (const found of (0, import_engine6.staticAuditDiagnostics)(
|
|
942
|
+
{
|
|
943
|
+
engine: tpl.meta.engine,
|
|
944
|
+
html: tpl.html,
|
|
945
|
+
head: tpl.head,
|
|
946
|
+
title: tpl.settings.pdf?.metadata?.title
|
|
947
|
+
},
|
|
948
|
+
ua
|
|
949
|
+
)) {
|
|
950
|
+
if (!found.location) {
|
|
951
|
+
out.push(about(found.severity, found.code, found.message));
|
|
952
|
+
continue;
|
|
953
|
+
}
|
|
954
|
+
body.push({
|
|
955
|
+
severity: found.severity,
|
|
956
|
+
code: found.code,
|
|
957
|
+
message: found.message,
|
|
958
|
+
range: { start: found.location, end: found.location }
|
|
959
|
+
});
|
|
960
|
+
}
|
|
961
|
+
if (body.length)
|
|
962
|
+
out.push({ file: templateFileName(tpl.meta.kind), diagnostics: body });
|
|
963
|
+
return out;
|
|
964
|
+
}
|
|
965
|
+
|
|
908
966
|
// packages/devkit/src/lib/files.ts
|
|
909
967
|
var import_node_crypto2 = require("node:crypto");
|
|
910
968
|
var import_node_fs5 = require("node:fs");
|
|
@@ -1043,7 +1101,7 @@ function isRecord(value) {
|
|
|
1043
1101
|
}
|
|
1044
1102
|
|
|
1045
1103
|
// packages/devkit/src/lib/types/index.ts
|
|
1046
|
-
var
|
|
1104
|
+
var import_engine7 = require("@formfeed/engine");
|
|
1047
1105
|
|
|
1048
1106
|
// packages/devkit/src/lib/types/model.ts
|
|
1049
1107
|
var isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -1531,7 +1589,7 @@ function localTypeSource(tpl) {
|
|
|
1531
1589
|
const sets = Object.values(tpl.dataSets);
|
|
1532
1590
|
return {
|
|
1533
1591
|
slug: tpl.slug,
|
|
1534
|
-
schema: (0,
|
|
1592
|
+
schema: (0, import_engine7.inferSchemaFromDataSets)(sets.length ? sets : [{}]),
|
|
1535
1593
|
origin: "inferred"
|
|
1536
1594
|
};
|
|
1537
1595
|
}
|
|
@@ -1548,6 +1606,7 @@ function localTypeSource(tpl) {
|
|
|
1548
1606
|
defaultProjectConfig,
|
|
1549
1607
|
defaultTypesFile,
|
|
1550
1608
|
diagnose,
|
|
1609
|
+
diagnoseAccessibility,
|
|
1551
1610
|
diagnoseEinvoice,
|
|
1552
1611
|
findProject,
|
|
1553
1612
|
generateTypes,
|
package/index.js
CHANGED
|
@@ -543,7 +543,8 @@ import {
|
|
|
543
543
|
pagedDocument,
|
|
544
544
|
parseDesign,
|
|
545
545
|
renderOffice,
|
|
546
|
-
renderVersion
|
|
546
|
+
renderVersion,
|
|
547
|
+
resolveUa
|
|
547
548
|
} from "@formfeed/engine";
|
|
548
549
|
function diagnose(tpl, sampleData) {
|
|
549
550
|
if (tpl.file) return diagnoseOffice(tpl, tpl.file.bytes, sampleData);
|
|
@@ -757,7 +758,8 @@ function previewDocument(tpl, rendered, mode, pagedScriptUrl) {
|
|
|
757
758
|
settings: rendered.settings,
|
|
758
759
|
kind
|
|
759
760
|
};
|
|
760
|
-
|
|
761
|
+
const audit = kind === "pdf" && resolveUa(rendered.settings.pdf?.ua) !== null;
|
|
762
|
+
return mode === "paged" && kind === "pdf" ? pagedDocument(draft, { pagedScriptUrl, audit }) : flowDocument(draft, { audit });
|
|
761
763
|
}
|
|
762
764
|
|
|
763
765
|
// packages/devkit/src/lib/einvoice.ts
|
|
@@ -859,6 +861,68 @@ function localEinvoiceXml(tpl, data, override) {
|
|
|
859
861
|
return { xml: result.xml, invoice: result.invoice, options };
|
|
860
862
|
}
|
|
861
863
|
|
|
864
|
+
// packages/devkit/src/lib/accessibility.ts
|
|
865
|
+
import {
|
|
866
|
+
UA_REFUSALS,
|
|
867
|
+
isOfficeKind as isOfficeKind3,
|
|
868
|
+
isUaSetting,
|
|
869
|
+
resolveUa as resolveUa2,
|
|
870
|
+
staticAuditDiagnostics
|
|
871
|
+
} from "@formfeed/engine";
|
|
872
|
+
var nowhere3 = { start: { line: 1, column: 1 }, end: { line: 1, column: 1 } };
|
|
873
|
+
var about = (severity, code, message) => ({
|
|
874
|
+
file: "settings.json",
|
|
875
|
+
diagnostics: [{ severity, code, message, range: nowhere3 }]
|
|
876
|
+
});
|
|
877
|
+
function diagnoseAccessibility(tpl) {
|
|
878
|
+
const declared = tpl.settings.pdf?.ua;
|
|
879
|
+
if (declared !== void 0 && !isUaSetting(declared))
|
|
880
|
+
return [
|
|
881
|
+
about(
|
|
882
|
+
"error",
|
|
883
|
+
"accessibility-setting",
|
|
884
|
+
'pdf.ua is true, false or { "check": "strict" | "report" }'
|
|
885
|
+
)
|
|
886
|
+
];
|
|
887
|
+
const ua = resolveUa2(declared);
|
|
888
|
+
if (!ua) return [];
|
|
889
|
+
if (tpl.meta.kind === "image")
|
|
890
|
+
return [
|
|
891
|
+
about(
|
|
892
|
+
"warning",
|
|
893
|
+
"accessibility-image",
|
|
894
|
+
"settings.json declares pdf.ua, which an image template never produces: PDF/UA is a format of PDF"
|
|
895
|
+
)
|
|
896
|
+
];
|
|
897
|
+
if (isOfficeKind3(tpl.meta.kind))
|
|
898
|
+
return [about("error", "accessibility-office", UA_REFUSALS.office)];
|
|
899
|
+
const out = [];
|
|
900
|
+
const body = [];
|
|
901
|
+
for (const found of staticAuditDiagnostics(
|
|
902
|
+
{
|
|
903
|
+
engine: tpl.meta.engine,
|
|
904
|
+
html: tpl.html,
|
|
905
|
+
head: tpl.head,
|
|
906
|
+
title: tpl.settings.pdf?.metadata?.title
|
|
907
|
+
},
|
|
908
|
+
ua
|
|
909
|
+
)) {
|
|
910
|
+
if (!found.location) {
|
|
911
|
+
out.push(about(found.severity, found.code, found.message));
|
|
912
|
+
continue;
|
|
913
|
+
}
|
|
914
|
+
body.push({
|
|
915
|
+
severity: found.severity,
|
|
916
|
+
code: found.code,
|
|
917
|
+
message: found.message,
|
|
918
|
+
range: { start: found.location, end: found.location }
|
|
919
|
+
});
|
|
920
|
+
}
|
|
921
|
+
if (body.length)
|
|
922
|
+
out.push({ file: templateFileName(tpl.meta.kind), diagnostics: body });
|
|
923
|
+
return out;
|
|
924
|
+
}
|
|
925
|
+
|
|
862
926
|
// packages/devkit/src/lib/files.ts
|
|
863
927
|
import { createHash as createHash2 } from "node:crypto";
|
|
864
928
|
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readdirSync as readdirSync2, readFileSync as readFileSync5, statSync as statSync2, writeFileSync as writeFileSync4 } from "node:fs";
|
|
@@ -1501,6 +1565,7 @@ export {
|
|
|
1501
1565
|
defaultProjectConfig,
|
|
1502
1566
|
defaultTypesFile,
|
|
1503
1567
|
diagnose,
|
|
1568
|
+
diagnoseAccessibility,
|
|
1504
1569
|
diagnoseEinvoice,
|
|
1505
1570
|
findProject,
|
|
1506
1571
|
generateTypes,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@formfeed/devkit",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.13",
|
|
4
4
|
"description": "Formfeed template folders, project config and local rendering, shared by the CLI and @formfeed/testing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
],
|
|
31
31
|
"sideEffects": false,
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@formfeed/engine": "0.3.
|
|
34
|
-
"@formfeed/sdk": "0.3.
|
|
33
|
+
"@formfeed/engine": "0.3.13",
|
|
34
|
+
"@formfeed/sdk": "0.3.13"
|
|
35
35
|
},
|
|
36
36
|
"keywords": [
|
|
37
37
|
"formfeed",
|
package/types/index.d.cts
CHANGED
|
@@ -10,6 +10,8 @@ export { diagnose, htmlSnapshot, officeSnapshot, prettyXml, previewDocument, ren
|
|
|
10
10
|
export type { LocalDiagnostic, OfficeLocalOptions } from './lib/local-render.cjs';
|
|
11
11
|
export { declaredEinvoice, diagnoseEinvoice, localEinvoiceXml, } from './lib/einvoice.cjs';
|
|
12
12
|
export type { DataSetDiagnostics } from './lib/einvoice.cjs';
|
|
13
|
+
export { diagnoseAccessibility } from './lib/accessibility.cjs';
|
|
14
|
+
export type { FileDiagnostics } from './lib/accessibility.cjs';
|
|
13
15
|
export { contentTypeFor, listLocalFiles, localFilePath, sha256File, writeLocalFile, } from './lib/files.cjs';
|
|
14
16
|
export type { LocalFile, LocalFileListing } from './lib/files.cjs';
|
|
15
17
|
export type { LocalRenderOptions } from './lib/local-render.cjs';
|
package/types/index.d.ts
CHANGED
|
@@ -10,6 +10,8 @@ export { diagnose, htmlSnapshot, officeSnapshot, prettyXml, previewDocument, ren
|
|
|
10
10
|
export type { LocalDiagnostic, OfficeLocalOptions } from './lib/local-render.js';
|
|
11
11
|
export { declaredEinvoice, diagnoseEinvoice, localEinvoiceXml, } from './lib/einvoice.js';
|
|
12
12
|
export type { DataSetDiagnostics } from './lib/einvoice.js';
|
|
13
|
+
export { diagnoseAccessibility } from './lib/accessibility.js';
|
|
14
|
+
export type { FileDiagnostics } from './lib/accessibility.js';
|
|
13
15
|
export { contentTypeFor, listLocalFiles, localFilePath, sha256File, writeLocalFile, } from './lib/files.js';
|
|
14
16
|
export type { LocalFile, LocalFileListing } from './lib/files.js';
|
|
15
17
|
export type { LocalRenderOptions } from './lib/local-render.js';
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LocalDiagnostic } from './local-render.cjs';
|
|
2
|
+
import { type LocalTemplate } from './project.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* `pdf.ua` of a template folder (plan 21 §6): what can be said about a template that declares
|
|
5
|
+
* PDF/UA-1 without rendering it. `formfeed validate` and the MCP server's validation report it. It
|
|
6
|
+
* is the static half of the template check: a document without a title, an image written without
|
|
7
|
+
* `alt`, and a declaration the API will refuse. What depends on the data (heading levels, table
|
|
8
|
+
* rows, a chart's name) is found in the rendered page, by the editor's preview and by the render.
|
|
9
|
+
*/
|
|
10
|
+
/** The findings of one file of a template folder. */
|
|
11
|
+
export interface FileDiagnostics {
|
|
12
|
+
/** Relative to the template folder: `template.html`, `settings.json`. */
|
|
13
|
+
file: string;
|
|
14
|
+
diagnostics: LocalDiagnostic[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Empty for a template that does not declare `pdf.ua`. A fault the validator fails the file for is
|
|
18
|
+
* an error where the template is strict, since every render of it then fails, and a warning where
|
|
19
|
+
* it only reports; what a reader stumbles over without a rule failing is a warning either way.
|
|
20
|
+
*/
|
|
21
|
+
export declare function diagnoseAccessibility(tpl: LocalTemplate): FileDiagnostics[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { LocalDiagnostic } from './local-render.js';
|
|
2
|
+
import { type LocalTemplate } from './project.js';
|
|
3
|
+
/**
|
|
4
|
+
* `pdf.ua` of a template folder (plan 21 §6): what can be said about a template that declares
|
|
5
|
+
* PDF/UA-1 without rendering it. `formfeed validate` and the MCP server's validation report it. It
|
|
6
|
+
* is the static half of the template check: a document without a title, an image written without
|
|
7
|
+
* `alt`, and a declaration the API will refuse. What depends on the data (heading levels, table
|
|
8
|
+
* rows, a chart's name) is found in the rendered page, by the editor's preview and by the render.
|
|
9
|
+
*/
|
|
10
|
+
/** The findings of one file of a template folder. */
|
|
11
|
+
export interface FileDiagnostics {
|
|
12
|
+
/** Relative to the template folder: `template.html`, `settings.json`. */
|
|
13
|
+
file: string;
|
|
14
|
+
diagnostics: LocalDiagnostic[];
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Empty for a template that does not declare `pdf.ua`. A fault the validator fails the file for is
|
|
18
|
+
* an error where the template is strict, since every render of it then fails, and a warning where
|
|
19
|
+
* it only reports; what a reader stumbles over without a rule failing is a warning either way.
|
|
20
|
+
*/
|
|
21
|
+
export declare function diagnoseAccessibility(tpl: LocalTemplate): FileDiagnostics[];
|