@livestore/cli 0.4.0-dev.22 → 0.4.0-dev.23
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/.tsbuildinfo +1 -0
- package/dist/__tests__/fixtures/mock-config.d.ts +13 -4
- package/dist/__tests__/fixtures/mock-config.d.ts.map +1 -1
- package/dist/__tests__/fixtures/mock-config.js +8 -2
- package/dist/__tests__/fixtures/mock-config.js.map +1 -1
- package/dist/__tests__/sync-operations.test.js +2 -2
- package/dist/__tests__/sync-operations.test.js.map +1 -1
- package/dist/bin.js.map +1 -1
- package/dist/cli.d.ts +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/import-export.d.ts.map +1 -1
- package/dist/commands/import-export.js +16 -14
- package/dist/commands/import-export.js.map +1 -1
- package/dist/commands/mcp-coach.d.ts.map +1 -1
- package/dist/commands/mcp-coach.js +3 -3
- package/dist/commands/mcp-coach.js.map +1 -1
- package/dist/commands/mcp-tool-handlers.d.ts.map +1 -1
- package/dist/commands/mcp-tool-handlers.js +4 -4
- package/dist/commands/mcp-tool-handlers.js.map +1 -1
- package/dist/commands/mcp-tools-defs.d.ts.map +1 -1
- package/dist/commands/mcp-tools-defs.js.map +1 -1
- package/dist/commands/mcp.d.ts.map +1 -1
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/new-project.d.ts +8 -1
- package/dist/commands/new-project.d.ts.map +1 -1
- package/dist/commands/new-project.js +26 -17
- package/dist/commands/new-project.js.map +1 -1
- package/dist/mcp-runtime/runtime.d.ts +2 -2
- package/dist/mcp-runtime/runtime.d.ts.map +1 -1
- package/dist/mcp-runtime/runtime.js +9 -9
- package/dist/mcp-runtime/runtime.js.map +1 -1
- package/dist/module-loader.d.ts.map +1 -1
- package/dist/module-loader.js +8 -8
- package/dist/module-loader.js.map +1 -1
- package/dist/package-manager.js +4 -4
- package/dist/package-manager.js.map +1 -1
- package/dist/sync-operations.d.ts +1 -1
- package/dist/sync-operations.d.ts.map +1 -1
- package/dist/sync-operations.js +15 -15
- package/dist/sync-operations.js.map +1 -1
- package/package.json +71 -27
- package/src/__tests__/fixtures/mock-config.ts +10 -2
- package/src/__tests__/sync-operations.test.ts +4 -2
- package/src/bin.ts +1 -0
- package/src/cli.ts +1 -0
- package/src/commands/import-export.ts +19 -14
- package/src/commands/mcp-coach.ts +4 -3
- package/src/commands/mcp-tool-handlers.ts +5 -4
- package/src/commands/mcp-tools-defs.ts +1 -0
- package/src/commands/mcp.ts +1 -0
- package/src/commands/new-project.ts +28 -17
- package/src/mcp-runtime/runtime.ts +37 -29
- package/src/module-loader.ts +9 -8
- package/src/package-manager.ts +4 -4
- package/src/sync-operations.ts +19 -19
- package/dist/tsconfig.tsbuildinfo +0 -1
package/src/module-loader.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import path from 'node:path'
|
|
6
6
|
import { pathToFileURL } from 'node:url'
|
|
7
|
+
|
|
7
8
|
import type { SyncBackend } from '@livestore/common'
|
|
8
9
|
import { UnknownError } from '@livestore/common'
|
|
9
10
|
import { isLiveStoreSchema, type LiveStoreSchema } from '@livestore/common/schema'
|
|
@@ -31,11 +32,11 @@ export const loadModuleConfig = ({
|
|
|
31
32
|
configPath: string
|
|
32
33
|
}): Effect.Effect<ModuleConfig, UnknownError, FileSystem.FileSystem> =>
|
|
33
34
|
Effect.gen(function* () {
|
|
34
|
-
const abs = path.isAbsolute(configPath) ? configPath : path.resolve(process.cwd(), configPath)
|
|
35
|
+
const abs = path.isAbsolute(configPath) === true ? configPath : path.resolve(process.cwd(), configPath)
|
|
35
36
|
|
|
36
37
|
const fs = yield* FileSystem.FileSystem
|
|
37
38
|
const exists = yield* fs.exists(abs).pipe(UnknownError.mapToUnknownError)
|
|
38
|
-
if (
|
|
39
|
+
if (exists === false) {
|
|
39
40
|
return yield* UnknownError.make({
|
|
40
41
|
cause: `Store module not found at ${abs}`,
|
|
41
42
|
note: 'Make sure the path points to a valid LiveStore module',
|
|
@@ -51,15 +52,15 @@ export const loadModuleConfig = ({
|
|
|
51
52
|
}),
|
|
52
53
|
})
|
|
53
54
|
|
|
54
|
-
const schema = (mod
|
|
55
|
-
if (
|
|
55
|
+
const schema = (mod)?.schema
|
|
56
|
+
if (isLiveStoreSchema(schema) === false) {
|
|
56
57
|
return yield* UnknownError.make({
|
|
57
58
|
cause: `Module at ${abs} must export a valid LiveStore 'schema'`,
|
|
58
59
|
note: `Ex: export { schema } from './src/livestore/schema.ts'`,
|
|
59
60
|
})
|
|
60
61
|
}
|
|
61
62
|
|
|
62
|
-
const syncBackendConstructor = (mod
|
|
63
|
+
const syncBackendConstructor = (mod)?.syncBackend
|
|
63
64
|
if (typeof syncBackendConstructor !== 'function') {
|
|
64
65
|
return yield* UnknownError.make({
|
|
65
66
|
cause: `Module at ${abs} must export a 'syncBackend' constructor`,
|
|
@@ -67,17 +68,17 @@ export const loadModuleConfig = ({
|
|
|
67
68
|
})
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
const syncPayloadSchemaExport = (mod
|
|
71
|
+
const syncPayloadSchemaExport = (mod)?.syncPayloadSchema
|
|
71
72
|
const syncPayloadSchema =
|
|
72
73
|
syncPayloadSchemaExport === undefined
|
|
73
74
|
? Schema.JsonValue
|
|
74
|
-
: Schema.isSchema(syncPayloadSchemaExport)
|
|
75
|
+
: Schema.isSchema(syncPayloadSchemaExport) === true
|
|
75
76
|
? (syncPayloadSchemaExport as Schema.Schema<any>)
|
|
76
77
|
: shouldNeverHappen(
|
|
77
78
|
`Exported 'syncPayloadSchema' from ${abs} must be an Effect Schema (received ${typeof syncPayloadSchemaExport}).`,
|
|
78
79
|
)
|
|
79
80
|
|
|
80
|
-
const syncPayloadExport = (mod
|
|
81
|
+
const syncPayloadExport = (mod)?.syncPayload
|
|
81
82
|
const syncPayload = yield* (
|
|
82
83
|
syncPayloadExport === undefined
|
|
83
84
|
? Effect.succeed<unknown>(undefined)
|
package/src/package-manager.ts
CHANGED
|
@@ -20,10 +20,10 @@ export type DetectPackageManagerResult = { _tag: 'supported'; pm: PackageManager
|
|
|
20
20
|
export const detectPackageManager = (
|
|
21
21
|
userAgent = process.env.npm_config_user_agent ?? '',
|
|
22
22
|
): DetectPackageManagerResult => {
|
|
23
|
-
if (userAgent.startsWith('bun/')) return { _tag: 'supported', pm: 'bun' }
|
|
24
|
-
if (userAgent.startsWith('pnpm/')) return { _tag: 'supported', pm: 'pnpm' }
|
|
25
|
-
if (userAgent.startsWith('npm/')) return { _tag: 'supported', pm: 'npm' }
|
|
26
|
-
if (userAgent.startsWith('yarn/')) return { _tag: 'unsupported', pm: 'yarn' }
|
|
23
|
+
if (userAgent.startsWith('bun/') === true) return { _tag: 'supported', pm: 'bun' }
|
|
24
|
+
if (userAgent.startsWith('pnpm/') === true) return { _tag: 'supported', pm: 'pnpm' }
|
|
25
|
+
if (userAgent.startsWith('npm/') === true) return { _tag: 'supported', pm: 'npm' }
|
|
26
|
+
if (userAgent.startsWith('yarn/') === true) return { _tag: 'unsupported', pm: 'yarn' }
|
|
27
27
|
|
|
28
28
|
// Default to bun when the package manager can't be detected
|
|
29
29
|
return { _tag: 'supported', pm: 'bun' }
|
package/src/sync-operations.ts
CHANGED
|
@@ -43,17 +43,17 @@ export const ExportFileSchema = Schema.Struct({
|
|
|
43
43
|
|
|
44
44
|
export type ExportFile = typeof ExportFileSchema.Type
|
|
45
45
|
|
|
46
|
-
export class ConnectionError extends Schema.TaggedError<ConnectionError>()('ConnectionError', {
|
|
46
|
+
export class ConnectionError extends Schema.TaggedError<ConnectionError>('~@livestore/cli/ConnectionError')('ConnectionError', {
|
|
47
47
|
cause: Schema.Defect,
|
|
48
48
|
note: Schema.String,
|
|
49
49
|
}) {}
|
|
50
50
|
|
|
51
|
-
export class ExportError extends Schema.TaggedError<ExportError>()('ExportError', {
|
|
51
|
+
export class ExportError extends Schema.TaggedError<ExportError>('~@livestore/cli/ExportError')('ExportError', {
|
|
52
52
|
cause: Schema.Defect,
|
|
53
53
|
note: Schema.String,
|
|
54
54
|
}) {}
|
|
55
55
|
|
|
56
|
-
export class ImportError extends Schema.TaggedError<ImportError>()('ImportError', {
|
|
56
|
+
export class ImportError extends Schema.TaggedError<ImportError>('~@livestore/cli/ImportError')('ImportError', {
|
|
57
57
|
cause: Schema.Defect,
|
|
58
58
|
note: Schema.String,
|
|
59
59
|
}) {}
|
|
@@ -81,7 +81,7 @@ export const makeSyncBackend = ({
|
|
|
81
81
|
Effect.gen(function* () {
|
|
82
82
|
const { syncBackendConstructor, syncPayload } = yield* loadModuleConfig({ configPath })
|
|
83
83
|
|
|
84
|
-
const syncBackend = yield*
|
|
84
|
+
const syncBackend = yield* syncBackendConstructor({
|
|
85
85
|
storeId,
|
|
86
86
|
clientId,
|
|
87
87
|
/** syncPayload is validated against syncPayloadSchema by loadModuleConfig */
|
|
@@ -103,7 +103,7 @@ export const makeSyncBackend = ({
|
|
|
103
103
|
yield* syncBackend.ping.pipe(
|
|
104
104
|
Effect.timeout(CONNECTION_TIMEOUT_MS),
|
|
105
105
|
Effect.catchAll((cause) => {
|
|
106
|
-
if (Cause.isTimeoutException(cause)) {
|
|
106
|
+
if (Cause.isTimeoutException(cause) === true) {
|
|
107
107
|
return Effect.fail(
|
|
108
108
|
new ConnectionError({
|
|
109
109
|
cause,
|
|
@@ -123,8 +123,8 @@ export const makeSyncBackend = ({
|
|
|
123
123
|
return syncBackend
|
|
124
124
|
})
|
|
125
125
|
|
|
126
|
-
const releaseSyncBackend = (syncBackend: SyncBackend.SyncBackend): Effect.Effect<void
|
|
127
|
-
const maybeDisconnect = (syncBackend as { disconnect?: Effect.Effect<void
|
|
126
|
+
const releaseSyncBackend = (syncBackend: SyncBackend.SyncBackend): Effect.Effect<void> => {
|
|
127
|
+
const maybeDisconnect = (syncBackend as { disconnect?: Effect.Effect<void> }).disconnect
|
|
128
128
|
const releaseEffect = maybeDisconnect ?? SubscriptionRef.set(syncBackend.isConnected, false)
|
|
129
129
|
return releaseEffect.pipe(Effect.orElse(() => Effect.void))
|
|
130
130
|
}
|
|
@@ -168,7 +168,7 @@ export const pullEventsFromSyncBackend = ({
|
|
|
168
168
|
(cause) =>
|
|
169
169
|
new ExportError({
|
|
170
170
|
cause,
|
|
171
|
-
note: `Failed to pull events from sync backend: ${cause}`,
|
|
171
|
+
note: `Failed to pull events from sync backend: ${String(cause)}`,
|
|
172
172
|
}),
|
|
173
173
|
),
|
|
174
174
|
)
|
|
@@ -228,8 +228,8 @@ export const validateExportData = ({
|
|
|
228
228
|
Effect.mapError(
|
|
229
229
|
(cause) =>
|
|
230
230
|
new ImportError({
|
|
231
|
-
cause: new Error(`Invalid export file format: ${cause}`),
|
|
232
|
-
note: `Invalid export file format: ${cause}`,
|
|
231
|
+
cause: new Error(`Invalid export file format: ${String(cause)}`),
|
|
232
|
+
note: `Invalid export file format: ${String(cause)}`,
|
|
233
233
|
}),
|
|
234
234
|
),
|
|
235
235
|
)
|
|
@@ -262,7 +262,7 @@ export const pushEventsToSyncBackend = ({
|
|
|
262
262
|
data: unknown
|
|
263
263
|
force: boolean
|
|
264
264
|
dryRun: boolean
|
|
265
|
-
onProgress?: (pushed: number, total: number) => Effect.Effect<void
|
|
265
|
+
onProgress?: (pushed: number, total: number) => Effect.Effect<void>
|
|
266
266
|
}): Effect.Effect<
|
|
267
267
|
ImportResult,
|
|
268
268
|
ImportError | UnknownError | ConnectionError,
|
|
@@ -276,20 +276,20 @@ export const pushEventsToSyncBackend = ({
|
|
|
276
276
|
Effect.mapError(
|
|
277
277
|
(cause) =>
|
|
278
278
|
new ImportError({
|
|
279
|
-
cause: new Error(`Invalid export file format: ${cause}`),
|
|
280
|
-
note: `Invalid export file format: ${cause}`,
|
|
279
|
+
cause: new Error(`Invalid export file format: ${String(cause)}`),
|
|
280
|
+
note: `Invalid export file format: ${String(cause)}`,
|
|
281
281
|
}),
|
|
282
282
|
),
|
|
283
283
|
)
|
|
284
284
|
|
|
285
|
-
if (exportData.storeId !== storeId &&
|
|
285
|
+
if (exportData.storeId !== storeId && force === false) {
|
|
286
286
|
return yield* new ImportError({
|
|
287
287
|
cause: new Error(`Store ID mismatch: file has '${exportData.storeId}', expected '${storeId}'`),
|
|
288
288
|
note: `The export file was created for a different store. Use force option to import anyway.`,
|
|
289
289
|
})
|
|
290
290
|
}
|
|
291
291
|
|
|
292
|
-
if (dryRun) {
|
|
292
|
+
if (dryRun === true) {
|
|
293
293
|
return {
|
|
294
294
|
storeId,
|
|
295
295
|
eventCount: exportData.events.length,
|
|
@@ -307,12 +307,12 @@ export const pushEventsToSyncBackend = ({
|
|
|
307
307
|
(cause) =>
|
|
308
308
|
new ImportError({
|
|
309
309
|
cause,
|
|
310
|
-
note: `Failed to check existing events: ${cause}`,
|
|
310
|
+
note: `Failed to check existing events: ${String(cause)}`,
|
|
311
311
|
}),
|
|
312
312
|
),
|
|
313
313
|
)
|
|
314
314
|
|
|
315
|
-
if (Option.isSome(existingBatchOption)) {
|
|
315
|
+
if (Option.isSome(existingBatchOption) === true) {
|
|
316
316
|
const existingBatch = existingBatchOption.value
|
|
317
317
|
const estimatedCount =
|
|
318
318
|
existingBatch.pageInfo._tag === 'MoreKnown'
|
|
@@ -338,13 +338,13 @@ export const pushEventsToSyncBackend = ({
|
|
|
338
338
|
(cause) =>
|
|
339
339
|
new ImportError({
|
|
340
340
|
cause,
|
|
341
|
-
note: `Failed to push events at position ${i}: ${cause}`,
|
|
341
|
+
note: `Failed to push events at position ${i}: ${String(cause)}`,
|
|
342
342
|
}),
|
|
343
343
|
),
|
|
344
344
|
)
|
|
345
345
|
|
|
346
346
|
pushed += batch.length
|
|
347
|
-
if (onProgress) {
|
|
347
|
+
if (onProgress !== undefined) {
|
|
348
348
|
yield* onProgress(pushed, total)
|
|
349
349
|
}
|
|
350
350
|
}
|