bulkyard 1.2.0 → 1.3.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.
@@ -62,6 +62,18 @@ export default class Extract extends SfCommand {
62
62
  this.spinner.stop();
63
63
  if (result.success) {
64
64
  this.log(` ${result.object} -> ${result.table}: ${result.recordCount} records`);
65
+ // Prompt to cache schema when a live describe was used (SELECT * cache miss)
66
+ if (result.liveDescribe && result.liveDescribeFields) {
67
+ // eslint-disable-next-line no-await-in-loop
68
+ const shouldCache = await this.confirm({
69
+ message: messages.getMessage('prompt.cacheSchema', [result.object]),
70
+ defaultAnswer: false,
71
+ });
72
+ if (shouldCache) {
73
+ db.createSchemaTable();
74
+ db.writeSchema(result.object, result.liveDescribeFields.map((f) => ({ fieldName: f.name, fieldType: f.type })));
75
+ }
76
+ }
65
77
  }
66
78
  else {
67
79
  this.warn(messages.getMessage('error.objectFailed', [result.object, result.error ?? 'unknown']));
@@ -1 +1 @@
1
- {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../src/commands/bulkyard/extract.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"extract.js","sourceRoot":"","sources":["../../../src/commands/bulkyard/extract.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { SfCommand } from '@salesforce/sf-plugins-core';
2
+ /** Return type for the `bulkyard schema` command. */
3
+ export type SchemaCommandResult = {
4
+ database: string;
5
+ objects: string[];
6
+ };
7
+ export default class Schema extends SfCommand<SchemaCommandResult> {
8
+ static readonly summary: string;
9
+ static readonly description: string;
10
+ static readonly examples: string[];
11
+ static readonly flags: {
12
+ 'target-org': import("@oclif/core/interfaces").OptionFlag<import("@salesforce/core").Org, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'api-version': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
14
+ sobjects: import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
15
+ 'config-file': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
16
+ database: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<SchemaCommandResult>;
19
+ }
@@ -0,0 +1,71 @@
1
+ import { SfCommand, Flags } from '@salesforce/sf-plugins-core';
2
+ import { Messages } from '@salesforce/core';
3
+ import { loadConfig } from '../../core/config.js';
4
+ import { BulkyardDatabase } from '../../core/database.js';
5
+ import { describeToFieldInfos } from '../../core/schema.js';
6
+ Messages.importMessagesDirectoryFromMetaUrl(import.meta.url);
7
+ const messages = Messages.loadMessages('bulkyard', 'bulkyard.schema');
8
+ export default class Schema extends SfCommand {
9
+ static summary = messages.getMessage('summary');
10
+ static description = messages.getMessage('description');
11
+ static examples = messages.getMessages('examples');
12
+ static flags = {
13
+ 'target-org': Flags.requiredOrg(),
14
+ 'api-version': Flags.orgApiVersion(),
15
+ sobjects: Flags.string({
16
+ summary: messages.getMessage('flags.sobjects.summary'),
17
+ exactlyOne: ['sobjects', 'config-file'],
18
+ }),
19
+ 'config-file': Flags.file({
20
+ char: 'c',
21
+ summary: messages.getMessage('flags.config-file.summary'),
22
+ exists: true,
23
+ exactlyOne: ['sobjects', 'config-file'],
24
+ }),
25
+ database: Flags.string({
26
+ char: 'd',
27
+ summary: messages.getMessage('flags.database.summary'),
28
+ default: 'bulkyard.db',
29
+ exclusive: ['config-file'],
30
+ }),
31
+ };
32
+ async run() {
33
+ const { flags } = await this.parse(Schema);
34
+ let objectNames;
35
+ let dbPath;
36
+ if (flags['config-file']) {
37
+ const config = loadConfig(flags['config-file']);
38
+ objectNames = config.objects.map((o) => o.object);
39
+ dbPath = config.database;
40
+ }
41
+ else {
42
+ objectNames = flags.sobjects.split(',').map((s) => s.trim());
43
+ dbPath = flags.database;
44
+ }
45
+ const conn = flags['target-org'].getConnection(flags['api-version']);
46
+ const db = new BulkyardDatabase(dbPath);
47
+ try {
48
+ db.createSchemaTable();
49
+ for (const objectName of objectNames) {
50
+ this.spinner.start(messages.getMessage('info.describing', [objectName]));
51
+ // eslint-disable-next-line no-await-in-loop
52
+ const describeResult = await conn.describe(objectName);
53
+ const fieldInfos = describeToFieldInfos(describeResult);
54
+ db.writeSchema(objectName, fieldInfos.map((f) => ({ fieldName: f.name, fieldType: f.type })));
55
+ this.spinner.stop();
56
+ this.log(` ${objectName}: ${fieldInfos.length} fields cached`);
57
+ }
58
+ this.log(messages.getMessage('info.complete'));
59
+ this.styledHeader('Schema Cache Results');
60
+ this.table({
61
+ data: objectNames.map((name) => ({ object: name })),
62
+ columns: ['object'],
63
+ });
64
+ }
65
+ finally {
66
+ db.close();
67
+ }
68
+ return { database: dbPath, objects: objectNames };
69
+ }
70
+ }
71
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/commands/bulkyard/schema.ts"],"names":[],"mappings":"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"}
@@ -14,5 +14,14 @@ export declare class BulkyardDatabase {
14
14
  tableExists(tableName: string): boolean;
15
15
  getTableColumns(tableName: string): string[];
16
16
  getRowCount(tableName: string): number;
17
+ createSchemaTable(): void;
18
+ readSchema(objectName: string): Array<{
19
+ fieldName: string;
20
+ fieldType: string;
21
+ }> | null;
22
+ writeSchema(objectName: string, fields: Array<{
23
+ fieldName: string;
24
+ fieldType: string;
25
+ }>): void;
17
26
  close(): void;
18
27
  }
@@ -60,6 +60,32 @@ export class BulkyardDatabase {
60
60
  const row = this.db.prepare(`SELECT count(*) as cnt FROM ${quoteId(tableName)}`).get();
61
61
  return row.cnt;
62
62
  }
63
+ createSchemaTable() {
64
+ this.db.exec(`CREATE TABLE IF NOT EXISTS "_bulkyard_schema" (
65
+ object_name TEXT NOT NULL,
66
+ field_name TEXT NOT NULL,
67
+ field_type TEXT NOT NULL
68
+ )`);
69
+ }
70
+ readSchema(objectName) {
71
+ const rows = this.db
72
+ .prepare('SELECT field_name, field_type FROM "_bulkyard_schema" WHERE object_name = ?')
73
+ .all(objectName);
74
+ if (rows.length === 0)
75
+ return null;
76
+ return rows.map((r) => ({ fieldName: r.field_name, fieldType: r.field_type }));
77
+ }
78
+ writeSchema(objectName, fields) {
79
+ this.createSchemaTable();
80
+ const deleteStmt = this.db.prepare('DELETE FROM "_bulkyard_schema" WHERE object_name = ?');
81
+ const insertStmt = this.db.prepare('INSERT INTO "_bulkyard_schema" (object_name, field_name, field_type) VALUES (?, ?, ?)');
82
+ this.db.transaction(() => {
83
+ deleteStmt.run(objectName);
84
+ for (const f of fields) {
85
+ insertStmt.run(objectName, f.fieldName, f.fieldType);
86
+ }
87
+ })();
88
+ }
63
89
  close() {
64
90
  this.db.close();
65
91
  }
@@ -1 +1 @@
1
- {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAU/C,SAAS,OAAO,CAAC,UAAkB;IACjC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,gBAAgB;IACnB,EAAE,CAAoB;IAE9B,YAAmB,MAAc;QAC/B,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAEM,WAAW,CAAC,SAAiB,EAAE,OAAoB;QACxD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,MAAM,KAAK,OAAO,GAAG,CAAC,CAAC;IACtD,CAAC;IAEM,aAAa,CAAC,SAAiB,EAAE,OAAiB,EAAE,OAAuC;QAChG,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,MAAM,KAAK,OAAO,aAAa,YAAY,GAAG,CAAC,CAAC;QAE5F,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAoC,EAAE,EAAE;gBAC/E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAC5D,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC,CAAC,CAAC;YACH,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC,GAAG,EAAoC,CAAC;IAC5F,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,2EAA2E,CAAC;aACpF,GAAG,CAAC,SAAS,CAAoB,CAAC;QACrC,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IACrB,CAAC;IAEM,eAAe,CAAC,SAAiB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,qBAAqB,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAA6B,CAAC;QAC1G,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+BAA+B,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAqB,CAAC;QAC1G,OAAO,GAAG,CAAC,GAAG,CAAC;IACjB,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF"}
1
+ {"version":3,"file":"database.js","sourceRoot":"","sources":["../../src/core/database.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAU/C,SAAS,OAAO,CAAC,UAAkB;IACjC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;AAC/C,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnD,IAAI,OAAO,GAAG,KAAK,SAAS;QAAE,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,IAAI,OAAO,GAAG,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,OAAO,gBAAgB;IACnB,EAAE,CAAoB;IAE9B,YAAmB,MAAc;QAC/B,IAAI,CAAC,EAAE,GAAG,IAAI,QAAQ,CAAC,MAAM,CAAC,CAAC;QAC/B,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;QACrC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;IACvC,CAAC;IAEM,WAAW,CAAC,SAAiB,EAAE,OAAoB;QACxD,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,wBAAwB,MAAM,EAAE,CAAC,CAAC;QAE/C,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChG,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,gBAAgB,MAAM,KAAK,OAAO,GAAG,CAAC,CAAC;IACtD,CAAC;IAEM,aAAa,CAAC,SAAiB,EAAE,OAAiB,EAAE,OAAuC;QAChG,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1D,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,eAAe,MAAM,KAAK,OAAO,aAAa,YAAY,GAAG,CAAC,CAAC;QAE5F,MAAM,SAAS,GAAG,IAAI,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC;YAC9C,MAAM,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,IAAoC,EAAE,EAAE;gBAC/E,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;oBAC5D,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC;gBACtB,CAAC;YACH,CAAC,CAAC,CAAC;YACH,WAAW,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;IACH,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC;QAClC,OAAO,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,iBAAiB,MAAM,EAAE,CAAC,CAAC,GAAG,EAAoC,CAAC;IAC5F,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE;aAChB,OAAO,CAAC,2EAA2E,CAAC;aACpF,GAAG,CAAC,SAAS,CAAoB,CAAC;QACrC,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IACrB,CAAC;IAEM,eAAe,CAAC,SAAiB;QACtC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,qBAAqB,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,EAA6B,CAAC;QAC1G,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IACjC,CAAC;IAEM,WAAW,CAAC,SAAiB;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,+BAA+B,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,GAAG,EAAqB,CAAC;QAC1G,OAAO,GAAG,CAAC,GAAG,CAAC;IACjB,CAAC;IAEM,iBAAiB;QACtB,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC;;;;MAIX,CAAC,CAAC;IACN,CAAC;IAEM,UAAU,CAAC,UAAkB;QAClC,MAAM,IAAI,GAAG,IAAI,CAAC,EAAE;aACjB,OAAO,CAAC,6EAA6E,CAAC;aACtF,GAAG,CAAC,UAAU,CAAsD,CAAC;QACxE,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QACnC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACjF,CAAC;IAEM,WAAW,CAAC,UAAkB,EAAE,MAAuD;QAC5F,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAAC,sDAAsD,CAAC,CAAC;QAC3F,MAAM,UAAU,GAAG,IAAI,CAAC,EAAE,CAAC,OAAO,CAChC,uFAAuF,CACxF,CAAC;QAEF,IAAI,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,EAAE;YACvB,UAAU,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAC3B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC;YACvD,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC;IAEM,KAAK;QACV,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;IAClB,CAAC;CACF"}
@@ -1,6 +1,7 @@
1
1
  import { Connection } from '@salesforce/core';
2
2
  import { BulkyardDatabase } from './database.js';
3
3
  import { BulkyardObjectConfig } from './config.js';
4
+ import { CachedFieldInfo } from './schema.js';
4
5
  /** Result of extracting a single Salesforce object into SQLite. */
5
6
  export type ExtractResult = {
6
7
  /** The Salesforce object API name that was extracted. */
@@ -13,5 +14,9 @@ export type ExtractResult = {
13
14
  success: boolean;
14
15
  /** Error message if the extraction failed. */
15
16
  error?: string;
17
+ /** Whether a live describe call was made (cache miss) for SELECT * expansion. */
18
+ liveDescribe?: boolean;
19
+ /** Field infos fetched via live describe, available for caching. */
20
+ liveDescribeFields?: CachedFieldInfo[];
16
21
  };
17
22
  export declare function extractObject(conn: Connection, db: BulkyardDatabase, objConfig: BulkyardObjectConfig): Promise<ExtractResult>;
@@ -1,29 +1,124 @@
1
+ import { parse } from 'csv-parse/sync';
2
+ import { containsSelectStar, expandSelectStar, getQueryableFields, describeToFieldInfos, } from './schema.js';
3
+ const BATCH_SIZE = 1000;
4
+ const POLL_INTERVAL_MS = 2000;
5
+ const POLL_TIMEOUT_MS = 600_000;
6
+ // Recursive rather than looping to satisfy no-constant-condition and no-await-in-loop.
7
+ async function waitForJobCompletion(conn, jobId, deadline) {
8
+ if (Date.now() > deadline) {
9
+ throw new Error(`Bulk query job timed out after ${POLL_TIMEOUT_MS / 1000}s`);
10
+ }
11
+ const jobUrl = `${conn.instanceUrl}/services/data/v${conn.getApiVersion()}/jobs/query/${jobId}`;
12
+ const info = await conn.requestGet(jobUrl);
13
+ if (info.state === 'JobComplete')
14
+ return;
15
+ if (info.state === 'Failed' || info.state === 'Aborted') {
16
+ const detail = info.errorMessage ? `: ${info.errorMessage}` : '';
17
+ throw new Error(`Bulk query job ${info.state}${detail}`);
18
+ }
19
+ await new Promise((r) => setTimeout(r, POLL_INTERVAL_MS));
20
+ return waitForJobCompletion(conn, jobId, deadline);
21
+ }
22
+ function parseCsvPage(csvText) {
23
+ // csv-parse uses snake_case option names
24
+ // eslint-disable-next-line camelcase
25
+ return parse(csvText, { columns: true, skip_empty_lines: true, cast: (v) => (v === '' ? null : v) });
26
+ }
1
27
  export async function extractObject(conn, db, objConfig) {
2
28
  const tableName = objConfig.table ?? objConfig.object;
3
29
  try {
4
- const queryResult = await conn.bulk2.query(objConfig.query);
5
- const records = await queryResult.toArray();
6
- if (records.length === 0) {
7
- return { object: objConfig.object, table: tableName, recordCount: 0, success: true };
8
- }
9
- const firstRecord = records[0];
10
- const recordKeys = Object.keys(firstRecord).filter((k) => k !== 'attributes');
11
- const describeResult = await conn.describe(objConfig.object);
12
- const fieldMap = new Map(describeResult.fields.map((f) => [f.name, f.type]));
13
- const columns = recordKeys.map((key) => ({
14
- name: key,
15
- sfType: fieldMap.get(key) ?? 'string',
16
- }));
17
- db.createTable(tableName, columns);
18
- const cleanRecords = records.map((rec) => {
19
- const cleaned = {};
20
- for (const key of recordKeys) {
21
- cleaned[key] = rec[key];
30
+ const apiVersion = conn.getApiVersion();
31
+ const jobsUrl = `${conn.instanceUrl}/services/data/v${apiVersion}/jobs/query`;
32
+ let resolvedQuery = objConfig.query;
33
+ let fieldMap;
34
+ let liveDescribe = false;
35
+ let liveDescribeFields;
36
+ if (containsSelectStar(resolvedQuery)) {
37
+ // Try schema cache first
38
+ db.createSchemaTable();
39
+ const cached = db.readSchema(objConfig.object);
40
+ let allFields;
41
+ if (cached) {
42
+ allFields = cached.map((r) => ({ name: r.fieldName, type: r.fieldType }));
43
+ }
44
+ else {
45
+ // Cache miss — fall back to live describe
46
+ const describeResult = await conn.describe(objConfig.object);
47
+ allFields = describeToFieldInfos(describeResult);
48
+ liveDescribe = true;
49
+ liveDescribeFields = allFields;
22
50
  }
23
- return cleaned;
51
+ const queryableFields = getQueryableFields(allFields);
52
+ resolvedQuery = expandSelectStar(resolvedQuery, queryableFields);
53
+ fieldMap = new Map(allFields.map((f) => [f.name, f.type]));
54
+ }
55
+ else {
56
+ const describeResult = await conn.describe(objConfig.object);
57
+ fieldMap = new Map(describeResult.fields.map((f) => [f.name, f.type]));
58
+ }
59
+ // Create the bulk query job
60
+ const jobInfo = await conn.requestPost(jobsUrl, {
61
+ operation: 'query',
62
+ query: resolvedQuery,
24
63
  });
25
- db.insertRecords(tableName, recordKeys, cleanRecords);
26
- return { object: objConfig.object, table: tableName, recordCount: records.length, success: true };
64
+ // Poll until the job is complete
65
+ await waitForJobCompletion(conn, jobInfo.id, Date.now() + POLL_TIMEOUT_MS);
66
+ // Fetch result pages one at a time using the Sforce-Locator header.
67
+ // Using fetch directly (rather than conn.bulk2.query's streaming abstraction) because
68
+ // jsforce's QueryJobV2.result() pipes multiple locator pages to the same stream with
69
+ // {end: true}, closing it after the first page and silently dropping subsequent pages.
70
+ const resultsBaseUrl = `${jobsUrl}/${jobInfo.id}/results`;
71
+ const authHeaders = {
72
+ Authorization: `Bearer ${conn.accessToken}`,
73
+ Accept: 'text/csv',
74
+ };
75
+ let locator = null;
76
+ let recordKeys = null;
77
+ let buffer = [];
78
+ let totalCount = 0;
79
+ do {
80
+ const url = locator ? `${resultsBaseUrl}?locator=${encodeURIComponent(locator)}` : resultsBaseUrl;
81
+ // eslint-disable-next-line no-await-in-loop
82
+ const response = await fetch(url, { headers: authHeaders });
83
+ if (!response.ok) {
84
+ // eslint-disable-next-line no-await-in-loop
85
+ const body = await response.text();
86
+ throw new Error(`Failed to fetch results page (${response.status}): ${body}`);
87
+ }
88
+ locator = response.headers.get('sforce-locator');
89
+ // eslint-disable-next-line no-await-in-loop
90
+ const csvText = await response.text();
91
+ if (!csvText.trim())
92
+ continue;
93
+ const rows = parseCsvPage(csvText);
94
+ for (const row of rows) {
95
+ if (recordKeys === null) {
96
+ recordKeys = Object.keys(row);
97
+ const columns = recordKeys.map((key) => ({
98
+ name: key,
99
+ sfType: fieldMap.get(key) ?? 'string',
100
+ }));
101
+ db.createTable(tableName, columns);
102
+ }
103
+ buffer.push(row);
104
+ totalCount++;
105
+ if (buffer.length >= BATCH_SIZE) {
106
+ db.insertRecords(tableName, recordKeys, buffer);
107
+ buffer = [];
108
+ }
109
+ }
110
+ } while (locator && locator !== 'null');
111
+ if (buffer.length > 0 && recordKeys !== null) {
112
+ db.insertRecords(tableName, recordKeys, buffer);
113
+ }
114
+ return {
115
+ object: objConfig.object,
116
+ table: tableName,
117
+ recordCount: totalCount,
118
+ success: true,
119
+ liveDescribe,
120
+ liveDescribeFields,
121
+ };
27
122
  }
28
123
  catch (err) {
29
124
  const message = err instanceof Error ? err.message : String(err);
@@ -1 +1 @@
1
- {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/core/extractor.ts"],"names":[],"mappings":"AAkBA,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,IAAgB,EAChB,EAAoB,EACpB,SAA+B;IAE/B,MAAM,SAAS,GAAG,SAAS,CAAC,KAAK,IAAI,SAAS,CAAC,MAAM,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,KAAM,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,OAAO,EAAE,CAAC;QAE5C,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;QACvF,CAAC;QAED,MAAM,WAAW,GAAG,OAAO,CAAC,CAAC,CAA4B,CAAC;QAC1D,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC;QAE9E,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAE7E,MAAM,OAAO,GAAgB,UAAU,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACpD,IAAI,EAAE,GAAG;YACT,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,QAAQ;SACtC,CAAC,CAAC,CAAC;QAEJ,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;QAEnC,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YACvC,MAAM,OAAO,GAA4B,EAAE,CAAC;YAC5C,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,GAAI,GAA+B,CAAC,GAAG,CAAC,CAAC;YACvD,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,UAAU,EAAE,YAAY,CAAC,CAAC;QAEtD,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IACpG,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IACxG,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/core/extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ /** Minimal per-field metadata stored in the schema cache. */
2
+ export type CachedFieldInfo = {
3
+ /** The field API name. */
4
+ name: string;
5
+ /** The Salesforce field type (e.g. "string", "id", "boolean"). */
6
+ type: string;
7
+ };
8
+ /** Returns true if the query contains `SELECT * FROM`. */
9
+ export declare function containsSelectStar(query: string): boolean;
10
+ /** Extracts the object name from the `FROM <object>` clause of a SOQL query. */
11
+ export declare function extractObjectName(query: string): string;
12
+ /** Filters out compound field types that cannot be queried directly. */
13
+ export declare function getQueryableFields(fields: CachedFieldInfo[]): CachedFieldInfo[];
14
+ /** Replaces `SELECT * FROM` with an explicit field list, preserving the rest of the query. */
15
+ export declare function expandSelectStar(query: string, fields: CachedFieldInfo[]): string;
16
+ /** Maps a Salesforce describe result's fields array to CachedFieldInfo[]. */
17
+ export declare function describeToFieldInfos(describeResult: {
18
+ fields: Array<{
19
+ name: string;
20
+ type: string;
21
+ }>;
22
+ }): CachedFieldInfo[];
@@ -0,0 +1,30 @@
1
+ const SELECT_STAR_RE = /\bSELECT\s+\*\s+FROM\b/i;
2
+ const FROM_OBJECT_RE = /\bFROM\s+(\w+)/i;
3
+ /** Compound field types that cannot be queried directly in SOQL. */
4
+ const COMPOUND_TYPES = new Set(['address', 'location']);
5
+ /** Returns true if the query contains `SELECT * FROM`. */
6
+ export function containsSelectStar(query) {
7
+ return SELECT_STAR_RE.test(query);
8
+ }
9
+ /** Extracts the object name from the `FROM <object>` clause of a SOQL query. */
10
+ export function extractObjectName(query) {
11
+ const match = FROM_OBJECT_RE.exec(query);
12
+ if (!match) {
13
+ throw new Error(`Unable to extract object name from query: ${query}`);
14
+ }
15
+ return match[1];
16
+ }
17
+ /** Filters out compound field types that cannot be queried directly. */
18
+ export function getQueryableFields(fields) {
19
+ return fields.filter((f) => !COMPOUND_TYPES.has(f.type));
20
+ }
21
+ /** Replaces `SELECT * FROM` with an explicit field list, preserving the rest of the query. */
22
+ export function expandSelectStar(query, fields) {
23
+ const fieldList = fields.map((f) => f.name).join(', ');
24
+ return query.replace(SELECT_STAR_RE, `SELECT ${fieldList} FROM`);
25
+ }
26
+ /** Maps a Salesforce describe result's fields array to CachedFieldInfo[]. */
27
+ export function describeToFieldInfos(describeResult) {
28
+ return describeResult.fields.map((f) => ({ name: f.name, type: f.type }));
29
+ }
30
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/core/schema.ts"],"names":[],"mappings":"AAQA,MAAM,cAAc,GAAG,yBAAyB,CAAC;AACjD,MAAM,cAAc,GAAG,iBAAiB,CAAC;AAEzC,oEAAoE;AACpE,MAAM,cAAc,GAAG,IAAI,GAAG,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;AAExD,0DAA0D;AAC1D,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AACpC,CAAC;AAED,gFAAgF;AAChF,MAAM,UAAU,iBAAiB,CAAC,KAAa;IAC7C,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,6CAA6C,KAAK,EAAE,CAAC,CAAC;IACxE,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,kBAAkB,CAAC,MAAyB;IAC1D,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,8FAA8F;AAC9F,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,MAAyB;IACvE,MAAM,SAAS,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,UAAU,SAAS,OAAO,CAAC,CAAC;AACnE,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,oBAAoB,CAAC,cAEpC;IACC,OAAO,cAAc,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC"}
@@ -18,6 +18,10 @@ Alternatively, use --sobject and --query to extract a single object without a co
18
18
 
19
19
  <%= config.bin %> <%= command.id %> --target-org myOrg --sobject Account --query "SELECT Id, Name FROM Account"
20
20
 
21
+ - Extract all fields from an object using SELECT \*:
22
+
23
+ <%= config.bin %> <%= command.id %> --target-org myOrg -s Account -q "SELECT \* FROM Account"
24
+
21
25
  - Extract inline with a custom database and table name:
22
26
 
23
27
  <%= config.bin %> <%= command.id %> --target-org myOrg -s Account -q "SELECT Id, Name FROM Account" -d my.db -t Account_Backup
@@ -50,6 +54,10 @@ Extracting %s...
50
54
 
51
55
  Extraction complete.
52
56
 
57
+ # prompt.cacheSchema
58
+
59
+ Schema for "%s" was fetched from the org. Save it locally for future extractions? (y/N)
60
+
53
61
  # error.objectFailed
54
62
 
55
63
  Failed to extract %s: %s
@@ -0,0 +1,39 @@
1
+ # summary
2
+
3
+ Cache Salesforce object schemas into a local SQLite database.
4
+
5
+ # description
6
+
7
+ Describes one or more Salesforce objects and caches their field metadata into a local SQLite database. Cached schemas allow `bulkyard extract` to expand `SELECT *` queries without making a live describe call.
8
+
9
+ Provide object names via `--sobjects` (comma-separated) or read them from a `--config-file`.
10
+
11
+ # examples
12
+
13
+ - Cache schemas for specific objects:
14
+
15
+ <%= config.bin %> <%= command.id %> --target-org myOrg --sobjects Account,Contact
16
+
17
+ - Cache schemas for all objects in a config file:
18
+
19
+ <%= config.bin %> <%= command.id %> --target-org myOrg --config-file bulkyard.config.yml
20
+
21
+ # flags.sobjects.summary
22
+
23
+ Comma-separated list of Salesforce object API names to describe.
24
+
25
+ # flags.config-file.summary
26
+
27
+ Path to the YAML config file (reads object names from it).
28
+
29
+ # flags.database.summary
30
+
31
+ Path to the SQLite database file.
32
+
33
+ # info.describing
34
+
35
+ Describing %s...
36
+
37
+ # info.complete
38
+
39
+ Schema caching complete.