@formfeed/devkit 0.3.5 → 0.3.7

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
@@ -1,6 +1,6 @@
1
1
  # @formfeed/devkit
2
2
 
3
- The local half of the [Formfeed](https://formfeed.dev) development kit: template folders, project
3
+ The local half of the [Formfeed](https://formfeed.dev/?utm_source=npm&utm_content=devkit) development kit: template folders, project
4
4
  configuration (`formfeed.json`) and offline rendering with the same engine the API uses. The
5
5
  [`formfeed` CLI](https://www.npmjs.com/package/formfeed) and
6
6
  [`@formfeed/testing`](https://www.npmjs.com/package/@formfeed/testing) are built on it; use it
package/index.cjs CHANGED
@@ -32,6 +32,7 @@ __export(index_exports, {
32
32
  diagnose: () => diagnose,
33
33
  findProject: () => findProject,
34
34
  generateTypes: () => generateTypes,
35
+ htmlSnapshot: () => htmlSnapshot,
35
36
  isIgnored: () => isIgnored,
36
37
  listLocalFiles: () => listLocalFiles,
37
38
  listTemplateSlugs: () => listTemplateSlugs,
@@ -538,6 +539,16 @@ async function renderOfficeLocal(project, tpl, data, options = {}) {
538
539
  if (options.locale) context.locale = options.locale;
539
540
  return (0, import_engine4.renderOffice)(tpl.file.bytes, { engine: tpl.meta.engine, data, context, images: options.images, random: options.random });
540
541
  }
542
+ function htmlSnapshot(rendered) {
543
+ let snapshot = rendered.document;
544
+ if (rendered.headerHtml) snapshot += `
545
+ <!-- formfeed:header -->
546
+ ${rendered.headerHtml}`;
547
+ if (rendered.footerHtml) snapshot += `
548
+ <!-- formfeed:footer -->
549
+ ${rendered.footerHtml}`;
550
+ return snapshot;
551
+ }
541
552
  function officeSnapshot(filled) {
542
553
  return (0, import_engine4.officeTextParts)(filled).map((part) => `--- ${part.name} ---
543
554
  ${prettyXml(part.xml)}`).join("\n");
@@ -1229,11 +1240,18 @@ function emitTypeScript(templates, options = {}) {
1229
1240
  return lines.join("\n") + "\n";
1230
1241
  }
1231
1242
 
1232
- // packages/devkit/src/lib/types/index.ts
1243
+ // packages/devkit/src/lib/types/generate.ts
1233
1244
  var defaultTypesFile = {
1234
1245
  ts: "formfeed.d.ts",
1235
1246
  python: "formfeed_templates.py"
1236
1247
  };
1248
+ function generateTypes(sources, language, options = {}) {
1249
+ const reserved = language === "python" ? ["TypedRenders", "AsyncTypedRenders", "Formfeed", "AsyncFormfeed", "Render", "Any", "Literal", "Union", "Never", "NotRequired", "TypedDict"] : ["FormfeedTemplates"];
1250
+ const model = buildTypes(sources, reserved);
1251
+ return language === "python" ? emitPython(model) : emitTypeScript(model, options);
1252
+ }
1253
+
1254
+ // packages/devkit/src/lib/types/index.ts
1237
1255
  function localTypeSource(tpl) {
1238
1256
  if (tpl.dataSchema) return { slug: tpl.slug, schema: tpl.dataSchema, origin: "local" };
1239
1257
  const sets = Object.values(tpl.dataSets);
@@ -1243,11 +1261,6 @@ function localTypeSource(tpl) {
1243
1261
  origin: "inferred"
1244
1262
  };
1245
1263
  }
1246
- function generateTypes(sources, language, options = {}) {
1247
- const reserved = language === "python" ? ["TypedRenders", "AsyncTypedRenders", "Formfeed", "AsyncFormfeed", "Render", "Any", "Literal", "Union", "Never", "NotRequired", "TypedDict"] : ["FormfeedTemplates"];
1248
- const model = buildTypes(sources, reserved);
1249
- return language === "python" ? emitPython(model) : emitTypeScript(model, options);
1250
- }
1251
1264
  // Annotate the CommonJS export names for ESM import in node:
1252
1265
  0 && (module.exports = {
1253
1266
  DevkitError,
@@ -1262,6 +1275,7 @@ function generateTypes(sources, language, options = {}) {
1262
1275
  diagnose,
1263
1276
  findProject,
1264
1277
  generateTypes,
1278
+ htmlSnapshot,
1265
1279
  isIgnored,
1266
1280
  listLocalFiles,
1267
1281
  listTemplateSlugs,
package/index.js CHANGED
@@ -480,6 +480,16 @@ async function renderOfficeLocal(project, tpl, data, options = {}) {
480
480
  if (options.locale) context.locale = options.locale;
481
481
  return renderOffice(tpl.file.bytes, { engine: tpl.meta.engine, data, context, images: options.images, random: options.random });
482
482
  }
483
+ function htmlSnapshot(rendered) {
484
+ let snapshot = rendered.document;
485
+ if (rendered.headerHtml) snapshot += `
486
+ <!-- formfeed:header -->
487
+ ${rendered.headerHtml}`;
488
+ if (rendered.footerHtml) snapshot += `
489
+ <!-- formfeed:footer -->
490
+ ${rendered.footerHtml}`;
491
+ return snapshot;
492
+ }
483
493
  function officeSnapshot(filled) {
484
494
  return officeTextParts(filled).map((part) => `--- ${part.name} ---
485
495
  ${prettyXml(part.xml)}`).join("\n");
@@ -1171,11 +1181,18 @@ function emitTypeScript(templates, options = {}) {
1171
1181
  return lines.join("\n") + "\n";
1172
1182
  }
1173
1183
 
1174
- // packages/devkit/src/lib/types/index.ts
1184
+ // packages/devkit/src/lib/types/generate.ts
1175
1185
  var defaultTypesFile = {
1176
1186
  ts: "formfeed.d.ts",
1177
1187
  python: "formfeed_templates.py"
1178
1188
  };
1189
+ function generateTypes(sources, language, options = {}) {
1190
+ const reserved = language === "python" ? ["TypedRenders", "AsyncTypedRenders", "Formfeed", "AsyncFormfeed", "Render", "Any", "Literal", "Union", "Never", "NotRequired", "TypedDict"] : ["FormfeedTemplates"];
1191
+ const model = buildTypes(sources, reserved);
1192
+ return language === "python" ? emitPython(model) : emitTypeScript(model, options);
1193
+ }
1194
+
1195
+ // packages/devkit/src/lib/types/index.ts
1179
1196
  function localTypeSource(tpl) {
1180
1197
  if (tpl.dataSchema) return { slug: tpl.slug, schema: tpl.dataSchema, origin: "local" };
1181
1198
  const sets = Object.values(tpl.dataSets);
@@ -1185,11 +1202,6 @@ function localTypeSource(tpl) {
1185
1202
  origin: "inferred"
1186
1203
  };
1187
1204
  }
1188
- function generateTypes(sources, language, options = {}) {
1189
- const reserved = language === "python" ? ["TypedRenders", "AsyncTypedRenders", "Formfeed", "AsyncFormfeed", "Render", "Any", "Literal", "Union", "Never", "NotRequired", "TypedDict"] : ["FormfeedTemplates"];
1190
- const model = buildTypes(sources, reserved);
1191
- return language === "python" ? emitPython(model) : emitTypeScript(model, options);
1192
- }
1193
1205
  export {
1194
1206
  DevkitError,
1195
1207
  brandFromJson,
@@ -1203,6 +1215,7 @@ export {
1203
1215
  diagnose,
1204
1216
  findProject,
1205
1217
  generateTypes,
1218
+ htmlSnapshot,
1206
1219
  isIgnored,
1207
1220
  listLocalFiles,
1208
1221
  listTemplateSlugs,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formfeed/devkit",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
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.5",
34
- "@formfeed/sdk": "0.3.5"
33
+ "@formfeed/engine": "0.3.7",
34
+ "@formfeed/sdk": "0.3.7"
35
35
  },
36
36
  "keywords": [
37
37
  "formfeed",
package/types/index.d.cts CHANGED
@@ -6,7 +6,7 @@ export type { LocalOfficeFile, LocalTemplate, ProjectState, SharedPartialState,
6
6
  export { brandFromJson, brandPath, readBrand, writeBrand } from './lib/brand.cjs';
7
7
  export { collectPartials } from './lib/partials.cjs';
8
8
  export type { CollectedPartials } from './lib/partials.cjs';
9
- export { diagnose, officeSnapshot, prettyXml, previewDocument, renderContext, renderLocal, renderOfficeLocal, renderedSettings } from './lib/local-render.cjs';
9
+ export { diagnose, htmlSnapshot, officeSnapshot, prettyXml, previewDocument, renderContext, renderLocal, renderOfficeLocal, renderedSettings } from './lib/local-render.cjs';
10
10
  export type { LocalDiagnostic, OfficeLocalOptions } from './lib/local-render.cjs';
11
11
  export { contentTypeFor, listLocalFiles, localFilePath, sha256File, writeLocalFile } from './lib/files.cjs';
12
12
  export type { LocalFile, LocalFileListing } from './lib/files.cjs';
package/types/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export type { LocalOfficeFile, LocalTemplate, ProjectState, SharedPartialState,
6
6
  export { brandFromJson, brandPath, readBrand, writeBrand } from './lib/brand.js';
7
7
  export { collectPartials } from './lib/partials.js';
8
8
  export type { CollectedPartials } from './lib/partials.js';
9
- export { diagnose, officeSnapshot, prettyXml, previewDocument, renderContext, renderLocal, renderOfficeLocal, renderedSettings } from './lib/local-render.js';
9
+ export { diagnose, htmlSnapshot, officeSnapshot, prettyXml, previewDocument, renderContext, renderLocal, renderOfficeLocal, renderedSettings } from './lib/local-render.js';
10
10
  export type { LocalDiagnostic, OfficeLocalOptions } from './lib/local-render.js';
11
11
  export { contentTypeFor, listLocalFiles, localFilePath, sha256File, writeLocalFile } from './lib/files.js';
12
12
  export type { LocalFile, LocalFileListing } from './lib/files.js';
@@ -23,6 +23,13 @@ export interface OfficeLocalOptions {
23
23
  }
24
24
  /** Fills a Word or PowerPoint template with the shared engine, as the render-worker does. */
25
25
  export declare function renderOfficeLocal(project: Project, tpl: LocalTemplate, data: unknown, options?: OfficeLocalOptions): Promise<OfficeRenderResult>;
26
+ /**
27
+ * An HTML template's snapshot: the assembled document, then the rendered header and footer under
28
+ * `<!-- formfeed:header -->` and `<!-- formfeed:footer -->` lines when the template has them.
29
+ * Chromium prints header and footer from templates of their own, outside the document, so a
30
+ * snapshot of the document alone passed a changed footer unnoticed.
31
+ */
32
+ export declare function htmlSnapshot(rendered: Pick<RenderedDocument, 'document' | 'headerHtml' | 'footerHtml'>): string;
26
33
  /**
27
34
  * The filled parts of a Word or PowerPoint document as readable text for snapshots: each part's XML,
28
35
  * one element per line and indented, text kept beside its element, under a `--- <part> ---` line.
@@ -23,6 +23,13 @@ export interface OfficeLocalOptions {
23
23
  }
24
24
  /** Fills a Word or PowerPoint template with the shared engine, as the render-worker does. */
25
25
  export declare function renderOfficeLocal(project: Project, tpl: LocalTemplate, data: unknown, options?: OfficeLocalOptions): Promise<OfficeRenderResult>;
26
+ /**
27
+ * An HTML template's snapshot: the assembled document, then the rendered header and footer under
28
+ * `<!-- formfeed:header -->` and `<!-- formfeed:footer -->` lines when the template has them.
29
+ * Chromium prints header and footer from templates of their own, outside the document, so a
30
+ * snapshot of the document alone passed a changed footer unnoticed.
31
+ */
32
+ export declare function htmlSnapshot(rendered: Pick<RenderedDocument, 'document' | 'headerHtml' | 'footerHtml'>): string;
26
33
  /**
27
34
  * The filled parts of a Word or PowerPoint document as readable text for snapshots: each part's XML,
28
35
  * one element per line and indented, text kept beside its element, under a `--- <part> ---` line.
@@ -0,0 +1,15 @@
1
+ import { type TypeScriptOptions } from './emit-ts.cjs';
2
+ import { type TypeSource } from './model.cjs';
3
+ /**
4
+ * `formfeed types` without the file system (spec 19 §2): a schema in, a generated file out. Apart
5
+ * from `index.ts`, which reads template folders and therefore brings the engine with it, so the
6
+ * landing site's browser tool can emit exactly what the CLI emits. `@formfeed/devkit/emit` in this
7
+ * workspace; the published package exposes the same functions from its single entry.
8
+ */
9
+ export type TypesLanguage = 'ts' | 'python';
10
+ export declare const defaultTypesFile: Record<TypesLanguage, string>;
11
+ /** The generated file for `sources` in `language`; the same input always gives the same bytes. */
12
+ export declare function generateTypes(sources: TypeSource[], language: TypesLanguage, options?: TypeScriptOptions): string;
13
+ export { buildTypes, pascalCase, relaxRequired, singular } from './model.cjs';
14
+ export type { SchemaOrigin, TemplateTypes, TypeNode, TypeSource } from './model.cjs';
15
+ export type { TypeScriptOptions } from './emit-ts.cjs';
@@ -0,0 +1,15 @@
1
+ import { type TypeScriptOptions } from './emit-ts.js';
2
+ import { type TypeSource } from './model.js';
3
+ /**
4
+ * `formfeed types` without the file system (spec 19 §2): a schema in, a generated file out. Apart
5
+ * from `index.ts`, which reads template folders and therefore brings the engine with it, so the
6
+ * landing site's browser tool can emit exactly what the CLI emits. `@formfeed/devkit/emit` in this
7
+ * workspace; the published package exposes the same functions from its single entry.
8
+ */
9
+ export type TypesLanguage = 'ts' | 'python';
10
+ export declare const defaultTypesFile: Record<TypesLanguage, string>;
11
+ /** The generated file for `sources` in `language`; the same input always gives the same bytes. */
12
+ export declare function generateTypes(sources: TypeSource[], language: TypesLanguage, options?: TypeScriptOptions): string;
13
+ export { buildTypes, pascalCase, relaxRequired, singular } from './model.js';
14
+ export type { SchemaOrigin, TemplateTypes, TypeNode, TypeSource } from './model.js';
15
+ export type { TypeScriptOptions } from './emit-ts.js';
@@ -1,15 +1,9 @@
1
1
  import type { LocalTemplate } from '../project.cjs';
2
- import { type TypeScriptOptions } from './emit-ts.cjs';
3
- import { type TypeSource } from './model.cjs';
4
- export type TypesLanguage = 'ts' | 'python';
5
- export declare const defaultTypesFile: Record<TypesLanguage, string>;
2
+ import type { TypeSource } from './model.cjs';
6
3
  /**
7
4
  * The schema of a template folder: `schema.json` when it has one, else inferred over all its data
8
5
  * sets (a field only some sets carry is optional), marked as inferred so every field is optional.
9
6
  */
10
7
  export declare function localTypeSource(tpl: LocalTemplate): TypeSource;
11
- /** The generated file for `sources` in `language`; the same input always gives the same bytes. */
12
- export declare function generateTypes(sources: TypeSource[], language: TypesLanguage, options?: TypeScriptOptions): string;
13
- export { buildTypes, pascalCase, relaxRequired, singular } from './model.cjs';
14
- export type { SchemaOrigin, TemplateTypes, TypeNode, TypeSource } from './model.cjs';
15
- export type { TypeScriptOptions } from './emit-ts.cjs';
8
+ export { buildTypes, defaultTypesFile, generateTypes, pascalCase, relaxRequired, singular } from './generate.cjs';
9
+ export type { SchemaOrigin, TemplateTypes, TypeNode, TypeScriptOptions, TypeSource, TypesLanguage } from './generate.cjs';
@@ -1,15 +1,9 @@
1
1
  import type { LocalTemplate } from '../project.js';
2
- import { type TypeScriptOptions } from './emit-ts.js';
3
- import { type TypeSource } from './model.js';
4
- export type TypesLanguage = 'ts' | 'python';
5
- export declare const defaultTypesFile: Record<TypesLanguage, string>;
2
+ import type { TypeSource } from './model.js';
6
3
  /**
7
4
  * The schema of a template folder: `schema.json` when it has one, else inferred over all its data
8
5
  * sets (a field only some sets carry is optional), marked as inferred so every field is optional.
9
6
  */
10
7
  export declare function localTypeSource(tpl: LocalTemplate): TypeSource;
11
- /** The generated file for `sources` in `language`; the same input always gives the same bytes. */
12
- export declare function generateTypes(sources: TypeSource[], language: TypesLanguage, options?: TypeScriptOptions): string;
13
- export { buildTypes, pascalCase, relaxRequired, singular } from './model.js';
14
- export type { SchemaOrigin, TemplateTypes, TypeNode, TypeSource } from './model.js';
15
- export type { TypeScriptOptions } from './emit-ts.js';
8
+ export { buildTypes, defaultTypesFile, generateTypes, pascalCase, relaxRequired, singular } from './generate.js';
9
+ export type { SchemaOrigin, TemplateTypes, TypeNode, TypeScriptOptions, TypeSource, TypesLanguage } from './generate.js';