@nuasite/cli 0.49.1 → 0.50.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/dist/index.js +144 -13
- package/dist/types/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -22517,7 +22517,14 @@ function parseConfigSource(source, _sourcePath) {
|
|
|
22517
22517
|
const loaderBase = loaderOptions.base;
|
|
22518
22518
|
const cmsProperty = decl.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "cms");
|
|
22519
22519
|
const layout = cmsProperty?.type === "ObjectProperty" ? parseCmsLayout(cmsProperty.value, bindings) : undefined;
|
|
22520
|
-
const
|
|
22520
|
+
const declaredPathname = cmsProperty?.type === "ObjectProperty" ? parseCmsPathname(cmsProperty.value, bindings) : undefined;
|
|
22521
|
+
const titleField = cmsProperty?.type === "ObjectProperty" ? parseCmsTitleField(cmsProperty.value, bindings) : undefined;
|
|
22522
|
+
const fragment = cmsProperty?.type === "ObjectProperty" ? parseCmsFragment(cmsProperty.value, bindings) : undefined;
|
|
22523
|
+
const previewOf = cmsProperty?.type === "ObjectProperty" ? parseCmsPreviewOf(cmsProperty.value, bindings) : undefined;
|
|
22524
|
+
if (fragment && declaredPathname) {
|
|
22525
|
+
console.warn(`[cms] collection "${collectionName}": \`cms.fragment\` and \`cms.pathname\` are mutually exclusive \u2014 a fragment collection has no page of its own, so the \`pathname\` rule is ignored`);
|
|
22526
|
+
}
|
|
22527
|
+
const pathname = fragment ? undefined : declaredPathname;
|
|
22521
22528
|
const schemaProperty = decl.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "schema");
|
|
22522
22529
|
if (!schemaProperty || schemaProperty.type !== "ObjectProperty") {
|
|
22523
22530
|
if (!loaderPattern)
|
|
@@ -22528,7 +22535,10 @@ function parseConfigSource(source, _sourcePath) {
|
|
|
22528
22535
|
loaderPattern,
|
|
22529
22536
|
loaderBase,
|
|
22530
22537
|
layout,
|
|
22531
|
-
pathname
|
|
22538
|
+
pathname,
|
|
22539
|
+
titleField,
|
|
22540
|
+
fragment,
|
|
22541
|
+
previewOf
|
|
22532
22542
|
});
|
|
22533
22543
|
continue;
|
|
22534
22544
|
}
|
|
@@ -22542,7 +22552,10 @@ function parseConfigSource(source, _sourcePath) {
|
|
|
22542
22552
|
loaderPattern,
|
|
22543
22553
|
loaderBase,
|
|
22544
22554
|
layout,
|
|
22545
|
-
pathname
|
|
22555
|
+
pathname,
|
|
22556
|
+
titleField,
|
|
22557
|
+
fragment,
|
|
22558
|
+
previewOf
|
|
22546
22559
|
});
|
|
22547
22560
|
continue;
|
|
22548
22561
|
}
|
|
@@ -22552,7 +22565,10 @@ function parseConfigSource(source, _sourcePath) {
|
|
|
22552
22565
|
loaderPattern,
|
|
22553
22566
|
loaderBase,
|
|
22554
22567
|
layout,
|
|
22555
|
-
pathname
|
|
22568
|
+
pathname,
|
|
22569
|
+
titleField,
|
|
22570
|
+
fragment,
|
|
22571
|
+
previewOf
|
|
22556
22572
|
});
|
|
22557
22573
|
}
|
|
22558
22574
|
return result;
|
|
@@ -22635,6 +22651,40 @@ function parseCmsPathname(node, bindings) {
|
|
|
22635
22651
|
}
|
|
22636
22652
|
return spec.length > 0 ? spec : undefined;
|
|
22637
22653
|
}
|
|
22654
|
+
function parseCmsTitleField(node, bindings) {
|
|
22655
|
+
const resolved = resolveExpression(node, bindings);
|
|
22656
|
+
if (resolved.type !== "ObjectExpression")
|
|
22657
|
+
return;
|
|
22658
|
+
const titleFieldProp = resolved.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "titleField");
|
|
22659
|
+
if (!titleFieldProp || titleFieldProp.type !== "ObjectProperty")
|
|
22660
|
+
return;
|
|
22661
|
+
const value = resolveExpression(titleFieldProp.value, bindings);
|
|
22662
|
+
if (value.type !== "StringLiteral" || value.value === "")
|
|
22663
|
+
return;
|
|
22664
|
+
return value.value;
|
|
22665
|
+
}
|
|
22666
|
+
function parseCmsFragment(node, bindings) {
|
|
22667
|
+
const resolved = resolveExpression(node, bindings);
|
|
22668
|
+
if (resolved.type !== "ObjectExpression")
|
|
22669
|
+
return;
|
|
22670
|
+
const fragmentProp = resolved.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "fragment");
|
|
22671
|
+
if (!fragmentProp || fragmentProp.type !== "ObjectProperty")
|
|
22672
|
+
return;
|
|
22673
|
+
const value = resolveExpression(fragmentProp.value, bindings);
|
|
22674
|
+
return value.type === "BooleanLiteral" && value.value ? true : undefined;
|
|
22675
|
+
}
|
|
22676
|
+
function parseCmsPreviewOf(node, bindings) {
|
|
22677
|
+
const resolved = resolveExpression(node, bindings);
|
|
22678
|
+
if (resolved.type !== "ObjectExpression")
|
|
22679
|
+
return;
|
|
22680
|
+
const previewOfProp = resolved.properties.find((p) => p.type === "ObjectProperty" && propertyKeyName(p.key) === "previewOf");
|
|
22681
|
+
if (!previewOfProp || previewOfProp.type !== "ObjectProperty")
|
|
22682
|
+
return;
|
|
22683
|
+
const value = resolveExpression(previewOfProp.value, bindings);
|
|
22684
|
+
if (value.type !== "StringLiteral" || value.value === "")
|
|
22685
|
+
return;
|
|
22686
|
+
return value.value;
|
|
22687
|
+
}
|
|
22638
22688
|
function parsePathnameSegment(node) {
|
|
22639
22689
|
if (node.type !== "ObjectExpression")
|
|
22640
22690
|
return null;
|
|
@@ -22838,6 +22888,12 @@ function analyzeBaseCall(node, field, bindings) {
|
|
|
22838
22888
|
field.options = options;
|
|
22839
22889
|
}
|
|
22840
22890
|
}
|
|
22891
|
+
const hintsArg = node.arguments[1];
|
|
22892
|
+
if (hintsArg?.type === "ObjectExpression") {
|
|
22893
|
+
const layout = parseFieldLayoutFromObject(hintsArg);
|
|
22894
|
+
if (layout)
|
|
22895
|
+
field.layout = layout;
|
|
22896
|
+
}
|
|
22841
22897
|
return;
|
|
22842
22898
|
}
|
|
22843
22899
|
if ((ns === "z" || ns === "n") && fn === "object") {
|
|
@@ -23030,6 +23086,18 @@ import path from "path";
|
|
|
23030
23086
|
function normalizeFieldName(name) {
|
|
23031
23087
|
return name.toLowerCase().replace(/[_-]/g, "");
|
|
23032
23088
|
}
|
|
23089
|
+
function deriveEntryTitle(data, titleField) {
|
|
23090
|
+
if (titleField) {
|
|
23091
|
+
const declared = data[titleField];
|
|
23092
|
+
return typeof declared === "string" && declared !== "" ? declared : undefined;
|
|
23093
|
+
}
|
|
23094
|
+
for (const key of TITLE_FALLBACK_FIELDS) {
|
|
23095
|
+
const value = data[key];
|
|
23096
|
+
if (typeof value === "string" && value !== "")
|
|
23097
|
+
return value;
|
|
23098
|
+
}
|
|
23099
|
+
return;
|
|
23100
|
+
}
|
|
23033
23101
|
function extractFrontmatterBlock(content) {
|
|
23034
23102
|
const match = content.match(FRONTMATTER_PATTERN);
|
|
23035
23103
|
return match?.[1] ?? null;
|
|
@@ -23263,8 +23331,9 @@ async function buildCollectionDefinition(fs, basePath, sources, collectionName,
|
|
|
23263
23331
|
sourcePath: path.join(sourceBasePath, source.relPath)
|
|
23264
23332
|
};
|
|
23265
23333
|
if (frontmatter) {
|
|
23266
|
-
|
|
23267
|
-
|
|
23334
|
+
const title = deriveEntryTitle(frontmatter);
|
|
23335
|
+
if (title !== undefined) {
|
|
23336
|
+
entryInfo.title = title;
|
|
23268
23337
|
}
|
|
23269
23338
|
if (typeof frontmatter.draft === "boolean" && frontmatter.draft) {
|
|
23270
23339
|
entryInfo.draft = true;
|
|
@@ -23307,7 +23376,7 @@ async function buildDataCollectionDefinition(fs, basePath, sources, collectionNa
|
|
|
23307
23376
|
}
|
|
23308
23377
|
if (!data || typeof data !== "object")
|
|
23309
23378
|
continue;
|
|
23310
|
-
const title =
|
|
23379
|
+
const title = deriveEntryTitle(data);
|
|
23311
23380
|
entryInfos.push({
|
|
23312
23381
|
slug: source.slug,
|
|
23313
23382
|
title,
|
|
@@ -23389,8 +23458,25 @@ function applyParsedConfig(collections, parsed) {
|
|
|
23389
23458
|
def.layout = parsedColl.layout;
|
|
23390
23459
|
if (parsedColl.pathname)
|
|
23391
23460
|
def.pathname = parsedColl.pathname;
|
|
23461
|
+
if (parsedColl.fragment) {
|
|
23462
|
+
def.fragment = parsedColl.fragment;
|
|
23463
|
+
if (parsedColl.previewOf)
|
|
23464
|
+
def.previewOf = parsedColl.previewOf;
|
|
23465
|
+
}
|
|
23466
|
+
if (parsedColl.titleField) {
|
|
23467
|
+
def.titleField = parsedColl.titleField;
|
|
23468
|
+
applyCollectionTitleField(def, parsedColl.titleField);
|
|
23469
|
+
}
|
|
23392
23470
|
}
|
|
23393
23471
|
}
|
|
23472
|
+
function applyCollectionTitleField(def, titleField) {
|
|
23473
|
+
if (!def.entries)
|
|
23474
|
+
return;
|
|
23475
|
+
for (const entry of def.entries) {
|
|
23476
|
+
entry.title = entry.data ? deriveEntryTitle(entry.data, titleField) : undefined;
|
|
23477
|
+
}
|
|
23478
|
+
def.entries.sort((a, b) => (a.title ?? a.slug).localeCompare(b.title ?? b.slug));
|
|
23479
|
+
}
|
|
23394
23480
|
function applyParsedFieldLayout(field, pf) {
|
|
23395
23481
|
const layout = pf.layout;
|
|
23396
23482
|
if (!layout)
|
|
@@ -23413,8 +23499,10 @@ function applyParsedFieldLayout(field, pf) {
|
|
|
23413
23499
|
function applyParsedFieldOverrides(field, pf) {
|
|
23414
23500
|
if (pf.type) {
|
|
23415
23501
|
field.type = pf.type;
|
|
23416
|
-
if (pf.options)
|
|
23502
|
+
if (pf.options) {
|
|
23417
23503
|
field.options = pf.options;
|
|
23504
|
+
field.optionsClosed = true;
|
|
23505
|
+
}
|
|
23418
23506
|
}
|
|
23419
23507
|
if (pf.itemType)
|
|
23420
23508
|
field.itemType = pf.itemType;
|
|
@@ -23442,8 +23530,10 @@ function parsedFieldToFieldDefinition(pf) {
|
|
|
23442
23530
|
type: pf.type ?? (pf.fields ? "object" : "text"),
|
|
23443
23531
|
required: pf.required
|
|
23444
23532
|
};
|
|
23445
|
-
if (pf.options)
|
|
23533
|
+
if (pf.options) {
|
|
23446
23534
|
fd.options = pf.options;
|
|
23535
|
+
fd.optionsClosed = true;
|
|
23536
|
+
}
|
|
23447
23537
|
if (pf.itemType)
|
|
23448
23538
|
fd.itemType = pf.itemType;
|
|
23449
23539
|
if (pf.hints)
|
|
@@ -23679,6 +23769,26 @@ async function scanDataCollection(fs, collectionPath, collectionName, contentDir
|
|
|
23679
23769
|
}
|
|
23680
23770
|
return await buildDataCollectionDefinition(fs, collectionPath, sources, collectionName, contentDir);
|
|
23681
23771
|
}
|
|
23772
|
+
function normalizeBasePath(basePath) {
|
|
23773
|
+
return path.normalize(basePath.replace(/^\.[/\\]+/, "")).replace(/[/\\]+$/, "");
|
|
23774
|
+
}
|
|
23775
|
+
function patternCoversWholeCollection(pattern, definition) {
|
|
23776
|
+
const match = pattern.trim().replace(/^\.[/\\]+/, "").match(WHOLE_DIRECTORY_PATTERN);
|
|
23777
|
+
if (!match)
|
|
23778
|
+
return false;
|
|
23779
|
+
const [, braceGroup, singleExtension] = match;
|
|
23780
|
+
if (braceGroup === undefined && singleExtension === undefined)
|
|
23781
|
+
return true;
|
|
23782
|
+
const patternExtensions = new Set((braceGroup !== undefined ? braceGroup.split(",") : [singleExtension]).map((ext) => ext.trim().replace(/^\./, "").toLowerCase()).filter(Boolean));
|
|
23783
|
+
const scannedExtensions = new Set((definition.entries ?? []).map((entry) => path.extname(entry.sourcePath).slice(1).toLowerCase()).filter(Boolean));
|
|
23784
|
+
if (scannedExtensions.size === 0)
|
|
23785
|
+
return false;
|
|
23786
|
+
for (const ext of scannedExtensions) {
|
|
23787
|
+
if (!patternExtensions.has(ext))
|
|
23788
|
+
return false;
|
|
23789
|
+
}
|
|
23790
|
+
return true;
|
|
23791
|
+
}
|
|
23682
23792
|
async function scanCollections(fs, contentDir = "src/content", parseCache = new Map) {
|
|
23683
23793
|
const collections = {};
|
|
23684
23794
|
const entries = await fs.list(contentDir);
|
|
@@ -23695,11 +23805,29 @@ async function scanCollections(fs, contentDir = "src/content", parseCache = new
|
|
|
23695
23805
|
});
|
|
23696
23806
|
await Promise.all(scanPromises);
|
|
23697
23807
|
const parsed = await parseContentConfig(fs, parseCache);
|
|
23808
|
+
const scannedNameByBasePath = new Map;
|
|
23809
|
+
for (const [name, definition] of Object.entries(collections)) {
|
|
23810
|
+
scannedNameByBasePath.set(normalizeBasePath(definition.path), name);
|
|
23811
|
+
}
|
|
23812
|
+
const rekeyedScannedNames = new Map;
|
|
23698
23813
|
for (const [collectionName, parsedCollection] of parsed) {
|
|
23699
23814
|
if (collections[collectionName])
|
|
23700
23815
|
continue;
|
|
23701
23816
|
if (!parsedCollection.loaderBase || !parsedCollection.loaderPattern)
|
|
23702
23817
|
continue;
|
|
23818
|
+
const scannedName = scannedNameByBasePath.get(normalizeBasePath(parsedCollection.loaderBase));
|
|
23819
|
+
const scannedDefinition = scannedName ? collections[scannedName] : undefined;
|
|
23820
|
+
if (scannedName && scannedDefinition && patternCoversWholeCollection(parsedCollection.loaderPattern, scannedDefinition)) {
|
|
23821
|
+
delete collections[scannedName];
|
|
23822
|
+
scannedDefinition.name = collectionName;
|
|
23823
|
+
for (const other of Object.values(collections)) {
|
|
23824
|
+
if (other.parentCollection === scannedName)
|
|
23825
|
+
other.parentCollection = collectionName;
|
|
23826
|
+
}
|
|
23827
|
+
collections[collectionName] = scannedDefinition;
|
|
23828
|
+
rekeyedScannedNames.set(scannedName, collectionName);
|
|
23829
|
+
continue;
|
|
23830
|
+
}
|
|
23703
23831
|
let definition;
|
|
23704
23832
|
try {
|
|
23705
23833
|
definition = await scanGlobCollection(fs, collectionName, parsedCollection.loaderBase, parsedCollection.loaderPattern, contentDir);
|
|
@@ -23710,8 +23838,9 @@ async function scanCollections(fs, contentDir = "src/content", parseCache = new
|
|
|
23710
23838
|
if (!definition)
|
|
23711
23839
|
continue;
|
|
23712
23840
|
const baseName = parsedCollection.loaderBase.replace(/[/\\]+$/, "").split(/[/\\]/).pop();
|
|
23713
|
-
|
|
23714
|
-
|
|
23841
|
+
const parentName = !baseName ? undefined : collections[baseName] ? baseName : rekeyedScannedNames.get(baseName);
|
|
23842
|
+
if (parentName && parentName !== collectionName) {
|
|
23843
|
+
definition.parentCollection = parentName;
|
|
23715
23844
|
}
|
|
23716
23845
|
collections[collectionName] = definition;
|
|
23717
23846
|
}
|
|
@@ -23741,7 +23870,7 @@ function warnOnPathnameCollisions(collections) {
|
|
|
23741
23870
|
}
|
|
23742
23871
|
}
|
|
23743
23872
|
}
|
|
23744
|
-
var import_yaml, DATE_PATTERN, URL_PATTERN, IMAGE_EXTENSIONS, MAX_SELECT_OPTIONS = 10, TEXTAREA_MIN_LENGTH = 200, SIDEBAR_FIELD_NAMES, DIRECTIVE_PATTERN, FREE_TEXT_FIELD_NAMES, PUBLISH_TOGGLE_NAMES, PUBLISH_DATE_NAMES, FRONTMATTER_PATTERN, MAX_NESTED_FIELD_DEPTH = 16, HREF_SUFFIXES;
|
|
23873
|
+
var import_yaml, DATE_PATTERN, URL_PATTERN, IMAGE_EXTENSIONS, MAX_SELECT_OPTIONS = 10, TEXTAREA_MIN_LENGTH = 200, SIDEBAR_FIELD_NAMES, DIRECTIVE_PATTERN, FREE_TEXT_FIELD_NAMES, PUBLISH_TOGGLE_NAMES, PUBLISH_DATE_NAMES, TITLE_FALLBACK_FIELDS, FRONTMATTER_PATTERN, MAX_NESTED_FIELD_DEPTH = 16, HREF_SUFFIXES, WHOLE_DIRECTORY_PATTERN;
|
|
23745
23874
|
var init_collection_scanner = __esm(() => {
|
|
23746
23875
|
init_content_config_ast();
|
|
23747
23876
|
import_yaml = __toESM(require_dist(), 1);
|
|
@@ -23785,8 +23914,10 @@ var init_collection_scanner = __esm(() => {
|
|
|
23785
23914
|
"publishedat",
|
|
23786
23915
|
"datepublished"
|
|
23787
23916
|
]);
|
|
23917
|
+
TITLE_FALLBACK_FIELDS = ["title", "name", "label"];
|
|
23788
23918
|
FRONTMATTER_PATTERN = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
23789
23919
|
HREF_SUFFIXES = ["href", "url", "link", "slug", "path"];
|
|
23920
|
+
WHOLE_DIRECTORY_PATTERN = /^(?:\*\*[/\\])*\*(?:\.(?:\{([^{}/\\]*)\}|([A-Za-z0-9]+)))?$/;
|
|
23790
23921
|
});
|
|
23791
23922
|
|
|
23792
23923
|
// ../cms-core/src/component-registry.ts
|
|
@@ -24368,7 +24499,7 @@ var init_scan_cache = __esm(() => {
|
|
|
24368
24499
|
|
|
24369
24500
|
// ../cms/src/shared.ts
|
|
24370
24501
|
function slugify2(text) {
|
|
24371
|
-
return text.toLowerCase().trim().replace(/[^\w\s\-/]/g, "").replace(/[\s_]+/g, "-").replace(/^[-/]+|[-/]+$/g, "");
|
|
24502
|
+
return text.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim().replace(/[^\w\s\-/]/g, "").replace(/[\s_]+/g, "-").replace(/^[-/]+|[-/]+$/g, "");
|
|
24372
24503
|
}
|
|
24373
24504
|
|
|
24374
24505
|
// ../cms/src/utils.ts
|