@im-nobsidian/core 0.1.9 → 0.1.11
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.d.ts +50 -1
- package/dist/index.js +240 -6
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -605,6 +605,19 @@ declare class NotionClient {
|
|
|
605
605
|
id: string;
|
|
606
606
|
type: string;
|
|
607
607
|
}>>;
|
|
608
|
+
getDatabaseSchemaFull(databaseId: string): Promise<Record<string, {
|
|
609
|
+
id: string;
|
|
610
|
+
type: string;
|
|
611
|
+
options?: Array<{
|
|
612
|
+
name: string;
|
|
613
|
+
color?: string;
|
|
614
|
+
}>;
|
|
615
|
+
groups?: Array<{
|
|
616
|
+
name: string;
|
|
617
|
+
color?: string;
|
|
618
|
+
optionIds?: string[];
|
|
619
|
+
}>;
|
|
620
|
+
}>>;
|
|
608
621
|
queryDatabase(databaseId: string, options?: {
|
|
609
622
|
startCursor?: string;
|
|
610
623
|
pageSize?: number;
|
|
@@ -1003,11 +1016,13 @@ declare class DatabaseSyncer {
|
|
|
1003
1016
|
private readonly pipeline;
|
|
1004
1017
|
private readonly imageHandler;
|
|
1005
1018
|
private readonly propertyMapper;
|
|
1019
|
+
private readonly baseFileGenerator;
|
|
1006
1020
|
constructor(config: Config, stateDb: IStateDB, notionClient: NotionClient, vaultFs: VaultFS, pipeline: ConversionPipeline, imageHandler: ImageHandler);
|
|
1007
1021
|
pullAll(): Promise<DatabaseSyncResult>;
|
|
1008
1022
|
pushAll(): Promise<DatabaseSyncResult>;
|
|
1009
1023
|
pullDatabase(dbConfig: DatabaseSyncConfig): Promise<DatabaseSyncResult>;
|
|
1010
1024
|
private pullDatabaseViews;
|
|
1025
|
+
private generateBaseFile;
|
|
1011
1026
|
private pullDatabasePage;
|
|
1012
1027
|
private pushDatabase;
|
|
1013
1028
|
}
|
|
@@ -1341,6 +1356,40 @@ declare class EntryEditor {
|
|
|
1341
1356
|
updateDate(entryPath: string, dateProperty: string, newDate: string): Promise<void>;
|
|
1342
1357
|
}
|
|
1343
1358
|
|
|
1359
|
+
interface BasePropertySchema {
|
|
1360
|
+
readonly id: string;
|
|
1361
|
+
readonly type: string;
|
|
1362
|
+
readonly options?: Array<{
|
|
1363
|
+
name: string;
|
|
1364
|
+
color?: string;
|
|
1365
|
+
}>;
|
|
1366
|
+
readonly groups?: Array<{
|
|
1367
|
+
name: string;
|
|
1368
|
+
color?: string;
|
|
1369
|
+
optionIds?: string[];
|
|
1370
|
+
}>;
|
|
1371
|
+
}
|
|
1372
|
+
interface BaseFileOptions {
|
|
1373
|
+
readonly databaseId: string;
|
|
1374
|
+
readonly databaseName: string;
|
|
1375
|
+
readonly schema: Record<string, BasePropertySchema>;
|
|
1376
|
+
readonly viewsConfig: DatabaseViewsConfig;
|
|
1377
|
+
readonly folderPath: string;
|
|
1378
|
+
}
|
|
1379
|
+
declare class BaseFileGenerator {
|
|
1380
|
+
generate(options: BaseFileOptions): string;
|
|
1381
|
+
private writeFilters;
|
|
1382
|
+
private needsContentCoverFormula;
|
|
1383
|
+
private writeFormulas;
|
|
1384
|
+
private writePropertyDisplayNames;
|
|
1385
|
+
private writeViews;
|
|
1386
|
+
private convertView;
|
|
1387
|
+
private toNoteRef;
|
|
1388
|
+
private resolvePropertyName;
|
|
1389
|
+
private yamlKey;
|
|
1390
|
+
private yamlValue;
|
|
1391
|
+
}
|
|
1392
|
+
|
|
1344
1393
|
declare function sortEntries(entries: DBEntry[], sorts: NonNullable<ViewConfig["sorts"]>): DBEntry[];
|
|
1345
1394
|
declare function groupEntries(entries: DBEntry[], groupByProperty: string, options?: {
|
|
1346
1395
|
sort?: "ascending" | "descending";
|
|
@@ -1388,4 +1437,4 @@ interface PipelineOptions {
|
|
|
1388
1437
|
}
|
|
1389
1438
|
declare function createDefaultPipeline(options?: PipelineOptions): ConversionPipeline;
|
|
1390
1439
|
|
|
1391
|
-
export { BlockConverter, type CalendarEntry, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, type Config, ConfigManager, ConfigSchema, type Conflict, ConflictResolver, type ConflictStrategy, type ConversionContext, type ConversionPath, ConversionPipeline, type ConversionResult, type CoverConfig, type DBEntry, DEFAULT_CONFIG, type DatabaseSyncConfig, type DatabaseSyncResult, DatabaseSyncer, type DatabaseViewsConfig, EmbedResolver, EntryEditor, type FailedOperation, type FileDownloadResult, FileHandler, type FileInfo, type FileRegistryEntry, type FileStatInfo, type FileSystemEntry, type FileType, type FileUploadResult, FileWatcher, type FilterCondition, FrontmatterExtractor, FrontmatterGenerator, type GroupByConfig, type GroupedEntries, HtmlAnnotationStripper, type IStateDB, type ImageDownloadResult, ImageHandler, type ImageReference, InlineDBParser, type LocalChange, LocalImageRestorer, type Logger, type MappingResult, type MappingType, MathNormalizer, MentionToWikilink, type MergeConflictRegion, type MergeResult, NodeVaultFS, type NonMdFileInfo, type NotionBlock, NotionBlockBuilder, NotionClient, type NotionClientOptions, type NotionColor, type NotionPageNode, type NotionRichText, type RichTextItem as NotionRichTextItem, type OperationType, type PageCover, type PageCreationPlan, type PageIcon, type PathFilterConfig, type PreserveMarker, PreserveMarkerCollector, PreserveMarkerInjector, type Processor, type ProcessorInput, type ProcessorMetadata, type ProcessorOutput, type ProgressCallback, type ProgressItem, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, type PropertyOption, type PropertySchema, type PropertyValue, type PullOptions, type PullResult, type PushOptions, type PushResult, type RegisterFileInput, type RemoteChange, type ResolutionChoice, type ResolutionResult, type RichTextSegment, StateDB, type StatusResult, type SyncDirection, type SyncOptions, SyncOrchestrator, type SyncRecord, type SyncResult, type SyncStatus, TreeMapper, UnsupportedBlockStripper, type UpsertSyncRecord, type VaultFS, type ViewConfig, ViewDataProvider, type ViewPropertyConfig, type ViewRenderData, type ViewType, type WatchSyncOptions, WatchSyncService, type WikilinkEntry, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
|
|
1440
|
+
export { BaseFileGenerator, type BaseFileOptions, type BasePropertySchema, BlockConverter, type CalendarEntry, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, type Config, ConfigManager, ConfigSchema, type Conflict, ConflictResolver, type ConflictStrategy, type ConversionContext, type ConversionPath, ConversionPipeline, type ConversionResult, type CoverConfig, type DBEntry, DEFAULT_CONFIG, type DatabaseSyncConfig, type DatabaseSyncResult, DatabaseSyncer, type DatabaseViewsConfig, EmbedResolver, EntryEditor, type FailedOperation, type FileDownloadResult, FileHandler, type FileInfo, type FileRegistryEntry, type FileStatInfo, type FileSystemEntry, type FileType, type FileUploadResult, FileWatcher, type FilterCondition, FrontmatterExtractor, FrontmatterGenerator, type GroupByConfig, type GroupedEntries, HtmlAnnotationStripper, type IStateDB, type ImageDownloadResult, ImageHandler, type ImageReference, InlineDBParser, type LocalChange, LocalImageRestorer, type Logger, type MappingResult, type MappingType, MathNormalizer, MentionToWikilink, type MergeConflictRegion, type MergeResult, NodeVaultFS, type NonMdFileInfo, type NotionBlock, NotionBlockBuilder, NotionClient, type NotionClientOptions, type NotionColor, type NotionPageNode, type NotionRichText, type RichTextItem as NotionRichTextItem, type OperationType, type PageCover, type PageCreationPlan, type PageIcon, type PathFilterConfig, type PreserveMarker, PreserveMarkerCollector, PreserveMarkerInjector, type Processor, type ProcessorInput, type ProcessorMetadata, type ProcessorOutput, type ProgressCallback, type ProgressItem, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, type PropertyOption, type PropertySchema, type PropertyValue, type PullOptions, type PullResult, type PushOptions, type PushResult, type RegisterFileInput, type RemoteChange, type ResolutionChoice, type ResolutionResult, type RichTextSegment, StateDB, type StatusResult, type SyncDirection, type SyncOptions, SyncOrchestrator, type SyncRecord, type SyncResult, type SyncStatus, TreeMapper, UnsupportedBlockStripper, type UpsertSyncRecord, type VaultFS, type ViewConfig, ViewDataProvider, type ViewPropertyConfig, type ViewRenderData, type ViewType, type WatchSyncOptions, WatchSyncService, type WikilinkEntry, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
|
package/dist/index.js
CHANGED
|
@@ -940,6 +940,39 @@ var NotionClient = class _NotionClient {
|
|
|
940
940
|
}
|
|
941
941
|
return schema;
|
|
942
942
|
}
|
|
943
|
+
async getDatabaseSchemaFull(databaseId) {
|
|
944
|
+
const db = await this.fetchDatabaseLegacy(databaseId);
|
|
945
|
+
const properties = db.properties;
|
|
946
|
+
if (!properties) return {};
|
|
947
|
+
const schema = {};
|
|
948
|
+
for (const [name, prop] of Object.entries(properties)) {
|
|
949
|
+
const entry = {
|
|
950
|
+
id: prop.id,
|
|
951
|
+
type: prop.type
|
|
952
|
+
};
|
|
953
|
+
if (prop.type === "select" || prop.type === "multi_select") {
|
|
954
|
+
const typeData = prop[prop.type];
|
|
955
|
+
if (typeData?.options) {
|
|
956
|
+
entry.options = typeData.options.map((o) => ({ name: o.name, color: o.color }));
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
if (prop.type === "status") {
|
|
960
|
+
const statusData = prop.status;
|
|
961
|
+
if (statusData?.options) {
|
|
962
|
+
entry.options = statusData.options.map((o) => ({ name: o.name, color: o.color }));
|
|
963
|
+
}
|
|
964
|
+
if (statusData?.groups) {
|
|
965
|
+
entry.groups = statusData.groups.map((g) => ({
|
|
966
|
+
name: g.name,
|
|
967
|
+
color: g.color,
|
|
968
|
+
optionIds: g.option_ids
|
|
969
|
+
}));
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
schema[name] = entry;
|
|
973
|
+
}
|
|
974
|
+
return schema;
|
|
975
|
+
}
|
|
943
976
|
async queryDatabase(databaseId, options) {
|
|
944
977
|
const dsId = await this.getDataSourceId(databaseId);
|
|
945
978
|
const response = await this.withRateLimit(
|
|
@@ -2816,6 +2849,7 @@ ${COLUMN_LIST_END}`;
|
|
|
2816
2849
|
let processed = this.extractToggleBlocks(markdown);
|
|
2817
2850
|
processed = this.extractColumnBlocks(processed);
|
|
2818
2851
|
processed = this.replaceDividers(processed);
|
|
2852
|
+
processed = processed.replace(/<unknown[^>]*\/>/g, "");
|
|
2819
2853
|
return processed;
|
|
2820
2854
|
}
|
|
2821
2855
|
replaceDividers(markdown) {
|
|
@@ -3768,6 +3802,168 @@ function sanitizeFileName(name) {
|
|
|
3768
3802
|
return sanitized;
|
|
3769
3803
|
}
|
|
3770
3804
|
|
|
3805
|
+
// src/view/base-file-generator.ts
|
|
3806
|
+
var NOTION_TO_BASES_VIEW = {
|
|
3807
|
+
table: "table",
|
|
3808
|
+
gallery: "cards",
|
|
3809
|
+
list: "list",
|
|
3810
|
+
board: "cards",
|
|
3811
|
+
calendar: null,
|
|
3812
|
+
timeline: null,
|
|
3813
|
+
form: null,
|
|
3814
|
+
chart: null,
|
|
3815
|
+
map: null,
|
|
3816
|
+
dashboard: null
|
|
3817
|
+
};
|
|
3818
|
+
var BaseFileGenerator = class {
|
|
3819
|
+
generate(options) {
|
|
3820
|
+
const lines = [];
|
|
3821
|
+
lines.push(`# Auto-generated by Im-Nobsidian from Notion DB: ${options.databaseName}`);
|
|
3822
|
+
lines.push(`# Database ID: ${options.databaseId}`);
|
|
3823
|
+
lines.push("");
|
|
3824
|
+
this.writeFilters(lines, options.folderPath);
|
|
3825
|
+
this.writeFormulas(lines, options.viewsConfig.views);
|
|
3826
|
+
this.writePropertyDisplayNames(lines, options.schema);
|
|
3827
|
+
this.writeViews(lines, options.viewsConfig.views, options.schema);
|
|
3828
|
+
return lines.join("\n");
|
|
3829
|
+
}
|
|
3830
|
+
writeFilters(lines, folderPath) {
|
|
3831
|
+
lines.push("filters:");
|
|
3832
|
+
lines.push(" and:");
|
|
3833
|
+
lines.push(` - file.inFolder("${folderPath}")`);
|
|
3834
|
+
lines.push("");
|
|
3835
|
+
}
|
|
3836
|
+
needsContentCoverFormula(views) {
|
|
3837
|
+
return views.some(
|
|
3838
|
+
(v) => v.type === "gallery" && v.cover && (v.cover.type === "page_content" || v.cover.type === "page_content_first")
|
|
3839
|
+
);
|
|
3840
|
+
}
|
|
3841
|
+
writeFormulas(lines, views) {
|
|
3842
|
+
if (!this.needsContentCoverFormula(views)) return;
|
|
3843
|
+
lines.push("formulas:");
|
|
3844
|
+
lines.push(" coverImage: file.embeds[0]");
|
|
3845
|
+
lines.push("");
|
|
3846
|
+
}
|
|
3847
|
+
writePropertyDisplayNames(lines, schema) {
|
|
3848
|
+
const entries = Object.entries(schema).filter(([, prop]) => prop.type !== "title");
|
|
3849
|
+
if (entries.length === 0) return;
|
|
3850
|
+
lines.push("properties:");
|
|
3851
|
+
for (const [name] of entries) {
|
|
3852
|
+
lines.push(` ${this.yamlKey(name)}:`);
|
|
3853
|
+
lines.push(` displayName: ${this.yamlValue(name)}`);
|
|
3854
|
+
}
|
|
3855
|
+
lines.push("");
|
|
3856
|
+
}
|
|
3857
|
+
writeViews(lines, views, schema) {
|
|
3858
|
+
const basesViews = views.map((v) => this.convertView(v, schema)).filter((v) => v !== null);
|
|
3859
|
+
if (basesViews.length === 0) {
|
|
3860
|
+
lines.push("views:");
|
|
3861
|
+
lines.push(" - type: table");
|
|
3862
|
+
lines.push(" name: Table");
|
|
3863
|
+
return;
|
|
3864
|
+
}
|
|
3865
|
+
lines.push("views:");
|
|
3866
|
+
for (const view of basesViews) {
|
|
3867
|
+
lines.push(` - type: ${view.type}`);
|
|
3868
|
+
lines.push(` name: ${this.yamlValue(view.name)}`);
|
|
3869
|
+
if (view.order && view.order.length > 0) {
|
|
3870
|
+
lines.push(" order:");
|
|
3871
|
+
for (const col of view.order) {
|
|
3872
|
+
lines.push(` - ${col}`);
|
|
3873
|
+
}
|
|
3874
|
+
}
|
|
3875
|
+
if (view.sort && view.sort.length > 0) {
|
|
3876
|
+
lines.push(" sort:");
|
|
3877
|
+
for (const s of view.sort) {
|
|
3878
|
+
lines.push(` - column: ${s.column}`);
|
|
3879
|
+
lines.push(` direction: ${s.direction}`);
|
|
3880
|
+
}
|
|
3881
|
+
}
|
|
3882
|
+
if (view.groupBy) {
|
|
3883
|
+
lines.push(" groupBy:");
|
|
3884
|
+
lines.push(` property: ${view.groupBy.property}`);
|
|
3885
|
+
if (view.groupBy.direction) {
|
|
3886
|
+
lines.push(` direction: ${view.groupBy.direction}`);
|
|
3887
|
+
}
|
|
3888
|
+
}
|
|
3889
|
+
if (view.image) {
|
|
3890
|
+
lines.push(` image: ${view.image}`);
|
|
3891
|
+
}
|
|
3892
|
+
}
|
|
3893
|
+
}
|
|
3894
|
+
convertView(view, schema) {
|
|
3895
|
+
const basesType = NOTION_TO_BASES_VIEW[view.type];
|
|
3896
|
+
if (!basesType) return null;
|
|
3897
|
+
const result = {
|
|
3898
|
+
type: basesType,
|
|
3899
|
+
name: view.name || view.type
|
|
3900
|
+
};
|
|
3901
|
+
if (view.properties && view.properties.length > 0) {
|
|
3902
|
+
const visible = view.properties.filter((p) => p.visible !== false).map((p) => {
|
|
3903
|
+
const name = p.propertyName ?? this.resolvePropertyName(p.propertyId, schema);
|
|
3904
|
+
return name ? this.toNoteRef(name) : null;
|
|
3905
|
+
}).filter((name) => !!name);
|
|
3906
|
+
if (visible.length > 0) {
|
|
3907
|
+
result.order = ["file.name", ...visible];
|
|
3908
|
+
}
|
|
3909
|
+
}
|
|
3910
|
+
if (view.sorts && view.sorts.length > 0) {
|
|
3911
|
+
result.sort = view.sorts.map((s) => {
|
|
3912
|
+
let column;
|
|
3913
|
+
if (s.property) {
|
|
3914
|
+
const propName = this.resolvePropertyName(s.property, schema) ?? s.property;
|
|
3915
|
+
column = this.toNoteRef(propName);
|
|
3916
|
+
} else if (s.timestamp) {
|
|
3917
|
+
column = s.timestamp === "created_time" ? "file.ctime" : "file.mtime";
|
|
3918
|
+
} else {
|
|
3919
|
+
return null;
|
|
3920
|
+
}
|
|
3921
|
+
return {
|
|
3922
|
+
column,
|
|
3923
|
+
direction: s.direction === "ascending" ? "ASC" : "DESC"
|
|
3924
|
+
};
|
|
3925
|
+
}).filter((s) => s !== null);
|
|
3926
|
+
}
|
|
3927
|
+
if (view.groupBy) {
|
|
3928
|
+
const propName = view.groupBy.propertyName ?? this.resolvePropertyName(view.groupBy.propertyId, schema);
|
|
3929
|
+
if (propName) {
|
|
3930
|
+
result.groupBy = {
|
|
3931
|
+
property: this.toNoteRef(propName),
|
|
3932
|
+
direction: view.groupBy.sort === "ascending" ? "ASC" : view.groupBy.sort === "descending" ? "DESC" : void 0
|
|
3933
|
+
};
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
if (view.type === "gallery" && view.cover) {
|
|
3937
|
+
if (view.cover.type === "property" && view.cover.propertyId) {
|
|
3938
|
+
const propName = this.resolvePropertyName(view.cover.propertyId, schema);
|
|
3939
|
+
if (propName) result.image = this.toNoteRef(propName);
|
|
3940
|
+
} else if (view.cover.type === "page_cover") {
|
|
3941
|
+
result.image = "note.cover";
|
|
3942
|
+
} else if (view.cover.type === "page_content" || view.cover.type === "page_content_first") {
|
|
3943
|
+
result.image = "formula.coverImage";
|
|
3944
|
+
}
|
|
3945
|
+
}
|
|
3946
|
+
return result;
|
|
3947
|
+
}
|
|
3948
|
+
toNoteRef(propertyName) {
|
|
3949
|
+
return propertyName;
|
|
3950
|
+
}
|
|
3951
|
+
resolvePropertyName(propertyId, schema) {
|
|
3952
|
+
for (const [name, prop] of Object.entries(schema)) {
|
|
3953
|
+
if (prop.id === propertyId) return name;
|
|
3954
|
+
}
|
|
3955
|
+
return void 0;
|
|
3956
|
+
}
|
|
3957
|
+
yamlKey(key) {
|
|
3958
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(key)) return key;
|
|
3959
|
+
return `"${key.replace(/"/g, '\\"')}"`;
|
|
3960
|
+
}
|
|
3961
|
+
yamlValue(value) {
|
|
3962
|
+
if (/^[a-zA-Z0-9_-]+$/.test(value)) return value;
|
|
3963
|
+
return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
|
|
3964
|
+
}
|
|
3965
|
+
};
|
|
3966
|
+
|
|
3771
3967
|
// src/converter/enhanced-md-converter.ts
|
|
3772
3968
|
var NOTION_CALLOUT_RE = /^::: callout\n([\s\S]*?)\n:::/gm;
|
|
3773
3969
|
var NOTION_CALLOUT_TAG_RE = /<callout[^>]*>\n?([\s\S]*?)<\/callout>/g;
|
|
@@ -3776,6 +3972,7 @@ var NOTION_PAGE_MENTION_RE = /<mention-page id="([^"]+)">([\s\S]*?)<\/mention-pa
|
|
|
3776
3972
|
var NOTION_USER_MENTION_RE = /<mention-user id="[^"]*">([^<]*)<\/mention-user>/g;
|
|
3777
3973
|
var NOTION_DATE_MENTION_RE = /<mention-date start="([^"]*)"(?: end="([^"]*)")?[^>]*\/>/g;
|
|
3778
3974
|
var NOTION_UNKNOWN_RE = /<unknown id="([^"]*)"([^>]*)\/>/g;
|
|
3975
|
+
var NOTION_UNKNOWN_URL_RE = /<unknown url="([^"]*)"([^>]*)\/>/g;
|
|
3779
3976
|
var NOTION_AUDIO_RE = /[\t ]*<audio src="([^"]*)">([\s\S]*?)<\/audio>/g;
|
|
3780
3977
|
var NOTION_VIDEO_RE = /[\t ]*<video src="([^"]*)">([\s\S]*?)<\/video>/g;
|
|
3781
3978
|
var NOTION_PDF_RE = /[\t ]*<pdf src="([^"]*)">([\s\S]*?)<\/pdf>/g;
|
|
@@ -3887,12 +4084,18 @@ function convertDateMentions(content) {
|
|
|
3887
4084
|
});
|
|
3888
4085
|
}
|
|
3889
4086
|
function preserveUnknownBlocks(content) {
|
|
3890
|
-
|
|
4087
|
+
let result = content.replace(NOTION_UNKNOWN_RE, (_match, id, attrs) => {
|
|
3891
4088
|
const typeMatch = /type="([^"]*)"/.exec(attrs);
|
|
3892
4089
|
const altMatch = /alt="([^"]*)"/.exec(attrs);
|
|
3893
4090
|
const blockType = altMatch?.[1] ?? typeMatch?.[1] ?? "unknown";
|
|
3894
4091
|
return `%%im-nobsidian:unknown:id=${id}&type=${blockType}%%`;
|
|
3895
4092
|
});
|
|
4093
|
+
result = result.replace(NOTION_UNKNOWN_URL_RE, (_match, url, attrs) => {
|
|
4094
|
+
const altMatch = /alt="([^"]*)"/.exec(attrs);
|
|
4095
|
+
const blockType = altMatch?.[1] ?? "bookmark";
|
|
4096
|
+
return `%%im-nobsidian:unknown:id=${encodeURIComponent(url)}&type=${blockType}%%`;
|
|
4097
|
+
});
|
|
4098
|
+
return result;
|
|
3896
4099
|
}
|
|
3897
4100
|
function convertSyncedBlockRef(content) {
|
|
3898
4101
|
let result = content.replace(
|
|
@@ -4170,6 +4373,10 @@ function restoreTabBlocks(content) {
|
|
|
4170
4373
|
var OBSIDIAN_UNKNOWN_RE = /%%im-nobsidian:unknown:id=([^&]+)&type=([^%]+)%%/g;
|
|
4171
4374
|
function restoreUnknownBlocks(content) {
|
|
4172
4375
|
return content.replace(OBSIDIAN_UNKNOWN_RE, (_match, id, type) => {
|
|
4376
|
+
const decoded = decodeURIComponent(id);
|
|
4377
|
+
if (decoded.startsWith("http")) {
|
|
4378
|
+
return `<unknown url="${decoded}" alt="${type}"/>`;
|
|
4379
|
+
}
|
|
4173
4380
|
return `<unknown id="${id}" type="${type}"/>`;
|
|
4174
4381
|
});
|
|
4175
4382
|
}
|
|
@@ -4241,6 +4448,7 @@ var DatabaseSyncer = class {
|
|
|
4241
4448
|
pipeline;
|
|
4242
4449
|
imageHandler;
|
|
4243
4450
|
propertyMapper = new PropertyMapper();
|
|
4451
|
+
baseFileGenerator = new BaseFileGenerator();
|
|
4244
4452
|
async pullAll() {
|
|
4245
4453
|
const databases = this.config.notion.databases;
|
|
4246
4454
|
if (!databases || databases.length === 0) {
|
|
@@ -4295,7 +4503,8 @@ var DatabaseSyncer = class {
|
|
|
4295
4503
|
const schema = await this.notionClient.getDatabaseSchema(dbConfig.databaseId);
|
|
4296
4504
|
this.propertyMapper.loadSchema(schema);
|
|
4297
4505
|
await this.vaultFs.ensureFolder(dbConfig.localFolder);
|
|
4298
|
-
await this.pullDatabaseViews(dbConfig);
|
|
4506
|
+
const viewsConfig = await this.pullDatabaseViews(dbConfig);
|
|
4507
|
+
await this.generateBaseFile(dbConfig, viewsConfig);
|
|
4299
4508
|
const pages = await this.notionClient.queryAllDatabasePages(
|
|
4300
4509
|
dbConfig.databaseId,
|
|
4301
4510
|
dbConfig.pullFilter
|
|
@@ -4332,7 +4541,7 @@ var DatabaseSyncer = class {
|
|
|
4332
4541
|
try {
|
|
4333
4542
|
const existing = await this.vaultFs.readFile(configPath);
|
|
4334
4543
|
const parsed = JSON.parse(existing);
|
|
4335
|
-
if (parsed[dbConfig.databaseId]) return;
|
|
4544
|
+
if (parsed[dbConfig.databaseId]) return parsed[dbConfig.databaseId];
|
|
4336
4545
|
} catch {
|
|
4337
4546
|
}
|
|
4338
4547
|
}
|
|
@@ -4349,8 +4558,33 @@ var DatabaseSyncer = class {
|
|
|
4349
4558
|
getLogger().debug(
|
|
4350
4559
|
`[DB Sync] \uBDF0 \uC124\uC815 ${viewsConfig.views.length}\uAC1C \uC800\uC7A5: ${dbConfig.databaseId}`
|
|
4351
4560
|
);
|
|
4561
|
+
return viewsConfig;
|
|
4352
4562
|
} catch (error) {
|
|
4353
4563
|
getLogger().warn(`[DB Sync] \uBDF0 \uC124\uC815 Pull \uC2E4\uD328 (\uACC4\uC18D \uC9C4\uD589):`, error);
|
|
4564
|
+
return null;
|
|
4565
|
+
}
|
|
4566
|
+
}
|
|
4567
|
+
async generateBaseFile(dbConfig, viewsConfig) {
|
|
4568
|
+
try {
|
|
4569
|
+
const schemaFull = await this.notionClient.getDatabaseSchemaFull(dbConfig.databaseId);
|
|
4570
|
+
const dbName = viewsConfig?.databaseName || await this.notionClient.getDatabaseTitle(dbConfig.databaseId) || dbConfig.localFolder.split("/").pop() || "Database";
|
|
4571
|
+
const baseContent = this.baseFileGenerator.generate({
|
|
4572
|
+
databaseId: dbConfig.databaseId,
|
|
4573
|
+
databaseName: dbName,
|
|
4574
|
+
schema: schemaFull,
|
|
4575
|
+
viewsConfig: viewsConfig ?? {
|
|
4576
|
+
databaseId: dbConfig.databaseId,
|
|
4577
|
+
databaseName: dbName,
|
|
4578
|
+
lastSynced: (/* @__PURE__ */ new Date()).toISOString(),
|
|
4579
|
+
views: [{ id: "default", name: "Table", type: "table" }]
|
|
4580
|
+
},
|
|
4581
|
+
folderPath: dbConfig.localFolder
|
|
4582
|
+
});
|
|
4583
|
+
const basePath = `${dbConfig.localFolder}/${sanitizeFileName(dbName)}.base`;
|
|
4584
|
+
await this.vaultFs.writeFile(basePath, baseContent);
|
|
4585
|
+
getLogger().debug(`[DB Sync] .base \uD30C\uC77C \uC0DD\uC131: ${basePath}`);
|
|
4586
|
+
} catch (error) {
|
|
4587
|
+
getLogger().warn(`[DB Sync] .base \uD30C\uC77C \uC0DD\uC131 \uC2E4\uD328 (\uACC4\uC18D \uC9C4\uD589):`, error);
|
|
4354
4588
|
}
|
|
4355
4589
|
}
|
|
4356
4590
|
async pullDatabasePage(page, dbConfig) {
|
|
@@ -4370,7 +4604,7 @@ var DatabaseSyncer = class {
|
|
|
4370
4604
|
);
|
|
4371
4605
|
const localUrlMatch = coverResult.content.match(/!\[cover\]\((.+?)\)/);
|
|
4372
4606
|
if (localUrlMatch?.[1]) {
|
|
4373
|
-
properties.cover = localUrlMatch[1]
|
|
4607
|
+
properties.cover = `[[${localUrlMatch[1]}]]`;
|
|
4374
4608
|
} else {
|
|
4375
4609
|
properties.cover = cover.url;
|
|
4376
4610
|
}
|
|
@@ -5990,7 +6224,7 @@ var NodeVaultFS = class {
|
|
|
5990
6224
|
if (this.isExcluded(relativePath)) continue;
|
|
5991
6225
|
if (entry.isDirectory()) {
|
|
5992
6226
|
await this.walkDirNonMd(fullPath, result);
|
|
5993
|
-
} else if (entry.isFile() && !entry.name.endsWith(".md")) {
|
|
6227
|
+
} else if (entry.isFile() && !entry.name.endsWith(".md") && !entry.name.endsWith(".base")) {
|
|
5994
6228
|
const fileStat = await stat(fullPath);
|
|
5995
6229
|
result.push({
|
|
5996
6230
|
path: relativePath,
|
|
@@ -6871,6 +7105,6 @@ ${lines.join("\n")}
|
|
|
6871
7105
|
}`;
|
|
6872
7106
|
}
|
|
6873
7107
|
|
|
6874
|
-
export { BlockConverter, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, ConfigManager, ConfigSchema, ConflictResolver, ConversionPipeline, DEFAULT_CONFIG, DatabaseSyncer, EmbedResolver, EntryEditor, FileHandler, FileWatcher, FrontmatterExtractor, FrontmatterGenerator, HtmlAnnotationStripper, ImageHandler, InlineDBParser, LocalImageRestorer, MathNormalizer, MentionToWikilink, NodeVaultFS, NotionBlockBuilder, NotionClient, PreserveMarkerCollector, PreserveMarkerInjector, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, StateDB, SyncOrchestrator, TreeMapper, UnsupportedBlockStripper, ViewDataProvider, WatchSyncService, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
|
|
7108
|
+
export { BaseFileGenerator, BlockConverter, CalloutRestorer, CalloutTransformer, ChangeDetector, ColorAnnotator, ConfigManager, ConfigSchema, ConflictResolver, ConversionPipeline, DEFAULT_CONFIG, DatabaseSyncer, EmbedResolver, EntryEditor, FileHandler, FileWatcher, FrontmatterExtractor, FrontmatterGenerator, HtmlAnnotationStripper, ImageHandler, InlineDBParser, LocalImageRestorer, MathNormalizer, MentionToWikilink, NodeVaultFS, NotionBlockBuilder, NotionClient, PreserveMarkerCollector, PreserveMarkerInjector, PropertiesTableInjector, PropertiesTableRestorer, PropertyMapper, StateDB, SyncOrchestrator, TreeMapper, UnsupportedBlockStripper, ViewDataProvider, WatchSyncService, WikilinkResolver, computeBufferHash, computeHash, createDefaultPipeline, extractCalendarEntries, filterByMonth, filterEntries, generateColorCSS, generateId, getLogger, getNotionBgColor, getNotionColor, getVisibleProperties, groupEntries, normalizeNotionId, notionIdsEqual, sanitizeFileName, setLogger, sortEntries, threeWayMerge };
|
|
6875
7109
|
//# sourceMappingURL=index.js.map
|
|
6876
7110
|
//# sourceMappingURL=index.js.map
|