@unrdf/kgn 5.0.1 → 26.4.2
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/dist/index.mjs +9207 -0
- package/package.json +33 -28
- package/src/base/filter-templates.js +7 -1
- package/src/base/index.js +15 -10
- package/src/base/injection-targets.js +6 -0
- package/src/base/macro-templates.js +6 -0
- package/src/base/shacl-templates.js +6 -0
- package/src/base/template-base.js +7 -1
- package/src/core/attestor.js +50 -1
- package/src/core/filters.js +134 -1
- package/src/core/index.js +8 -1
- package/src/core/kgen-engine.js +49 -1
- package/src/core/parser.js +52 -1
- package/src/core/post-processor.js +7 -1
- package/src/core/renderer.js +67 -1
- package/src/doc-generator/mdx-generator.mjs +1 -1
- package/src/doc-generator/nav-generator.mjs +1 -1
- package/src/doc-generator/rdf-builder.mjs +2 -2
- package/src/engine/index.js +9 -0
- package/src/engine/pipeline.js +7 -1
- package/src/engine/renderer.js +18 -3
- package/src/engine/template-engine.js +12 -3
- package/src/filters/array.js +14 -6
- package/src/filters/index.js +165 -17
- package/src/filters/rdf.js +3 -3
- package/src/{index.js → index.mjs} +46 -0
- package/src/index.test.mjs +40 -0
- package/src/inheritance/index.js +19 -1
- package/src/injection/atomic-writer.js +22 -1
- package/src/injection/idempotency-manager.js +33 -0
- package/src/injection/injection-engine.js +46 -1
- package/src/injection/integration.js +3 -3
- package/src/injection/modes/index.js +30 -0
- package/src/injection/rollback-manager.js +26 -2
- package/src/injection/target-resolver.js +48 -3
- package/src/injection/tests/injection-engine.test.js +3 -3
- package/src/injection/tests/integration.test.js +2 -1
- package/src/injection/tests/run-tests.js +3 -0
- package/src/injection/validation-engine.js +71 -5
- package/src/linter/determinism-linter.js +20 -5
- package/src/linter/determinism.js +8 -2
- package/src/linter/index.js +3 -1
- package/src/linter/test-doubles.js +151 -4
- package/src/parser/frontmatter.js +6 -0
- package/src/parser/variables.js +7 -1
- package/src/rdf/filters.js +393 -0
- package/src/rdf/index.js +444 -0
- package/src/renderer/deterministic.js +6 -0
- package/src/renderer/index.js +3 -1
- package/src/templates/rdf/DELIVERY-SUMMARY.md +266 -0
- package/src/templates/rdf/README.md +595 -0
- package/src/templates/rdf/dataset.njk +83 -0
- package/src/templates/rdf/index.js +106 -0
- package/src/templates/rdf/jsonld-context.njk +63 -0
- package/src/templates/rdf/ontology.njk +107 -0
- package/src/templates/rdf/schema.njk +79 -0
- package/src/templates/rdf/shapes.njk +89 -0
- package/src/templates/rdf/sparql-queries.njk +70 -0
- package/src/templates/rdf/vocabulary.njk +79 -0
package/src/rdf/index.js
ADDED
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file RDF-Aware Template System Integration
|
|
3
|
+
* @module @unrdf/kgn/rdf
|
|
4
|
+
* @description Integration layer between @unrdf/kgn and @unrdf/core for RDF-aware templating
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { z } from 'zod';
|
|
8
|
+
import nunjucks from 'nunjucks';
|
|
9
|
+
import {
|
|
10
|
+
createStore,
|
|
11
|
+
namedNode,
|
|
12
|
+
literal as createLiteral,
|
|
13
|
+
blankNode as createBlankNode,
|
|
14
|
+
quad,
|
|
15
|
+
executeQuery,
|
|
16
|
+
COMMON_PREFIXES,
|
|
17
|
+
} from '@unrdf/core';
|
|
18
|
+
import { rdfTemplateFilters } from './filters.js';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Schema for RDF template engine configuration
|
|
22
|
+
*/
|
|
23
|
+
const RdfTemplateEngineConfigSchema = z.object({
|
|
24
|
+
autoescape: z.boolean().optional(),
|
|
25
|
+
throwOnUndefined: z.boolean().optional(),
|
|
26
|
+
trimBlocks: z.boolean().optional(),
|
|
27
|
+
lstripBlocks: z.boolean().optional(),
|
|
28
|
+
prefixes: z.record(z.string()).optional(),
|
|
29
|
+
enableStore: z.boolean().optional(),
|
|
30
|
+
storeOptions: z.any().optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Schema for RDF template rendering context
|
|
35
|
+
*/
|
|
36
|
+
const RdfRenderContextSchema = z.object({
|
|
37
|
+
data: z.any(),
|
|
38
|
+
prefixes: z.record(z.string()).optional(),
|
|
39
|
+
store: z.any().optional(),
|
|
40
|
+
baseUri: z.string().url().optional(),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Schema for SPARQL template generation
|
|
45
|
+
*/
|
|
46
|
+
const SparqlTemplateSchema = z.object({
|
|
47
|
+
prefixes: z.record(z.string()).optional(),
|
|
48
|
+
where: z.array(z.object({
|
|
49
|
+
subject: z.string(),
|
|
50
|
+
predicate: z.string(),
|
|
51
|
+
object: z.string(),
|
|
52
|
+
})).min(1),
|
|
53
|
+
select: z.array(z.string()).optional(),
|
|
54
|
+
distinct: z.boolean().optional(),
|
|
55
|
+
limit: z.number().int().positive().optional(),
|
|
56
|
+
offset: z.number().int().nonnegative().optional(),
|
|
57
|
+
orderBy: z.array(z.object({
|
|
58
|
+
variable: z.string(),
|
|
59
|
+
direction: z.enum(['ASC', 'DESC']).optional(),
|
|
60
|
+
})).optional(),
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* RDF-aware template engine
|
|
65
|
+
* Extends Nunjucks with RDF-specific filters and functions
|
|
66
|
+
*/
|
|
67
|
+
export class RdfTemplateEngine {
|
|
68
|
+
/**
|
|
69
|
+
* Create RDF template engine
|
|
70
|
+
* @param {Object} config - Engine configuration
|
|
71
|
+
*/
|
|
72
|
+
constructor(config = {}) {
|
|
73
|
+
this.config = RdfTemplateEngineConfigSchema.parse(config);
|
|
74
|
+
|
|
75
|
+
// Apply defaults
|
|
76
|
+
const {
|
|
77
|
+
autoescape = false,
|
|
78
|
+
throwOnUndefined = false,
|
|
79
|
+
trimBlocks = true,
|
|
80
|
+
lstripBlocks = true,
|
|
81
|
+
prefixes = {},
|
|
82
|
+
enableStore = true,
|
|
83
|
+
storeOptions,
|
|
84
|
+
} = this.config;
|
|
85
|
+
|
|
86
|
+
// Create Nunjucks environment
|
|
87
|
+
this.env = new nunjucks.Environment(null, {
|
|
88
|
+
autoescape,
|
|
89
|
+
throwOnUndefined,
|
|
90
|
+
trimBlocks,
|
|
91
|
+
lstripBlocks,
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Initialize RDF store if enabled
|
|
95
|
+
this.store = enableStore ? createStore(storeOptions) : null;
|
|
96
|
+
|
|
97
|
+
// Merge common prefixes with custom prefixes
|
|
98
|
+
this.prefixes = { ...COMMON_PREFIXES, ...prefixes };
|
|
99
|
+
|
|
100
|
+
// Register RDF filters
|
|
101
|
+
this._registerFilters();
|
|
102
|
+
|
|
103
|
+
// Register RDF functions
|
|
104
|
+
this._registerGlobals();
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Register RDF template filters
|
|
109
|
+
* @private
|
|
110
|
+
*/
|
|
111
|
+
_registerFilters() {
|
|
112
|
+
// Register all RDF template filters
|
|
113
|
+
for (const [name, filter] of Object.entries(rdfTemplateFilters)) {
|
|
114
|
+
this.env.addFilter(name, filter);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Additional utility filters
|
|
118
|
+
this.env.addFilter('expandUri', (curie) => this._expandUri(curie));
|
|
119
|
+
this.env.addFilter('contractUri', (uri) => this._contractUri(uri));
|
|
120
|
+
this.env.addFilter('toQuad', (triple) => this._toQuad(triple));
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Register global RDF functions
|
|
125
|
+
* @private
|
|
126
|
+
*/
|
|
127
|
+
_registerGlobals() {
|
|
128
|
+
// Add RDF term constructors as globals
|
|
129
|
+
this.env.addGlobal('namedNode', (uri) => namedNode(uri));
|
|
130
|
+
this.env.addGlobal('literal', (value, langOrDatatype) => {
|
|
131
|
+
if (!langOrDatatype) {
|
|
132
|
+
return createLiteral(value);
|
|
133
|
+
}
|
|
134
|
+
// Check if it's a language tag
|
|
135
|
+
if (/^[a-z]{2,3}(-[A-Z]{2})?$/.test(langOrDatatype)) {
|
|
136
|
+
return createLiteral(value, langOrDatatype);
|
|
137
|
+
}
|
|
138
|
+
// Treat as datatype
|
|
139
|
+
return createLiteral(value, null, namedNode(langOrDatatype));
|
|
140
|
+
});
|
|
141
|
+
this.env.addGlobal('blankNode', (id) => createBlankNode(id));
|
|
142
|
+
this.env.addGlobal('quad', (s, p, o, g) => quad(s, p, o, g));
|
|
143
|
+
|
|
144
|
+
// Add prefix expansion
|
|
145
|
+
this.env.addGlobal('expand', (curie) => this._expandUri(curie));
|
|
146
|
+
this.env.addGlobal('contract', (uri) => this._contractUri(uri));
|
|
147
|
+
|
|
148
|
+
// Add SPARQL query builder
|
|
149
|
+
this.env.addGlobal('sparqlQuery', (spec) => this._buildSparqlQuery(spec));
|
|
150
|
+
|
|
151
|
+
// Add store access (if enabled)
|
|
152
|
+
if (this.store) {
|
|
153
|
+
this.env.addGlobal('queryStore', async (query) => {
|
|
154
|
+
return await executeQuery(this.store, query);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Expand CURIE to full URI
|
|
161
|
+
* @private
|
|
162
|
+
* @param {string} curie - CURIE (prefix:localName)
|
|
163
|
+
* @returns {string} Full URI
|
|
164
|
+
*/
|
|
165
|
+
_expandUri(curie) {
|
|
166
|
+
if (!curie || typeof curie !== 'string') {
|
|
167
|
+
return '';
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
const colonIndex = curie.indexOf(':');
|
|
171
|
+
if (colonIndex === -1) {
|
|
172
|
+
return curie;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
const prefix = curie.substring(0, colonIndex);
|
|
176
|
+
const localName = curie.substring(colonIndex + 1);
|
|
177
|
+
|
|
178
|
+
if (this.prefixes[prefix]) {
|
|
179
|
+
return this.prefixes[prefix] + localName;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
return curie;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Contract URI to CURIE
|
|
187
|
+
* @private
|
|
188
|
+
* @param {string} uri - Full URI
|
|
189
|
+
* @returns {string} CURIE or original URI
|
|
190
|
+
*/
|
|
191
|
+
_contractUri(uri) {
|
|
192
|
+
if (!uri || typeof uri !== 'string') {
|
|
193
|
+
return '';
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
for (const [prefix, namespace] of Object.entries(this.prefixes)) {
|
|
197
|
+
if (uri.startsWith(namespace)) {
|
|
198
|
+
const localName = uri.substring(namespace.length);
|
|
199
|
+
return `${prefix}:${localName}`;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return uri;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Convert triple object to quad
|
|
208
|
+
* @private
|
|
209
|
+
* @param {Object} triple - Triple object
|
|
210
|
+
* @returns {Object} Quad object
|
|
211
|
+
*/
|
|
212
|
+
_toQuad(triple) {
|
|
213
|
+
if (!triple || typeof triple !== 'object') {
|
|
214
|
+
return null;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const subject = this._createTerm(triple.subject || triple.s);
|
|
218
|
+
const predicate = this._createTerm(triple.predicate || triple.p);
|
|
219
|
+
const object = this._createTerm(triple.object || triple.o);
|
|
220
|
+
|
|
221
|
+
return quad(subject, predicate, object);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Create RDF term from string or object
|
|
226
|
+
* @private
|
|
227
|
+
* @param {string|Object} term - Term specification
|
|
228
|
+
* @returns {Object} RDF term
|
|
229
|
+
*/
|
|
230
|
+
_createTerm(term) {
|
|
231
|
+
if (!term) {
|
|
232
|
+
return null;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
if (typeof term === 'object' && term.termType) {
|
|
236
|
+
return term;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (typeof term === 'string') {
|
|
240
|
+
// Blank node
|
|
241
|
+
if (term.startsWith('_:')) {
|
|
242
|
+
return createBlankNode(term.substring(2));
|
|
243
|
+
}
|
|
244
|
+
// URI
|
|
245
|
+
if (term.startsWith('http://') || term.startsWith('https://')) {
|
|
246
|
+
return namedNode(term);
|
|
247
|
+
}
|
|
248
|
+
// CURIE
|
|
249
|
+
if (term.includes(':')) {
|
|
250
|
+
return namedNode(this._expandUri(term));
|
|
251
|
+
}
|
|
252
|
+
// Literal
|
|
253
|
+
return createLiteral(term);
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return createLiteral(String(term));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* Build SPARQL query from template specification
|
|
261
|
+
* @private
|
|
262
|
+
* @param {Object} spec - Query specification
|
|
263
|
+
* @returns {string} SPARQL query
|
|
264
|
+
*/
|
|
265
|
+
_buildSparqlQuery(spec) {
|
|
266
|
+
const validated = SparqlTemplateSchema.parse(spec);
|
|
267
|
+
|
|
268
|
+
// Apply defaults
|
|
269
|
+
const {
|
|
270
|
+
prefixes = {},
|
|
271
|
+
where,
|
|
272
|
+
select,
|
|
273
|
+
distinct = false,
|
|
274
|
+
limit,
|
|
275
|
+
offset = 0,
|
|
276
|
+
orderBy,
|
|
277
|
+
} = validated;
|
|
278
|
+
|
|
279
|
+
const lines = [];
|
|
280
|
+
|
|
281
|
+
// Prefixes
|
|
282
|
+
const queryPrefixes = { ...this.prefixes, ...prefixes };
|
|
283
|
+
for (const [prefix, uri] of Object.entries(queryPrefixes)) {
|
|
284
|
+
lines.push(`PREFIX ${prefix}: <${uri}>`);
|
|
285
|
+
}
|
|
286
|
+
lines.push('');
|
|
287
|
+
|
|
288
|
+
// SELECT clause
|
|
289
|
+
const selectVars = select || ['*'];
|
|
290
|
+
const distinctStr = distinct ? 'DISTINCT ' : '';
|
|
291
|
+
lines.push(`SELECT ${distinctStr}${selectVars.join(' ')}`);
|
|
292
|
+
|
|
293
|
+
// WHERE clause
|
|
294
|
+
lines.push('WHERE {');
|
|
295
|
+
for (const pattern of where) {
|
|
296
|
+
lines.push(` ${pattern.subject} ${pattern.predicate} ${pattern.object} .`);
|
|
297
|
+
}
|
|
298
|
+
lines.push('}');
|
|
299
|
+
|
|
300
|
+
// ORDER BY
|
|
301
|
+
if (orderBy && orderBy.length > 0) {
|
|
302
|
+
const orderClauses = orderBy.map(
|
|
303
|
+
(o) => `${o.direction || 'ASC'}(${o.variable})`
|
|
304
|
+
);
|
|
305
|
+
lines.push(`ORDER BY ${orderClauses.join(' ')}`);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
// LIMIT and OFFSET
|
|
309
|
+
if (limit) {
|
|
310
|
+
lines.push(`LIMIT ${limit}`);
|
|
311
|
+
}
|
|
312
|
+
if (offset > 0) {
|
|
313
|
+
lines.push(`OFFSET ${offset}`);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return lines.join('\n');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Render template with RDF context
|
|
321
|
+
* @param {string} template - Template string
|
|
322
|
+
* @param {Object} context - Rendering context
|
|
323
|
+
* @returns {string} Rendered output
|
|
324
|
+
*/
|
|
325
|
+
render(template, context = {}) {
|
|
326
|
+
const validated = RdfRenderContextSchema.parse({
|
|
327
|
+
data: context,
|
|
328
|
+
prefixes: context.prefixes,
|
|
329
|
+
store: context.store || this.store,
|
|
330
|
+
baseUri: context.baseUri,
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Merge context with RDF utilities
|
|
334
|
+
const renderContext = {
|
|
335
|
+
...validated.data,
|
|
336
|
+
prefixes: { ...this.prefixes, ...validated.prefixes },
|
|
337
|
+
store: validated.store,
|
|
338
|
+
baseUri: validated.baseUri,
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
return this.env.renderString(template, renderContext);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Render template from file
|
|
346
|
+
* @param {string} templatePath - Path to template file
|
|
347
|
+
* @param {Object} context - Rendering context
|
|
348
|
+
* @returns {string} Rendered output
|
|
349
|
+
*/
|
|
350
|
+
renderFile(templatePath, context = {}) {
|
|
351
|
+
const validated = RdfRenderContextSchema.parse({
|
|
352
|
+
data: context,
|
|
353
|
+
prefixes: context.prefixes,
|
|
354
|
+
store: context.store || this.store,
|
|
355
|
+
baseUri: context.baseUri,
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
const renderContext = {
|
|
359
|
+
...validated.data,
|
|
360
|
+
prefixes: { ...this.prefixes, ...validated.prefixes },
|
|
361
|
+
store: validated.store,
|
|
362
|
+
baseUri: validated.baseUri,
|
|
363
|
+
};
|
|
364
|
+
|
|
365
|
+
return this.env.render(templatePath, renderContext);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Add custom prefix mapping
|
|
370
|
+
* @param {string} prefix - Prefix name
|
|
371
|
+
* @param {string} uri - Namespace URI
|
|
372
|
+
*/
|
|
373
|
+
addPrefix(prefix, uri) {
|
|
374
|
+
z.string().min(1).parse(prefix);
|
|
375
|
+
z.string().url().parse(uri);
|
|
376
|
+
|
|
377
|
+
this.prefixes[prefix] = uri;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Get RDF store instance
|
|
382
|
+
* @returns {Object|null} RDF store or null if disabled
|
|
383
|
+
*/
|
|
384
|
+
getStore() {
|
|
385
|
+
return this.store;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Get Nunjucks environment
|
|
390
|
+
* @returns {Object} Nunjucks environment
|
|
391
|
+
*/
|
|
392
|
+
getEnvironment() {
|
|
393
|
+
return this.env;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Create RDF template engine instance
|
|
399
|
+
* @param {Object} config - Engine configuration
|
|
400
|
+
* @returns {RdfTemplateEngine} RDF template engine
|
|
401
|
+
*/
|
|
402
|
+
export function createRdfTemplateEngine(config = {}) {
|
|
403
|
+
return new RdfTemplateEngine(config);
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* Render RDF template (convenience function)
|
|
408
|
+
* @param {string} template - Template string
|
|
409
|
+
* @param {Object} context - Rendering context
|
|
410
|
+
* @param {Object} config - Engine configuration
|
|
411
|
+
* @returns {string} Rendered output
|
|
412
|
+
*/
|
|
413
|
+
export function renderRdfTemplate(template, context = {}, config = {}) {
|
|
414
|
+
const engine = new RdfTemplateEngine(config);
|
|
415
|
+
return engine.render(template, context);
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* Export RDF template filters
|
|
420
|
+
*/
|
|
421
|
+
export {
|
|
422
|
+
rdfTemplateFilters,
|
|
423
|
+
toTurtle,
|
|
424
|
+
toSparql,
|
|
425
|
+
rdfPrefix,
|
|
426
|
+
blankNode,
|
|
427
|
+
literal,
|
|
428
|
+
} from './filters.js';
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Export schemas for external validation
|
|
432
|
+
*/
|
|
433
|
+
export {
|
|
434
|
+
RdfTemplateEngineConfigSchema,
|
|
435
|
+
RdfRenderContextSchema,
|
|
436
|
+
SparqlTemplateSchema,
|
|
437
|
+
};
|
|
438
|
+
|
|
439
|
+
export default {
|
|
440
|
+
RdfTemplateEngine,
|
|
441
|
+
createRdfTemplateEngine,
|
|
442
|
+
renderRdfTemplate,
|
|
443
|
+
rdfTemplateFilters,
|
|
444
|
+
};
|
|
@@ -5,7 +5,13 @@
|
|
|
5
5
|
|
|
6
6
|
import crypto from 'crypto';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
*
|
|
10
|
+
*/
|
|
8
11
|
export class DeterministicRenderer {
|
|
12
|
+
/**
|
|
13
|
+
*
|
|
14
|
+
*/
|
|
9
15
|
constructor(options = {}) {
|
|
10
16
|
this.staticBuildTime = options.staticBuildTime || '2024-01-01T00:00:00.000Z';
|
|
11
17
|
this.blockNonDeterministic = options.blockNonDeterministic !== false;
|
package/src/renderer/index.js
CHANGED