create-dfactory 0.1.0
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/LICENSE +21 -0
- package/README.md +37 -0
- package/package.json +50 -0
- package/templates/base/dfactory.config.ts +34 -0
- package/templates/react/src/templates/invoice/template.tsx +154 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferenceDocument.tsx +309 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferenceFooter.tsx +26 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferenceHeader.tsx +23 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferencePagination.tsx +24 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferenceToc.tsx +30 -0
- package/templates/react/src/templates/invoice-reference/components/InvoiceReferenceWatermark.tsx +16 -0
- package/templates/react/src/templates/invoice-reference/components/types.ts +65 -0
- package/templates/react/src/templates/invoice-reference/template.tsx +307 -0
- package/templates/vue/src/templates/invoice/InvoiceTemplate.vue +96 -0
- package/templates/vue/src/templates/invoice/template.ts +85 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferenceDocument.vue +241 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferenceFooter.vue +26 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferenceHeader.vue +25 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferencePagination.vue +24 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferenceToc.vue +34 -0
- package/templates/vue/src/templates/invoice-reference/components/InvoiceReferenceWatermark.vue +20 -0
- package/templates/vue/src/templates/invoice-reference/components/types.ts +65 -0
- package/templates/vue/src/templates/invoice-reference/template.ts +300 -0
- package/templates/vue/src/vue-shims.d.ts +6 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
import { h } from "vue";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
import { defineTemplate } from "@dfactory/template-kit";
|
|
5
|
+
|
|
6
|
+
import InvoiceReferenceDocument from "./components/InvoiceReferenceDocument.vue";
|
|
7
|
+
import InvoiceReferenceFooter from "./components/InvoiceReferenceFooter.vue";
|
|
8
|
+
import InvoiceReferenceHeader from "./components/InvoiceReferenceHeader.vue";
|
|
9
|
+
import InvoiceReferencePagination from "./components/InvoiceReferencePagination.vue";
|
|
10
|
+
import InvoiceReferenceToc from "./components/InvoiceReferenceToc.vue";
|
|
11
|
+
import InvoiceReferenceWatermark from "./components/InvoiceReferenceWatermark.vue";
|
|
12
|
+
|
|
13
|
+
const lineItemSchema = z.object({
|
|
14
|
+
id: z.string(),
|
|
15
|
+
name: z.string(),
|
|
16
|
+
description: z.string().optional(),
|
|
17
|
+
qty: z.number().positive(),
|
|
18
|
+
unitPrice: z.number().nonnegative(),
|
|
19
|
+
discount: z.number().nonnegative().max(100).optional(),
|
|
20
|
+
taxRate: z.number().nonnegative().max(100).optional()
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
const sectionSchema = z.object({
|
|
24
|
+
title: z.string(),
|
|
25
|
+
description: z.string(),
|
|
26
|
+
notes: z.string().optional()
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
const invoiceReferenceSchema = z.object({
|
|
30
|
+
invoiceNumber: z.string(),
|
|
31
|
+
purchaseOrder: z.string().optional(),
|
|
32
|
+
issuedAt: z.string(),
|
|
33
|
+
dueAt: z.string(),
|
|
34
|
+
currency: z.string(),
|
|
35
|
+
company: z.object({
|
|
36
|
+
name: z.string(),
|
|
37
|
+
address: z.string(),
|
|
38
|
+
email: z.string(),
|
|
39
|
+
phone: z.string(),
|
|
40
|
+
website: z.string(),
|
|
41
|
+
taxId: z.string(),
|
|
42
|
+
logoUrl: z.string().url().optional()
|
|
43
|
+
}),
|
|
44
|
+
customer: z.object({
|
|
45
|
+
name: z.string(),
|
|
46
|
+
contact: z.string(),
|
|
47
|
+
email: z.string(),
|
|
48
|
+
address: z.string()
|
|
49
|
+
}),
|
|
50
|
+
items: z.array(lineItemSchema).min(1),
|
|
51
|
+
sections: z.array(sectionSchema).min(1),
|
|
52
|
+
payment: z.object({
|
|
53
|
+
iban: z.string(),
|
|
54
|
+
swift: z.string(),
|
|
55
|
+
bankName: z.string(),
|
|
56
|
+
instructions: z.string().optional()
|
|
57
|
+
}),
|
|
58
|
+
notes: z.string().optional(),
|
|
59
|
+
watermark: z
|
|
60
|
+
.object({
|
|
61
|
+
enabled: z.boolean(),
|
|
62
|
+
text: z.string()
|
|
63
|
+
})
|
|
64
|
+
.optional(),
|
|
65
|
+
brand: z
|
|
66
|
+
.object({
|
|
67
|
+
accentColor: z.string().optional(),
|
|
68
|
+
supportEmail: z.string().optional()
|
|
69
|
+
})
|
|
70
|
+
.optional()
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
type InvoiceReferencePayload = z.infer<typeof invoiceReferenceSchema>;
|
|
74
|
+
|
|
75
|
+
function createItems(count: number): InvoiceReferencePayload["items"] {
|
|
76
|
+
return Array.from({ length: count }, (_, index) => {
|
|
77
|
+
const row = index + 1;
|
|
78
|
+
return {
|
|
79
|
+
id: `line-${row}`,
|
|
80
|
+
name: `Professional Service Block ${row}`,
|
|
81
|
+
description:
|
|
82
|
+
row % 2 === 0
|
|
83
|
+
? "Includes discovery, implementation, and QA handoff."
|
|
84
|
+
: "Includes architecture review and stakeholder alignment.",
|
|
85
|
+
qty: (row % 3) + 1,
|
|
86
|
+
unitPrice: 180 + row * 12,
|
|
87
|
+
discount: row % 5 === 0 ? 8 : 0,
|
|
88
|
+
taxRate: 21
|
|
89
|
+
};
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function createSections(count: number): InvoiceReferencePayload["sections"] {
|
|
94
|
+
return Array.from({ length: count }, (_, index) => {
|
|
95
|
+
const row = index + 1;
|
|
96
|
+
return {
|
|
97
|
+
title: `Delivery Milestone ${row}`,
|
|
98
|
+
description:
|
|
99
|
+
"This section demonstrates long-form print content with structured headings, making TOC and page breaks easy to validate during authoring.",
|
|
100
|
+
notes:
|
|
101
|
+
row % 2 === 0
|
|
102
|
+
? "Attach acceptance notes and sign-off evidence for enterprise audits."
|
|
103
|
+
: "Use pagination markers for sections that should stay together."
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
function createPayload(options: {
|
|
109
|
+
invoiceNumber: string;
|
|
110
|
+
lineCount: number;
|
|
111
|
+
watermarkText: string;
|
|
112
|
+
accentColor: string;
|
|
113
|
+
}): InvoiceReferencePayload {
|
|
114
|
+
return {
|
|
115
|
+
invoiceNumber: options.invoiceNumber,
|
|
116
|
+
purchaseOrder: "PO-40218",
|
|
117
|
+
issuedAt: "2026-03-27",
|
|
118
|
+
dueAt: "2026-04-10",
|
|
119
|
+
currency: "EUR",
|
|
120
|
+
company: {
|
|
121
|
+
name: "DFactory Labs Ltd.",
|
|
122
|
+
address: "A. Briana Street 9A\nRiga, LV-1001\nLatvia",
|
|
123
|
+
email: "finance@dfactory.dev",
|
|
124
|
+
phone: "+371 6700 4500",
|
|
125
|
+
website: "https://dfactory.dev",
|
|
126
|
+
taxId: "LV40203577891"
|
|
127
|
+
},
|
|
128
|
+
customer: {
|
|
129
|
+
name: "Northwind Trading Group",
|
|
130
|
+
contact: "Marta Jensen",
|
|
131
|
+
email: "marta.jensen@northwind.example",
|
|
132
|
+
address: "28 Innovation Plaza\nTallinn, 10111\nEstonia"
|
|
133
|
+
},
|
|
134
|
+
items: createItems(options.lineCount),
|
|
135
|
+
sections: createSections(Math.max(4, Math.ceil(options.lineCount / 4))),
|
|
136
|
+
payment: {
|
|
137
|
+
iban: "LV80HABA0551045933178",
|
|
138
|
+
swift: "HABALV22",
|
|
139
|
+
bankName: "Swedbank AS",
|
|
140
|
+
instructions: "Please reference invoice number in payment details."
|
|
141
|
+
},
|
|
142
|
+
notes:
|
|
143
|
+
"All deliverables were accepted during sprint review. This reference template showcases advanced TOC, pagination markers, watermark layers, and custom header/footer element rendering.",
|
|
144
|
+
watermark: {
|
|
145
|
+
enabled: true,
|
|
146
|
+
text: options.watermarkText
|
|
147
|
+
},
|
|
148
|
+
brand: {
|
|
149
|
+
accentColor: options.accentColor,
|
|
150
|
+
supportEmail: "support@dfactory.dev"
|
|
151
|
+
}
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
const template = defineTemplate({
|
|
156
|
+
meta: {
|
|
157
|
+
id: "invoice-reference",
|
|
158
|
+
title: "Invoice Reference (Advanced)",
|
|
159
|
+
description:
|
|
160
|
+
"Rich multi-file reference template with first-class TOC/header/footer/watermark/pagination elements.",
|
|
161
|
+
framework: "vue",
|
|
162
|
+
version: "1.0.0",
|
|
163
|
+
tags: ["billing", "reference", "advanced"]
|
|
164
|
+
},
|
|
165
|
+
schema: invoiceReferenceSchema,
|
|
166
|
+
pdf: {
|
|
167
|
+
page: {
|
|
168
|
+
size: "A4",
|
|
169
|
+
marginsMm: { top: 16, right: 12, bottom: 16, left: 12 }
|
|
170
|
+
},
|
|
171
|
+
toc: {
|
|
172
|
+
enabled: true,
|
|
173
|
+
maxDepth: 3,
|
|
174
|
+
title: "Invoice Reference Contents"
|
|
175
|
+
},
|
|
176
|
+
pagination: {
|
|
177
|
+
mode: "css"
|
|
178
|
+
},
|
|
179
|
+
headerFooter: {
|
|
180
|
+
enabled: true
|
|
181
|
+
},
|
|
182
|
+
assets: {
|
|
183
|
+
maxAssetCount: 24,
|
|
184
|
+
maxAssetBytes: 1024 * 1024,
|
|
185
|
+
timeoutMs: 4000
|
|
186
|
+
},
|
|
187
|
+
metadata: {
|
|
188
|
+
title: "DFactory Invoice Reference Document",
|
|
189
|
+
author: "DFactory",
|
|
190
|
+
keywords: ["invoice", "reference", "pdf", "dfactory"]
|
|
191
|
+
},
|
|
192
|
+
watermark: {
|
|
193
|
+
text: "DRAFT",
|
|
194
|
+
opacity: 0.12,
|
|
195
|
+
fontSize: 44
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
pdfElements: {
|
|
199
|
+
toc: {
|
|
200
|
+
render(context) {
|
|
201
|
+
return h(InvoiceReferenceToc, {
|
|
202
|
+
title: `${context.template.title} TOC`,
|
|
203
|
+
headings: context.headings
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
header: {
|
|
208
|
+
render(context) {
|
|
209
|
+
return h(InvoiceReferenceHeader, {
|
|
210
|
+
title: context.template.title,
|
|
211
|
+
invoiceNumber: (context.payload as InvoiceReferencePayload).invoiceNumber,
|
|
212
|
+
generatedAtToken: context.tokens.date
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
footer: {
|
|
217
|
+
render(context) {
|
|
218
|
+
return h(InvoiceReferenceFooter, {
|
|
219
|
+
templateId: context.templateId,
|
|
220
|
+
pageNumberToken: context.tokens.pageNumber,
|
|
221
|
+
totalPagesToken: context.tokens.totalPages,
|
|
222
|
+
supportEmail: (context.payload as InvoiceReferencePayload).brand?.supportEmail
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
watermark: {
|
|
227
|
+
render(context) {
|
|
228
|
+
const watermark = (context.payload as InvoiceReferencePayload).watermark;
|
|
229
|
+
if (!watermark?.enabled) {
|
|
230
|
+
return "";
|
|
231
|
+
}
|
|
232
|
+
return h(InvoiceReferenceWatermark, {
|
|
233
|
+
text: watermark.text
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
},
|
|
237
|
+
pagination: {
|
|
238
|
+
render(context) {
|
|
239
|
+
return h(InvoiceReferencePagination, {
|
|
240
|
+
pageNumberToken: context.tokens.pageNumber,
|
|
241
|
+
totalPagesToken: context.tokens.totalPages
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
},
|
|
246
|
+
examples: [
|
|
247
|
+
{
|
|
248
|
+
name: "short",
|
|
249
|
+
description: "Single-page styled invoice with minimal line items.",
|
|
250
|
+
payload: createPayload({
|
|
251
|
+
invoiceNumber: "INV-REF-1001",
|
|
252
|
+
lineCount: 4,
|
|
253
|
+
watermarkText: "INTERNAL",
|
|
254
|
+
accentColor: "#4f46e5"
|
|
255
|
+
})
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
name: "multi-page",
|
|
259
|
+
description: "Long-form invoice designed to exercise TOC and pagination.",
|
|
260
|
+
payload: createPayload({
|
|
261
|
+
invoiceNumber: "INV-REF-1002",
|
|
262
|
+
lineCount: 24,
|
|
263
|
+
watermarkText: "REVIEW",
|
|
264
|
+
accentColor: "#3730a3"
|
|
265
|
+
})
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
name: "branded",
|
|
269
|
+
description: "Branded variation with strong accent and support metadata.",
|
|
270
|
+
payload: createPayload({
|
|
271
|
+
invoiceNumber: "INV-REF-1003",
|
|
272
|
+
lineCount: 12,
|
|
273
|
+
watermarkText: "BRANDED",
|
|
274
|
+
accentColor: "#1d4ed8"
|
|
275
|
+
})
|
|
276
|
+
},
|
|
277
|
+
{
|
|
278
|
+
name: "watermark-heavy",
|
|
279
|
+
description: "Watermark-forward profile to validate overlay readability.",
|
|
280
|
+
payload: createPayload({
|
|
281
|
+
invoiceNumber: "INV-REF-1004",
|
|
282
|
+
lineCount: 18,
|
|
283
|
+
watermarkText: "CONFIDENTIAL",
|
|
284
|
+
accentColor: "#4338ca"
|
|
285
|
+
})
|
|
286
|
+
}
|
|
287
|
+
],
|
|
288
|
+
render(payload) {
|
|
289
|
+
return h(InvoiceReferenceDocument, {
|
|
290
|
+
payload
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
export const meta = template.meta;
|
|
296
|
+
export const schema = template.schema;
|
|
297
|
+
export const pdf = template.pdf;
|
|
298
|
+
export const pdfElements = template.pdfElements;
|
|
299
|
+
export const examples = template.examples;
|
|
300
|
+
export const render = template.render;
|