@heliosgraphics/epoque 0.0.1-alpha.3 → 0.0.1-alpha.4

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.
Files changed (3) hide show
  1. package/package.json +1 -1
  2. package/src/cli.ts +49 -4
  3. package/src/sync.ts +11 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@heliosgraphics/epoque",
3
- "version": "0.0.1-alpha.3",
3
+ "version": "0.0.1-alpha.4",
4
4
  "author": "Chris Puska <chris@puska.org>",
5
5
  "description": "sync a local folder",
6
6
  "type": "module",
package/src/cli.ts CHANGED
@@ -2,15 +2,22 @@
2
2
 
3
3
  import { createInterface } from "node:readline/promises"
4
4
  import { stdin as input, stdout as output } from "node:process"
5
+ import { resolve } from "node:path"
5
6
  import { EpoqueApi } from "./api"
6
7
  import { getApiKey, normalizeOrigin, readGlobalConfig, writeGlobalConfig } from "./config"
7
8
  import { syncFolder } from "./sync"
8
9
 
9
10
  const HELP = `Usage:
10
11
  epoque login
11
- epoque sync [--dry-run]
12
+ epoque sync [folder] [--dry-run] [--collection id]
12
13
  `
13
14
 
15
+ interface SyncArgs {
16
+ cwd: string
17
+ dryRun: boolean
18
+ collectionId?: string
19
+ }
20
+
14
21
  const promptLine = async (question: string): Promise<string> => {
15
22
  const readline = createInterface({ input, output })
16
23
 
@@ -68,7 +75,44 @@ const promptSecret = async (question: string): Promise<string> => {
68
75
  })
69
76
  }
70
77
 
71
- const hasFlag = (args: Array<string>, name: string): boolean => args.includes(name)
78
+ const parseSyncArgs = (args: Array<string>): SyncArgs => {
79
+ let target: string | undefined
80
+ let collectionId: string | undefined
81
+ let dryRun: boolean = false
82
+
83
+ for (let index = 0; index < args.length; index++) {
84
+ const arg = args[index]
85
+
86
+ if (arg === "--dry-run") {
87
+ dryRun = true
88
+ continue
89
+ }
90
+
91
+ if (arg === "--collection") {
92
+ collectionId = args[index + 1]?.trim()
93
+ if (!collectionId) throw new Error("--collection requires a collection id")
94
+ index += 1
95
+ continue
96
+ }
97
+
98
+ if (arg.startsWith("--collection=")) {
99
+ collectionId = arg.slice("--collection=".length).trim()
100
+ if (!collectionId) throw new Error("--collection requires a collection id")
101
+ continue
102
+ }
103
+
104
+ if (arg.startsWith("--")) throw new Error(`unknown option: ${arg}`)
105
+
106
+ if (target) throw new Error(`unexpected argument: ${arg}`)
107
+ target = arg
108
+ }
109
+
110
+ return {
111
+ collectionId,
112
+ cwd: target ? resolve(process.cwd(), target) : process.cwd(),
113
+ dryRun,
114
+ }
115
+ }
72
116
 
73
117
  const login = async (): Promise<void> => {
74
118
  const origin = normalizeOrigin(undefined)
@@ -85,7 +129,7 @@ const login = async (): Promise<void> => {
85
129
  }
86
130
 
87
131
  const sync = async (args: Array<string>): Promise<void> => {
88
- const cwd = process.cwd()
132
+ const { collectionId, cwd, dryRun } = parseSyncArgs(args)
89
133
  const origin = normalizeOrigin(undefined)
90
134
  const apiKey = await getApiKey()
91
135
 
@@ -93,8 +137,9 @@ const sync = async (args: Array<string>): Promise<void> => {
93
137
 
94
138
  const summary = await syncFolder({
95
139
  api: new EpoqueApi({ apiKey, origin }),
140
+ collectionId,
96
141
  cwd,
97
- dryRun: hasFlag(args, "--dry-run"),
142
+ dryRun,
98
143
  origin,
99
144
  prompt: promptLine,
100
145
  })
package/src/sync.ts CHANGED
@@ -10,6 +10,7 @@ export interface SyncOptions {
10
10
  cwd: string
11
11
  origin: string
12
12
  api: EpoqueApi
13
+ collectionId?: string
13
14
  dryRun: boolean
14
15
  prompt: Prompt
15
16
  }
@@ -97,12 +98,12 @@ const resolveCollectionId = async ({ api, prompt }: { api: EpoqueApi; prompt: Pr
97
98
  return collection.id
98
99
  }
99
100
 
100
- const ensureProjectConfig = async ({ api, cwd, dryRun, origin, prompt }: SyncOptions): Promise<ProjectConfig> => {
101
+ const ensureProjectConfig = async ({ api, collectionId, cwd, dryRun, origin, prompt }: SyncOptions): Promise<ProjectConfig> => {
101
102
  const existing = await readProjectConfig(cwd)
102
- if (existing) return { ...existing, origin }
103
+ if (existing && (!collectionId || collectionId === existing.collectionId)) return { ...existing, origin }
103
104
 
104
- const collectionId = await resolveCollectionId({ api, prompt })
105
- const config = createProjectConfig({ collectionId, origin })
105
+ const resolvedCollectionId = collectionId ?? (await resolveCollectionId({ api, prompt }))
106
+ const config = createProjectConfig({ collectionId: resolvedCollectionId, origin })
106
107
 
107
108
  if (!dryRun) await writeProjectConfig(cwd, config)
108
109
 
@@ -301,6 +302,12 @@ export const syncFolder = async (options: SyncOptions): Promise<SyncSummary> =>
301
302
  let articleId = localArticle.id
302
303
  let remoteArticle = articleId ? remoteById.get(articleId) : undefined
303
304
 
305
+ if (articleId && !remoteArticle) {
306
+ delete config.articles[articleId]
307
+ articleId = null
308
+ if (!options.dryRun) localArticle.id = null
309
+ }
310
+
304
311
  if (!articleId) {
305
312
  summary.createdArticles += 1
306
313