@dboio/cli 0.16.2 → 0.19.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/README.md +175 -138
- package/bin/dbo.js +2 -2
- package/package.json +1 -1
- package/plugins/claude/dbo/docs/dbo-cli-readme.md +175 -138
- package/src/commands/adopt.js +534 -0
- package/src/commands/build.js +3 -3
- package/src/commands/clone.js +209 -75
- package/src/commands/deploy.js +3 -3
- package/src/commands/init.js +11 -11
- package/src/commands/install.js +3 -3
- package/src/commands/login.js +2 -2
- package/src/commands/mv.js +15 -15
- package/src/commands/pull.js +1 -1
- package/src/commands/push.js +194 -15
- package/src/commands/rm.js +2 -2
- package/src/commands/run.js +4 -4
- package/src/commands/status.js +1 -1
- package/src/commands/sync.js +2 -2
- package/src/lib/config.js +186 -135
- package/src/lib/delta.js +119 -17
- package/src/lib/dependencies.js +51 -24
- package/src/lib/deploy-config.js +4 -4
- package/src/lib/domain-guard.js +8 -9
- package/src/lib/filenames.js +13 -2
- package/src/lib/ignore.js +2 -3
- package/src/{commands/add.js → lib/insert.js} +127 -472
- package/src/lib/metadata-schema.js +14 -20
- package/src/lib/metadata-templates.js +4 -4
- package/src/lib/migrations.js +1 -1
- package/src/lib/modify-key.js +1 -1
- package/src/lib/scaffold.js +5 -12
- package/src/lib/schema.js +67 -37
- package/src/lib/structure.js +6 -6
- package/src/lib/tagging.js +2 -2
- package/src/lib/ticketing.js +3 -7
- package/src/lib/toe-stepping.js +5 -5
- package/src/lib/transaction-key.js +1 -1
- package/src/migrations/004-rename-output-files.js +2 -2
- package/src/migrations/005-rename-output-metadata.js +2 -2
- package/src/migrations/006-remove-uid-companion-filenames.js +1 -1
- package/src/migrations/007-natural-entity-companion-filenames.js +1 -1
- package/src/migrations/008-metadata-uid-in-suffix.js +1 -1
- package/src/migrations/009-fix-media-collision-metadata-names.js +1 -1
- package/src/migrations/010-delete-paren-media-orphans.js +1 -1
- package/src/migrations/012-project-dir-restructure.js +211 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { readFile, writeFile, readdir, access } from 'fs/promises';
|
|
2
2
|
import { join, relative, basename, extname } from 'path';
|
|
3
3
|
import { EXTENSION_DESCRIPTORS_DIR, ENTITY_DIR_NAMES } from './structure.js';
|
|
4
|
+
import { metadataSchemaPath } from './config.js';
|
|
4
5
|
import inquirer from 'inquirer';
|
|
5
6
|
|
|
6
|
-
export const METADATA_SCHEMA_FILE = '.dbo/metadata_schema.json';
|
|
7
|
-
|
|
8
7
|
const STATIC_DIRECTIVE_MAP = {
|
|
9
8
|
docs: { entity: 'extension', descriptor: 'documentation' },
|
|
10
9
|
};
|
|
@@ -67,33 +66,29 @@ export function resolveDirective(filePath) {
|
|
|
67
66
|
}
|
|
68
67
|
|
|
69
68
|
/**
|
|
70
|
-
* Load metadata schema from .
|
|
69
|
+
* Load metadata schema from .app/<shortName>.metadata_schema.json.
|
|
71
70
|
*/
|
|
72
71
|
export async function loadMetadataSchema() {
|
|
73
72
|
try {
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
} catch (err) {
|
|
82
|
-
if (err.code === 'ENOENT') return {};
|
|
83
|
-
return {};
|
|
73
|
+
const path = await metadataSchemaPath();
|
|
74
|
+
const raw = await readFile(path, 'utf8');
|
|
75
|
+
return JSON.parse(raw);
|
|
76
|
+
} catch {
|
|
77
|
+
return null;
|
|
84
78
|
}
|
|
85
79
|
}
|
|
86
80
|
|
|
87
81
|
/**
|
|
88
|
-
* Save metadata schema to .
|
|
82
|
+
* Save metadata schema to .app/<shortName>.metadata_schema.json.
|
|
89
83
|
*/
|
|
90
|
-
export async function saveMetadataSchema(
|
|
91
|
-
|
|
84
|
+
export async function saveMetadataSchema(data) {
|
|
85
|
+
const path = await metadataSchemaPath();
|
|
86
|
+
await writeFile(path, JSON.stringify(data, null, 2) + '\n');
|
|
92
87
|
}
|
|
93
88
|
|
|
94
89
|
/**
|
|
95
90
|
* Merge extension descriptor definitions from dependency metadata_schema.json files.
|
|
96
|
-
* For each dependency in
|
|
91
|
+
* For each dependency in app_dependencies/<name>/, reads its .app/<name>.metadata_schema.json
|
|
97
92
|
* and copies any extension descriptor entries that don't already exist locally.
|
|
98
93
|
*
|
|
99
94
|
* @param {Object} localSchema - The current project's metadata_schema object (mutated in place)
|
|
@@ -102,7 +97,7 @@ export async function saveMetadataSchema(templates) {
|
|
|
102
97
|
export async function mergeDescriptorSchemaFromDependencies(localSchema) {
|
|
103
98
|
if (!localSchema) return false;
|
|
104
99
|
|
|
105
|
-
const depsRoot = join(
|
|
100
|
+
const depsRoot = join(process.cwd(), 'app_dependencies');
|
|
106
101
|
let depNames;
|
|
107
102
|
try {
|
|
108
103
|
depNames = await readdir(depsRoot);
|
|
@@ -113,7 +108,7 @@ export async function mergeDescriptorSchemaFromDependencies(localSchema) {
|
|
|
113
108
|
let merged = false;
|
|
114
109
|
|
|
115
110
|
for (const depName of depNames) {
|
|
116
|
-
const depSchemaPath = join(depsRoot, depName, '.
|
|
111
|
+
const depSchemaPath = join(depsRoot, depName, '.app', `${depName}.metadata_schema.json`);
|
|
117
112
|
let depSchema;
|
|
118
113
|
try {
|
|
119
114
|
depSchema = JSON.parse(await readFile(depSchemaPath, 'utf8'));
|
|
@@ -489,4 +484,3 @@ export function generateMetadataFromSchema(schema, existing = {}) {
|
|
|
489
484
|
// Backward-compat re-exports
|
|
490
485
|
export const loadMetadataTemplates = loadMetadataSchema;
|
|
491
486
|
export const saveMetadataTemplates = saveMetadataSchema;
|
|
492
|
-
export const METADATA_TEMPLATES_FILE = METADATA_SCHEMA_FILE;
|
|
@@ -3,7 +3,7 @@ import { relative, basename, extname } from 'path';
|
|
|
3
3
|
import { EXTENSION_DESCRIPTORS_DIR, ENTITY_DIR_NAMES } from './structure.js';
|
|
4
4
|
import inquirer from 'inquirer';
|
|
5
5
|
|
|
6
|
-
const METADATA_TEMPLATES_FILE = '.
|
|
6
|
+
const METADATA_TEMPLATES_FILE = '.app/metadata_templates.json';
|
|
7
7
|
|
|
8
8
|
const STATIC_DIRECTIVE_MAP = {
|
|
9
9
|
docs: { entity: 'extension', descriptor: 'documentation' },
|
|
@@ -67,7 +67,7 @@ export function resolveDirective(filePath) {
|
|
|
67
67
|
}
|
|
68
68
|
|
|
69
69
|
/**
|
|
70
|
-
* Load metadata templates from .
|
|
70
|
+
* Load metadata templates from .app/metadata_templates.json.
|
|
71
71
|
*/
|
|
72
72
|
export async function loadMetadataTemplates() {
|
|
73
73
|
try {
|
|
@@ -75,7 +75,7 @@ export async function loadMetadataTemplates() {
|
|
|
75
75
|
try {
|
|
76
76
|
return JSON.parse(raw);
|
|
77
77
|
} catch {
|
|
78
|
-
console.warn('Warning: .
|
|
78
|
+
console.warn('Warning: .app/metadata_templates.json is malformed JSON — falling back to generic wizard');
|
|
79
79
|
return null;
|
|
80
80
|
}
|
|
81
81
|
} catch (err) {
|
|
@@ -85,7 +85,7 @@ export async function loadMetadataTemplates() {
|
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
/**
|
|
88
|
-
* Save metadata templates to .
|
|
88
|
+
* Save metadata templates to .app/metadata_templates.json.
|
|
89
89
|
*/
|
|
90
90
|
export async function saveMetadataTemplates(templates) {
|
|
91
91
|
await writeFile(METADATA_TEMPLATES_FILE, JSON.stringify(templates, null, 2) + '\n');
|
package/src/lib/migrations.js
CHANGED
|
@@ -17,7 +17,7 @@ export async function runPendingMigrations(options = {}) {
|
|
|
17
17
|
// --no-migrate suppresses for this invocation
|
|
18
18
|
if (options.migrate === false) return;
|
|
19
19
|
|
|
20
|
-
// No .
|
|
20
|
+
// No .app/ project in this directory — nothing to migrate
|
|
21
21
|
if (!(await isInitialized())) return;
|
|
22
22
|
|
|
23
23
|
// Discover migration files
|
package/src/lib/modify-key.js
CHANGED
|
@@ -104,6 +104,6 @@ export async function handleModifyKeyError() {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
await saveAppModifyKey(key);
|
|
107
|
-
log.info(' ModifyKey saved to .
|
|
107
|
+
log.info(' ModifyKey saved to .app/config.json for future use.');
|
|
108
108
|
return { modifyKey: key, cancel: false };
|
|
109
109
|
}
|
package/src/lib/scaffold.js
CHANGED
|
@@ -3,6 +3,7 @@ import { join } from 'path';
|
|
|
3
3
|
import { SCAFFOLD_DIRS } from './structure.js';
|
|
4
4
|
import { log } from './logger.js';
|
|
5
5
|
import { applyTrashIcon } from './tagging.js';
|
|
6
|
+
import { appMetadataPath } from './config.js';
|
|
6
7
|
|
|
7
8
|
/**
|
|
8
9
|
* Scaffold the standard DBO project directory structure in cwd.
|
|
@@ -37,21 +38,12 @@ export async function scaffoldProjectDirs(cwd = process.cwd()) {
|
|
|
37
38
|
// Best-effort: apply trash icon to the trash directory
|
|
38
39
|
await applyTrashIcon(join(cwd, 'trash'));
|
|
39
40
|
|
|
40
|
-
// Create app.json if absent
|
|
41
|
-
const appJsonPath = join(cwd, 'app.json');
|
|
42
|
-
try {
|
|
43
|
-
await access(appJsonPath);
|
|
44
|
-
} catch {
|
|
45
|
-
await writeFile(appJsonPath, '{}\n');
|
|
46
|
-
created.push('app.json');
|
|
47
|
-
}
|
|
48
|
-
|
|
49
41
|
// Create manifest.json if absent
|
|
50
42
|
const manifestPath = join(cwd, 'manifest.json');
|
|
51
43
|
try {
|
|
52
44
|
await access(manifestPath);
|
|
53
45
|
} catch {
|
|
54
|
-
// Try to resolve values from
|
|
46
|
+
// Try to resolve values from app metadata file; fall back to empty strings
|
|
55
47
|
let appName = '';
|
|
56
48
|
let shortName = '';
|
|
57
49
|
let description = '';
|
|
@@ -59,7 +51,8 @@ export async function scaffoldProjectDirs(cwd = process.cwd()) {
|
|
|
59
51
|
let domain = '';
|
|
60
52
|
|
|
61
53
|
try {
|
|
62
|
-
const
|
|
54
|
+
const appMetaPath = await appMetadataPath();
|
|
55
|
+
const appData = JSON.parse(await readFile(appMetaPath, 'utf8'));
|
|
63
56
|
appName = appData.Name || '';
|
|
64
57
|
shortName = appData.ShortName || '';
|
|
65
58
|
description = appData.Description || '';
|
|
@@ -74,7 +67,7 @@ export async function scaffoldProjectDirs(cwd = process.cwd()) {
|
|
|
74
67
|
}
|
|
75
68
|
}
|
|
76
69
|
}
|
|
77
|
-
} catch { /*
|
|
70
|
+
} catch { /* metadata file missing or unparseable — use empty defaults */ }
|
|
78
71
|
|
|
79
72
|
const manifest = {
|
|
80
73
|
name: `${appName} | ${domain}`,
|
package/src/lib/schema.js
CHANGED
|
@@ -1,53 +1,83 @@
|
|
|
1
|
-
import { readFile
|
|
2
|
-
import {
|
|
1
|
+
import { readFile } from 'fs/promises';
|
|
2
|
+
import { join, sep } from 'path';
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
const SCHEMA_API_PATH = '/api/app/object/_system';
|
|
4
|
+
const SYSTEM_BASELINE_PATH = join('app_dependencies', '_system', '.app', '_system.json');
|
|
6
5
|
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Kept for call-site compatibility with commands that pass systemSchemaPath.
|
|
8
|
+
* Points to the _system dependency baseline location.
|
|
9
|
+
*/
|
|
10
|
+
export const SCHEMA_FILE = SYSTEM_BASELINE_PATH;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Load schema from the _system dependency baseline.
|
|
14
|
+
* When inside a dependency checkout (app_dependencies/<dep>/), traverses up
|
|
15
|
+
* to the parent project's _system baseline.
|
|
16
|
+
* Returns parsed object or null if the dependency hasn't been cloned yet.
|
|
17
|
+
*/
|
|
18
|
+
export async function loadSchema() {
|
|
19
|
+
// Try local path first (works for top-level projects)
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(await readFile(SYSTEM_BASELINE_PATH, 'utf8'));
|
|
22
|
+
} catch { /* not found locally */ }
|
|
23
|
+
|
|
24
|
+
// If inside a dependency checkout, try parent project's schema
|
|
25
|
+
const cwd = process.cwd();
|
|
26
|
+
const marker = `${sep}app_dependencies${sep}`;
|
|
27
|
+
const depIdx = cwd.indexOf(marker);
|
|
28
|
+
if (depIdx >= 0) {
|
|
29
|
+
const parentRoot = cwd.substring(0, depIdx);
|
|
30
|
+
const parentSchemaPath = join(parentRoot, SYSTEM_BASELINE_PATH);
|
|
31
|
+
try {
|
|
32
|
+
return JSON.parse(await readFile(parentSchemaPath, 'utf8'));
|
|
33
|
+
} catch { /* parent schema not available either */ }
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return null;
|
|
13
37
|
}
|
|
14
38
|
|
|
15
39
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Returns ISO date string or null on failure.
|
|
40
|
+
* saveSchema() is now a no-op — schema is managed by the _system dependency clone.
|
|
41
|
+
* Kept for call-site compatibility.
|
|
19
42
|
*/
|
|
20
|
-
export async function
|
|
21
|
-
|
|
22
|
-
const result = await client.get(`${SCHEMA_API_PATH}[_LastUpdated]`);
|
|
23
|
-
if (!result.ok || !result.data) return null;
|
|
24
|
-
return result.data._LastUpdated || null;
|
|
43
|
+
export async function saveSchema(_data) {
|
|
44
|
+
// no-op
|
|
25
45
|
}
|
|
26
46
|
|
|
27
47
|
/**
|
|
28
|
-
* Check whether the
|
|
29
|
-
*
|
|
48
|
+
* Check whether the _system dependency needs refreshing.
|
|
49
|
+
* Delegates to checkDependencyStaleness('_system').
|
|
30
50
|
*/
|
|
31
51
|
export async function isSchemaStale(options = {}) {
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const serverTs = await fetchSchemaLastUpdated(options);
|
|
36
|
-
if (!serverTs) return false; // can't determine — assume not stale
|
|
37
|
-
|
|
38
|
-
return new Date(serverTs) > new Date(local._LastUpdated);
|
|
52
|
+
const { checkDependencyStaleness } = await import('./dependencies.js');
|
|
53
|
+
return checkDependencyStaleness('_system', options);
|
|
39
54
|
}
|
|
40
55
|
|
|
41
|
-
/**
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
56
|
+
/**
|
|
57
|
+
* "Fetch" schema by forcing a re-clone of the _system dependency.
|
|
58
|
+
* When inside a dependency checkout, falls back to direct API fetch
|
|
59
|
+
* (syncDependencies would skip due to the self-detection guard).
|
|
60
|
+
* Returns the freshly loaded schema after sync completes.
|
|
61
|
+
*/
|
|
62
|
+
export async function fetchSchema(options = {}) {
|
|
63
|
+
const cwd = process.cwd();
|
|
64
|
+
if (cwd.includes(`${sep}app_dependencies${sep}`)) {
|
|
65
|
+
// Inside a dependency checkout — can't sync _system here.
|
|
66
|
+
// Try parent's schema first (already cloned by parent).
|
|
67
|
+
const existing = await loadSchema();
|
|
68
|
+
if (existing) return existing;
|
|
69
|
+
|
|
70
|
+
// Fallback: fetch directly from API (old behavior)
|
|
71
|
+
const { DboClient } = await import('./client.js');
|
|
72
|
+
const { loadConfig } = await import('./config.js');
|
|
73
|
+
const config = await loadConfig();
|
|
74
|
+
const domain = options.domain || config.domain;
|
|
75
|
+
const client = new DboClient({ domain, verbose: options.verbose });
|
|
76
|
+
const resp = await client.get('/api/app/object/_system');
|
|
77
|
+
return resp?.data || resp;
|
|
47
78
|
}
|
|
48
|
-
}
|
|
49
79
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
80
|
+
const { syncDependencies } = await import('./dependencies.js');
|
|
81
|
+
await syncDependencies({ ...options, only: ['_system'], force: true });
|
|
82
|
+
return loadSchema();
|
|
53
83
|
}
|
package/src/lib/structure.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
|
|
4
|
-
const STRUCTURE_FILE = '.
|
|
4
|
+
const STRUCTURE_FILE = '.app/directories.json';
|
|
5
5
|
|
|
6
6
|
/** All server-managed directories live under this subdirectory */
|
|
7
7
|
export const LIB_DIR = 'lib';
|
|
@@ -271,15 +271,15 @@ export async function createDirectories(structure) {
|
|
|
271
271
|
}
|
|
272
272
|
|
|
273
273
|
/**
|
|
274
|
-
* Save the bin structure to .
|
|
274
|
+
* Save the bin structure to .app/directories.json.
|
|
275
275
|
*/
|
|
276
276
|
export async function saveStructureFile(structure) {
|
|
277
|
-
await mkdir('.
|
|
277
|
+
await mkdir('.app', { recursive: true });
|
|
278
278
|
await writeFile(STRUCTURE_FILE, JSON.stringify(structure, null, 2) + '\n');
|
|
279
279
|
}
|
|
280
280
|
|
|
281
281
|
/**
|
|
282
|
-
* Load bin structure from .
|
|
282
|
+
* Load bin structure from .app/directories.json.
|
|
283
283
|
*/
|
|
284
284
|
export async function loadStructureFile() {
|
|
285
285
|
try {
|
|
@@ -389,7 +389,7 @@ export function resolveFieldValue(value) {
|
|
|
389
389
|
}
|
|
390
390
|
|
|
391
391
|
/**
|
|
392
|
-
* Persist descriptorMapping and extensionDescriptorDirs into .
|
|
392
|
+
* Persist descriptorMapping and extensionDescriptorDirs into .app/directories.json.
|
|
393
393
|
* Extends the existing structure object (already contains bin entries).
|
|
394
394
|
*
|
|
395
395
|
* @param {Object} structure - Current structure from loadStructureFile()
|
|
@@ -411,7 +411,7 @@ export async function saveDescriptorMapping(structure, mapping) {
|
|
|
411
411
|
}
|
|
412
412
|
|
|
413
413
|
/**
|
|
414
|
-
* Load descriptorMapping from .
|
|
414
|
+
* Load descriptorMapping from .app/directories.json.
|
|
415
415
|
* Returns {} if not yet persisted.
|
|
416
416
|
*/
|
|
417
417
|
export async function loadDescriptorMapping() {
|
package/src/lib/tagging.js
CHANGED
|
@@ -149,13 +149,13 @@ async function _findUntrackedFiles(dir, ig, knownMetaPaths) {
|
|
|
149
149
|
return all.filter(fp => !knownCompanions.has(fp));
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
// Recursively collect non-metadata, non-hidden, non-.
|
|
152
|
+
// Recursively collect non-metadata, non-hidden, non-.app content files
|
|
153
153
|
async function _collectContentFiles(dir, ig) {
|
|
154
154
|
const results = [];
|
|
155
155
|
let entries;
|
|
156
156
|
try { entries = await readdir(dir, { withFileTypes: true }); } catch { return []; }
|
|
157
157
|
for (const entry of entries) {
|
|
158
|
-
if (entry.name.startsWith('.')) continue; // skip hidden and .
|
|
158
|
+
if (entry.name.startsWith('.')) continue; // skip hidden and .app
|
|
159
159
|
const fullPath = join(dir, entry.name);
|
|
160
160
|
const relPath = relative(process.cwd(), fullPath).replace(/\\/g, '/');
|
|
161
161
|
if (entry.isDirectory()) {
|
package/src/lib/ticketing.js
CHANGED
|
@@ -1,16 +1,12 @@
|
|
|
1
1
|
import { readFile, writeFile, mkdir } from 'fs/promises';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { log } from './logger.js';
|
|
4
|
+
import { projectDir } from './config.js';
|
|
4
5
|
|
|
5
|
-
const DBO_DIR = '.dbo';
|
|
6
6
|
const TICKETING_FILE = 'ticketing.local.json';
|
|
7
7
|
|
|
8
|
-
function dboDir() {
|
|
9
|
-
return join(process.cwd(), DBO_DIR);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
8
|
function ticketingPath() {
|
|
13
|
-
return join(
|
|
9
|
+
return join(projectDir(), TICKETING_FILE);
|
|
14
10
|
}
|
|
15
11
|
|
|
16
12
|
const DEFAULT_TICKETING = { ticket_id: null, ticketing_required: false, ticket_confirmed: false, records: [] };
|
|
@@ -48,7 +44,7 @@ export async function loadTicketing() {
|
|
|
48
44
|
* Save ticketing.local.json.
|
|
49
45
|
*/
|
|
50
46
|
export async function saveTicketing(data) {
|
|
51
|
-
await mkdir(
|
|
47
|
+
await mkdir(projectDir(), { recursive: true });
|
|
52
48
|
await writeFile(ticketingPath(), JSON.stringify(data, null, 2) + '\n');
|
|
53
49
|
}
|
|
54
50
|
|
package/src/lib/toe-stepping.js
CHANGED
|
@@ -87,8 +87,8 @@ export async function fetchServerRecords(client, requests) {
|
|
|
87
87
|
* makes a single HTTP request and the server only returns records modified
|
|
88
88
|
* after the given date.
|
|
89
89
|
*
|
|
90
|
-
* The response is used ONLY for comparison — it must NOT replace
|
|
91
|
-
*
|
|
90
|
+
* The response is used ONLY for comparison — it must NOT replace the metadata
|
|
91
|
+
* or baseline files.
|
|
92
92
|
*
|
|
93
93
|
* @param {DboClient} client
|
|
94
94
|
* @param {string} appShortName - App short name for the /api/app/object/ endpoint
|
|
@@ -181,7 +181,7 @@ function decodeServerValue(value) {
|
|
|
181
181
|
* a newer server edit, and _LastUpdatedUserID identifies who made the change.
|
|
182
182
|
*
|
|
183
183
|
* @param {Object} serverEntry - Record from per-record server fetch
|
|
184
|
-
* @param {Object} baselineEntry - Record from
|
|
184
|
+
* @param {Object} baselineEntry - Record from the baseline file
|
|
185
185
|
* @param {Object} localMeta - Local .metadata.json object
|
|
186
186
|
* @param {string} metaDir - Absolute directory of the metadata file
|
|
187
187
|
* @returns {Promise<Array<{ col: string, serverValue: string, localValue: string, baselineValue: string }>>}
|
|
@@ -278,12 +278,12 @@ function findOldestBaselineDate(records, baseline) {
|
|
|
278
278
|
* unavailable or returns no data.
|
|
279
279
|
*
|
|
280
280
|
* The bulk response is used ONLY for comparison — it does NOT replace
|
|
281
|
-
*
|
|
281
|
+
* the metadata or baseline files.
|
|
282
282
|
*
|
|
283
283
|
* @param {Array<{ meta: Object, metaPath: string }>} records
|
|
284
284
|
* Records about to be pushed. Each must have meta.UID, meta._entity.
|
|
285
285
|
* @param {DboClient} client
|
|
286
|
-
* @param {Object} baseline - Loaded baseline from .
|
|
286
|
+
* @param {Object} baseline - Loaded baseline from .app/<shortName>.json (baseline)
|
|
287
287
|
* @param {Object} options - Commander options (options.yes used for auto-accept)
|
|
288
288
|
* @param {string} [appShortName] - App short name for bulk fetch (optional)
|
|
289
289
|
* @param {string} [serverTz] - Server timezone from config (e.g. "America/Chicago")
|
|
@@ -41,6 +41,6 @@ export async function resolveTransactionKey(options = {}) {
|
|
|
41
41
|
}]);
|
|
42
42
|
|
|
43
43
|
await saveTransactionKeyPreset(preset);
|
|
44
|
-
log.dim(` Saved TransactionKeyPreset: ${preset} to .
|
|
44
|
+
log.dim(` Saved TransactionKeyPreset: ${preset} to .app/config.json`);
|
|
45
45
|
return preset;
|
|
46
46
|
}
|
|
@@ -73,10 +73,10 @@ async function rewriteReferences(filePath) {
|
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Recursively find directories that contain _output~ files.
|
|
76
|
-
* Skips .
|
|
76
|
+
* Skips .app/, node_modules/, trash/, .git/.
|
|
77
77
|
*/
|
|
78
78
|
async function findDirsWithOutputFiles(root) {
|
|
79
|
-
const SKIP = new Set(['.
|
|
79
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
80
80
|
const results = [];
|
|
81
81
|
|
|
82
82
|
async function walk(dir) {
|
|
@@ -57,10 +57,10 @@ export default async function run(_options) {
|
|
|
57
57
|
|
|
58
58
|
/**
|
|
59
59
|
* Recursively find directories that contain output .json files (with ~ in name).
|
|
60
|
-
* Skips .
|
|
60
|
+
* Skips .app/, node_modules/, trash/, .git/.
|
|
61
61
|
*/
|
|
62
62
|
async function findDirsWithOutputJsonFiles(root) {
|
|
63
|
-
const SKIP = new Set(['.
|
|
63
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
64
64
|
const results = [];
|
|
65
65
|
|
|
66
66
|
async function walk(dir) {
|
|
@@ -161,7 +161,7 @@ export default async function run(_options) {
|
|
|
161
161
|
}
|
|
162
162
|
}
|
|
163
163
|
|
|
164
|
-
const SKIP = new Set(['.
|
|
164
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
165
165
|
|
|
166
166
|
async function findAllMetadataFiles(dir) {
|
|
167
167
|
const results = [];
|
|
@@ -127,7 +127,7 @@ const ENTITY_DIRS = new Set([
|
|
|
127
127
|
'data_source', 'group', 'site', 'redirect',
|
|
128
128
|
]);
|
|
129
129
|
|
|
130
|
-
const SKIP = new Set(['.
|
|
130
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
131
131
|
|
|
132
132
|
/**
|
|
133
133
|
* Find all .metadata.json files inside entity directories (lib/<entity>/).
|
|
@@ -50,7 +50,7 @@ export default async function run(_options) {
|
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
const SKIP = new Set(['.
|
|
53
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
54
54
|
|
|
55
55
|
async function findAllLegacyMetadataFiles(dir) {
|
|
56
56
|
const results = [];
|
|
@@ -141,7 +141,7 @@ export default async function run(_options) {
|
|
|
141
141
|
}
|
|
142
142
|
}
|
|
143
143
|
|
|
144
|
-
const SKIP = new Set(['.
|
|
144
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
145
145
|
|
|
146
146
|
async function findAllMetadataFiles(dir) {
|
|
147
147
|
const results = [];
|
|
@@ -41,7 +41,7 @@ export default async function run(_options) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const SKIP = new Set(['.
|
|
44
|
+
const SKIP = new Set(['.app', 'node_modules', 'trash', '.git', '.claude', 'app_dependencies']);
|
|
45
45
|
|
|
46
46
|
async function findParenMediaFiles(dir) {
|
|
47
47
|
const results = [];
|