@leverstack/arcq 1.0.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/LICENSE +21 -0
- package/README.md +361 -0
- package/dist/bin/arcq.d.ts +2 -0
- package/dist/bin/arcq.js +11 -0
- package/dist/bin/arcq.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +85 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/active-cmd.d.ts +1 -0
- package/dist/lib/active-cmd.js +16 -0
- package/dist/lib/active-cmd.js.map +1 -0
- package/dist/lib/arcgis-core.d.ts +5 -0
- package/dist/lib/arcgis-core.js +89 -0
- package/dist/lib/arcgis-core.js.map +1 -0
- package/dist/lib/cache-core.d.ts +4 -0
- package/dist/lib/cache-core.js +13 -0
- package/dist/lib/cache-core.js.map +1 -0
- package/dist/lib/config-core.d.ts +4 -0
- package/dist/lib/config-core.js +21 -0
- package/dist/lib/config-core.js.map +1 -0
- package/dist/lib/context-core.d.ts +3 -0
- package/dist/lib/context-core.js +13 -0
- package/dist/lib/context-core.js.map +1 -0
- package/dist/lib/errors.d.ts +5 -0
- package/dist/lib/errors.js +13 -0
- package/dist/lib/errors.js.map +1 -0
- package/dist/lib/fields-cmd.d.ts +1 -0
- package/dist/lib/fields-cmd.js +22 -0
- package/dist/lib/fields-cmd.js.map +1 -0
- package/dist/lib/help-cmd.d.ts +1 -0
- package/dist/lib/help-cmd.js +71 -0
- package/dist/lib/help-cmd.js.map +1 -0
- package/dist/lib/interactive-cmd.d.ts +1 -0
- package/dist/lib/interactive-cmd.js +90 -0
- package/dist/lib/interactive-cmd.js.map +1 -0
- package/dist/lib/layer-resolve.d.ts +6 -0
- package/dist/lib/layer-resolve.js +34 -0
- package/dist/lib/layer-resolve.js.map +1 -0
- package/dist/lib/layers-cmd.d.ts +1 -0
- package/dist/lib/layers-cmd.js +15 -0
- package/dist/lib/layers-cmd.js.map +1 -0
- package/dist/lib/list-cmd.d.ts +1 -0
- package/dist/lib/list-cmd.js +19 -0
- package/dist/lib/list-cmd.js.map +1 -0
- package/dist/lib/query-cmd.d.ts +1 -0
- package/dist/lib/query-cmd.js +130 -0
- package/dist/lib/query-cmd.js.map +1 -0
- package/dist/lib/refresh-cmd.d.ts +1 -0
- package/dist/lib/refresh-cmd.js +16 -0
- package/dist/lib/refresh-cmd.js.map +1 -0
- package/dist/lib/services-cmd.d.ts +1 -0
- package/dist/lib/services-cmd.js +20 -0
- package/dist/lib/services-cmd.js.map +1 -0
- package/dist/lib/sync-cmd.d.ts +1 -0
- package/dist/lib/sync-cmd.js +25 -0
- package/dist/lib/sync-cmd.js.map +1 -0
- package/dist/lib/tls-core.d.ts +4 -0
- package/dist/lib/tls-core.js +47 -0
- package/dist/lib/tls-core.js.map +1 -0
- package/dist/lib/token-cmd.d.ts +1 -0
- package/dist/lib/token-cmd.js +22 -0
- package/dist/lib/token-cmd.js.map +1 -0
- package/dist/lib/token-core.d.ts +3 -0
- package/dist/lib/token-core.js +18 -0
- package/dist/lib/token-core.js.map +1 -0
- package/dist/lib/types.d.ts +65 -0
- package/dist/lib/types.js +3 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/version-cmd.d.ts +2 -0
- package/dist/lib/version-cmd.js +22 -0
- package/dist/lib/version-cmd.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
export function resolveConfigPath() {
|
|
5
|
+
return process.env.ARCQ_CONFIG || path.join(os.homedir(), '.arcq.json');
|
|
6
|
+
}
|
|
7
|
+
export function loadConfig() {
|
|
8
|
+
const configPath = resolveConfigPath();
|
|
9
|
+
if (!fs.existsSync(configPath))
|
|
10
|
+
return {};
|
|
11
|
+
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
12
|
+
// The optional top-level `insecure` key is only honored when it is exactly
|
|
13
|
+
// the boolean true; anything else (missing, string, number) is ignored.
|
|
14
|
+
if (config.insecure !== true)
|
|
15
|
+
delete config.insecure;
|
|
16
|
+
return config;
|
|
17
|
+
}
|
|
18
|
+
export function saveConfig(config) {
|
|
19
|
+
fs.writeFileSync(resolveConfigPath(), JSON.stringify(config, null, 2));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=config-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config-core.js","sourceRoot":"","sources":["../../lib/config-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,YAAY,CAAC,CAAC;AAC1E,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,UAAU,GAAG,iBAAiB,EAAE,CAAC;IACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,EAAE,CAAC;IAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAW,CAAC;IAC1E,2EAA2E;IAC3E,wEAAwE;IACxE,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC,QAAQ,CAAC;IACrD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,EAAE,CAAC,aAAa,CAAC,iBAAiB,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACzE,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
const CONTEXT_PATH = path.join(os.homedir(), '.arcq-context.json');
|
|
5
|
+
export function loadContext() {
|
|
6
|
+
if (!fs.existsSync(CONTEXT_PATH))
|
|
7
|
+
return null;
|
|
8
|
+
return JSON.parse(fs.readFileSync(CONTEXT_PATH, 'utf-8'));
|
|
9
|
+
}
|
|
10
|
+
export function saveContext(ctx) {
|
|
11
|
+
fs.writeFileSync(CONTEXT_PATH, JSON.stringify(ctx, null, 2));
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=context-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context-core.js","sourceRoot":"","sources":["../../lib/context-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,oBAAoB,CAAC,CAAC;AAEnE,MAAM,UAAU,WAAW;IACzB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,IAAI,CAAC;IAC9C,OAAO,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAY,CAAC;AACvE,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAY;IACtC,EAAE,CAAC,aAAa,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/D,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
// Errors carry the process exit code: 1 general, 2 token invalid/expired.
|
|
2
|
+
export class ArcqError extends Error {
|
|
3
|
+
exitCode;
|
|
4
|
+
constructor(message, exitCode = 1) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'ArcqError';
|
|
7
|
+
this.exitCode = exitCode;
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export function tokenError() {
|
|
11
|
+
return new ArcqError('token invalid or expired - run: arcq token set', 2);
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../lib/errors.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAE1E,MAAM,OAAO,SAAU,SAAQ,KAAK;IAClC,QAAQ,CAAS;IAEjB,YAAY,OAAe,EAAE,QAAQ,GAAG,CAAC;QACvC,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,WAAW,CAAC;QACxB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC3B,CAAC;CACF;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,IAAI,SAAS,CAAC,gDAAgD,EAAE,CAAC,CAAC,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function fieldsCmd(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { loadContext } from './context-core.js';
|
|
2
|
+
import { loadConfig } from './config-core.js';
|
|
3
|
+
import { getToken } from './token-core.js';
|
|
4
|
+
import { fetchLayerMetadata } from './arcgis-core.js';
|
|
5
|
+
import { ArcqError } from './errors.js';
|
|
6
|
+
import { resolveLayerArg } from './layer-resolve.js';
|
|
7
|
+
export default async function fieldsCmd(args) {
|
|
8
|
+
let layerUrl;
|
|
9
|
+
if (args.length === 0) {
|
|
10
|
+
const ctx = loadContext();
|
|
11
|
+
if (!ctx) {
|
|
12
|
+
throw new ArcqError('no active layer - run: arcq use <name>');
|
|
13
|
+
}
|
|
14
|
+
layerUrl = ctx.url;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
layerUrl = resolveLayerArg(args[0], loadConfig()).url;
|
|
18
|
+
}
|
|
19
|
+
const fields = await fetchLayerMetadata(layerUrl, getToken());
|
|
20
|
+
console.log(JSON.stringify(fields, null, 2));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=fields-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fields-cmd.js","sourceRoot":"","sources":["../../lib/fields-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAErD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,SAAS,CAAC,IAAc;IACpD,IAAI,QAAgB,CAAC;IAErB,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,WAAW,EAAE,CAAC;QAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,MAAM,IAAI,SAAS,CAAC,wCAAwC,CAAC,CAAC;QAChE,CAAC;QACD,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,QAAQ,GAAG,eAAe,CAAC,IAAI,CAAC,CAAC,CAAE,EAAE,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC;IACzD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;IAE9D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function helpCmd(): void;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { resolveConfigPath } from './config-core.js';
|
|
2
|
+
export default function helpCmd() {
|
|
3
|
+
console.log(`
|
|
4
|
+
arcq - ArcGIS query CLI
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
arcq refresh Fetch and cache all service catalogs
|
|
8
|
+
arcq sync Rewrite config layers from all services (servicename-layername keys)
|
|
9
|
+
arcq use Select the active layer interactively (requires fzf)
|
|
10
|
+
arcq use <name> Select the active layer by config key, service:id, or cached layer name (first match wins)
|
|
11
|
+
arcq active Print the active layer and its URL
|
|
12
|
+
arcq query <where> Query the active layer
|
|
13
|
+
arcq query <layer> <where> Query a named layer or raw URL
|
|
14
|
+
arcq <layer> <where> Shorthand for query
|
|
15
|
+
arcq fields [layer] Print layer field metadata as JSON (default: the active layer)
|
|
16
|
+
arcq list <service> List layers/tables in a service or URL
|
|
17
|
+
arcq layers List named layers in the config (--names for keys only)
|
|
18
|
+
arcq services add <name> <url> Add a named service to the config
|
|
19
|
+
arcq token set <token> Save an auth token
|
|
20
|
+
arcq token show Print the stored token
|
|
21
|
+
arcq version, --version, -V Print the arcq version
|
|
22
|
+
arcq --help, -h Show this help
|
|
23
|
+
|
|
24
|
+
Global flags:
|
|
25
|
+
--insecure Disable TLS certificate verification for arcq's own requests
|
|
26
|
+
(trusted self-signed servers only; prints a stderr warning).
|
|
27
|
+
Also settable via ARCQ_INSECURE=1 or "insecure": true in the config.
|
|
28
|
+
|
|
29
|
+
Query flags:
|
|
30
|
+
-q, --quiet Suppress the query summary (layer/where/endpoint) on stderr
|
|
31
|
+
--out-fields <a,b,c> Return only the listed fields (default: all)
|
|
32
|
+
--limit <N> Stop after N rows
|
|
33
|
+
--count Print {"count":N} only (--out-fields and --limit are ignored)
|
|
34
|
+
--order-by <expr> Sort server-side, e.g. --order-by "NAME DESC"
|
|
35
|
+
|
|
36
|
+
Where clauses:
|
|
37
|
+
ArcGIS string literals use SINGLE quotes; double-quote the shell argument:
|
|
38
|
+
arcq query parcels "STATUS = 'ACTIVE'"
|
|
39
|
+
"STATUS = \\"ACTIVE\\"" is an ArcGIS syntax error and exits 1.
|
|
40
|
+
|
|
41
|
+
Exit codes:
|
|
42
|
+
0 success - an empty [] result is a real answer, not an error
|
|
43
|
+
1 error (bad where clause, unknown layer, no active layer, server error)
|
|
44
|
+
2 token invalid or expired - run: arcq token set
|
|
45
|
+
|
|
46
|
+
Examples:
|
|
47
|
+
arcq refresh && arcq sync
|
|
48
|
+
arcq use my-service-parcels
|
|
49
|
+
arcq active
|
|
50
|
+
arcq fields
|
|
51
|
+
arcq query "AREA > 1000"
|
|
52
|
+
arcq query --count "1=1"
|
|
53
|
+
arcq query --limit 5 --out-fields OBJECTID,STATUS "STATUS = 'ACTIVE'"
|
|
54
|
+
arcq parcels "1=1"
|
|
55
|
+
|
|
56
|
+
Config:
|
|
57
|
+
${resolveConfigPath()} (override with ARCQ_CONFIG env var)
|
|
58
|
+
|
|
59
|
+
{
|
|
60
|
+
"services": { "my-service": "https://example.com/.../FeatureServer" },
|
|
61
|
+
"layers": { "parcels": "https://example.com/.../FeatureServer/0" }
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
Service and layer values accept a raw URL in place of a name.
|
|
65
|
+
|
|
66
|
+
Output:
|
|
67
|
+
query prints a JSON array of feature attributes, paginated automatically.
|
|
68
|
+
fields prints a JSON array of {name,type,alias,length}.
|
|
69
|
+
`);
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=help-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"help-cmd.js","sourceRoot":"","sources":["../../lib/help-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AAErD,MAAM,CAAC,OAAO,UAAU,OAAO;IAC7B,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAsDV,iBAAiB,EAAE;;;;;;;;;;;;CAYtB,CAAC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function interactiveCmd(args?: string[]): Promise<void>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { loadCache } from './cache-core.js';
|
|
2
|
+
import { loadConfig } from './config-core.js';
|
|
3
|
+
import { saveContext } from './context-core.js';
|
|
4
|
+
import { execSync } from 'child_process';
|
|
5
|
+
import { ArcqError } from './errors.js';
|
|
6
|
+
import { suggestNames } from './layer-resolve.js';
|
|
7
|
+
// Resolution order for `arcq use <name>`: config layer key, then cache
|
|
8
|
+
// `service:id`, then exact cache layer name (ambiguity errors, not
|
|
9
|
+
// first-match). Documented in help — agents need to know which wins.
|
|
10
|
+
function resolveNamed(name, allLayers) {
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
const configUrl = config.layers?.[name];
|
|
13
|
+
if (configUrl)
|
|
14
|
+
return { name, url: configUrl };
|
|
15
|
+
// Split on the LAST ':' so service names containing ':' don't break.
|
|
16
|
+
const sep = name.lastIndexOf(':');
|
|
17
|
+
if (sep !== -1) {
|
|
18
|
+
const service = name.slice(0, sep);
|
|
19
|
+
const idStr = name.slice(sep + 1);
|
|
20
|
+
if (/^\d+$/.test(idStr)) {
|
|
21
|
+
const id = parseInt(idStr, 10);
|
|
22
|
+
const match = allLayers.find((l) => l.service === service && l.id === id);
|
|
23
|
+
if (match) {
|
|
24
|
+
return {
|
|
25
|
+
service: match.service,
|
|
26
|
+
layerId: match.id,
|
|
27
|
+
name: match.name,
|
|
28
|
+
url: match.url,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
const byName = allLayers.filter((l) => l.name === name);
|
|
34
|
+
if (byName.length === 1) {
|
|
35
|
+
const match = byName[0];
|
|
36
|
+
return {
|
|
37
|
+
service: match.service,
|
|
38
|
+
layerId: match.id,
|
|
39
|
+
name: match.name,
|
|
40
|
+
url: match.url,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
if (byName.length > 1) {
|
|
44
|
+
const candidates = byName
|
|
45
|
+
.map((l) => `${l.service}:${l.id} → ${l.name}`)
|
|
46
|
+
.join(', ');
|
|
47
|
+
throw new ArcqError(`ambiguous layer name '${name}' - use one of: ${candidates}`);
|
|
48
|
+
}
|
|
49
|
+
const candidates = [
|
|
50
|
+
...Object.keys(config.layers ?? {}),
|
|
51
|
+
...allLayers.map((l) => l.name),
|
|
52
|
+
];
|
|
53
|
+
const suggestions = suggestNames(name, candidates);
|
|
54
|
+
const hint = suggestions.length
|
|
55
|
+
? `did you mean: ${suggestions.join(', ')}? `
|
|
56
|
+
: '';
|
|
57
|
+
throw new ArcqError(`unknown layer '${name}' - ${hint}(see: arcq layers --names)`);
|
|
58
|
+
}
|
|
59
|
+
export default async function interactiveCmd(args = []) {
|
|
60
|
+
const cache = loadCache();
|
|
61
|
+
const allLayers = Object.entries(cache).flatMap(([service, layers]) => layers.map((l) => ({ service, ...l })));
|
|
62
|
+
const name = args[0];
|
|
63
|
+
if (name) {
|
|
64
|
+
const ctx = resolveNamed(name, allLayers);
|
|
65
|
+
saveContext(ctx);
|
|
66
|
+
console.log(`[arcq] active layer set → ${ctx.name}`);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
const input = allLayers
|
|
70
|
+
.map((l) => `${l.service}:${l.id} → ${l.name}`)
|
|
71
|
+
.join('\n');
|
|
72
|
+
const selection = execSync('fzf', {
|
|
73
|
+
input,
|
|
74
|
+
encoding: 'utf-8',
|
|
75
|
+
}).trim();
|
|
76
|
+
const match = allLayers.find((l) => selection.startsWith(`${l.service}:${l.id} →`));
|
|
77
|
+
if (!match) {
|
|
78
|
+
console.log('[arcq] no matching layer selected');
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
const ctx = {
|
|
82
|
+
service: match.service,
|
|
83
|
+
layerId: match.id,
|
|
84
|
+
name: match.name,
|
|
85
|
+
url: match.url,
|
|
86
|
+
};
|
|
87
|
+
saveContext(ctx);
|
|
88
|
+
console.log(`[arcq] active layer set → ${match.name}`);
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=interactive-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interactive-cmd.js","sourceRoot":"","sources":["../../lib/interactive-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { ArcqError } from './errors.js';
|
|
2
|
+
// Cheap closest-match scoring over slug-style keys (substring first, then
|
|
3
|
+
// hyphen-token overlap) — good enough for typo suggestions without an
|
|
4
|
+
// edit-distance dependency.
|
|
5
|
+
export function suggestNames(input, candidates) {
|
|
6
|
+
const lower = input.toLowerCase();
|
|
7
|
+
const tokens = new Set(lower.split('-').filter(Boolean));
|
|
8
|
+
return candidates
|
|
9
|
+
.map((name) => {
|
|
10
|
+
const candidate = name.toLowerCase();
|
|
11
|
+
let score = 0;
|
|
12
|
+
if (candidate.includes(lower) || lower.includes(candidate))
|
|
13
|
+
score += 100;
|
|
14
|
+
score += candidate.split('-').filter((t) => tokens.has(t)).length;
|
|
15
|
+
return { name, score };
|
|
16
|
+
})
|
|
17
|
+
.filter((c) => c.score > 0)
|
|
18
|
+
.sort((a, b) => b.score - a.score)
|
|
19
|
+
.slice(0, 3)
|
|
20
|
+
.map((c) => c.name);
|
|
21
|
+
}
|
|
22
|
+
export function resolveLayerArg(name, config) {
|
|
23
|
+
const named = config.layers?.[name];
|
|
24
|
+
if (named)
|
|
25
|
+
return { url: named, source: `named layer '${name}'` };
|
|
26
|
+
if (name.includes('://'))
|
|
27
|
+
return { url: name, source: 'raw URL' };
|
|
28
|
+
const suggestions = suggestNames(name, Object.keys(config.layers ?? {}));
|
|
29
|
+
const hint = suggestions.length
|
|
30
|
+
? `did you mean: ${suggestions.join(', ')}? `
|
|
31
|
+
: '';
|
|
32
|
+
throw new ArcqError(`unknown layer '${name}' - ${hint}(see: arcq layers --names)`);
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=layer-resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer-resolve.js","sourceRoot":"","sources":["../../lib/layer-resolve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAGxC,0EAA0E;AAC1E,sEAAsE;AACtE,4BAA4B;AAC5B,MAAM,UAAU,YAAY,CAAC,KAAa,EAAE,UAAoB;IAC9D,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAClC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;IAEzD,OAAO,UAAU;SACd,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QACrC,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,QAAQ,CAAC,SAAS,CAAC;YAAE,KAAK,IAAI,GAAG,CAAC;QACzE,KAAK,IAAI,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAClE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;IACzB,CAAC,CAAC;SACD,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;SAC1B,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC;SACjC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC;SACX,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,IAAY,EACZ,MAAc;IAEd,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,KAAK;QAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,IAAI,GAAG,EAAE,CAAC;IAClE,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAElE,MAAM,WAAW,GAAG,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC,CAAC;IACzE,MAAM,IAAI,GAAG,WAAW,CAAC,MAAM;QAC7B,CAAC,CAAC,iBAAiB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,IAAI,SAAS,CACjB,kBAAkB,IAAI,OAAO,IAAI,4BAA4B,CAC9D,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function layersCmd(args?: string[]): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { loadConfig } from './config-core.js';
|
|
2
|
+
export default function layersCmd(args = []) {
|
|
3
|
+
const namesOnly = args.includes('--names');
|
|
4
|
+
const config = loadConfig();
|
|
5
|
+
const layers = config.layers || {};
|
|
6
|
+
const entries = Object.entries(layers);
|
|
7
|
+
if (entries.length === 0) {
|
|
8
|
+
console.log('No layers in config. Run: arcq sync');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
entries.forEach(([key, url]) => {
|
|
12
|
+
console.log(namesOnly ? key : `${key} → ${url}`);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=layers-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layers-cmd.js","sourceRoot":"","sources":["../../lib/layers-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE9C,MAAM,CAAC,OAAO,UAAU,SAAS,CAAC,OAAiB,EAAE;IACnD,MAAM,SAAS,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;IACnC,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEvC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,CAAC,GAAG,CAAC,qCAAqC,CAAC,CAAC;QACnD,OAAO;IACT,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,EAAE;QAC7B,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,MAAM,GAAG,EAAE,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function listCmd(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { loadConfig } from './config-core.js';
|
|
2
|
+
import { getToken } from './token-core.js';
|
|
3
|
+
import { fetchServiceCatalog } from './arcgis-core.js';
|
|
4
|
+
export default async function listCmd(args) {
|
|
5
|
+
const config = loadConfig();
|
|
6
|
+
const serviceKey = args[0];
|
|
7
|
+
const serviceUrl = (serviceKey && config.services && config.services[serviceKey]) ||
|
|
8
|
+
serviceKey;
|
|
9
|
+
if (!serviceUrl) {
|
|
10
|
+
console.log('Usage: arcq list <service>');
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
const token = getToken();
|
|
14
|
+
const layers = await fetchServiceCatalog(serviceUrl, token);
|
|
15
|
+
layers.forEach((l) => {
|
|
16
|
+
console.log(`${l.id} → ${l.name}`);
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=list-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-cmd.js","sourceRoot":"","sources":["../../lib/list-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,OAAO,CAAC,IAAc;IAClD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAE3B,MAAM,UAAU,GACd,CAAC,UAAU,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAC9D,UAAU,CAAC;IAEb,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC;QAC1C,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAE5D,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACnB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACrC,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function queryCmd(args: string[]): Promise<void>;
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { loadContext } from './context-core.js';
|
|
2
|
+
import { loadConfig } from './config-core.js';
|
|
3
|
+
import { getToken } from './token-core.js';
|
|
4
|
+
import { queryLayer } from './arcgis-core.js';
|
|
5
|
+
import { ArcqError } from './errors.js';
|
|
6
|
+
import { resolveLayerArg } from './layer-resolve.js';
|
|
7
|
+
// The query summary prints by default; -q / --quiet suppresses it.
|
|
8
|
+
// -v / --verbose is still accepted (now a no-op) so it doesn't break the
|
|
9
|
+
// positional parsing for anyone with it in muscle memory.
|
|
10
|
+
function parseQueryArgs(args) {
|
|
11
|
+
const flags = { quiet: false, count: false };
|
|
12
|
+
const positionals = [];
|
|
13
|
+
for (let i = 0; i < args.length; i++) {
|
|
14
|
+
const arg = args[i];
|
|
15
|
+
switch (arg) {
|
|
16
|
+
case '-q':
|
|
17
|
+
case '--quiet':
|
|
18
|
+
flags.quiet = true;
|
|
19
|
+
break;
|
|
20
|
+
case '-v':
|
|
21
|
+
case '--verbose':
|
|
22
|
+
break;
|
|
23
|
+
case '--count':
|
|
24
|
+
flags.count = true;
|
|
25
|
+
break;
|
|
26
|
+
case '--out-fields':
|
|
27
|
+
case '--order-by':
|
|
28
|
+
case '--limit': {
|
|
29
|
+
const value = args[++i];
|
|
30
|
+
if (value === undefined) {
|
|
31
|
+
throw new ArcqError(`${arg} requires a value`);
|
|
32
|
+
}
|
|
33
|
+
if (arg === '--out-fields') {
|
|
34
|
+
flags.outFields = value;
|
|
35
|
+
}
|
|
36
|
+
else if (arg === '--order-by') {
|
|
37
|
+
flags.orderBy = value;
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
if (!/^\d+$/.test(value) || parseInt(value, 10) < 1) {
|
|
41
|
+
throw new ArcqError('--limit requires a positive integer');
|
|
42
|
+
}
|
|
43
|
+
flags.limit = parseInt(value, 10);
|
|
44
|
+
}
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
default:
|
|
48
|
+
if (arg.startsWith('-')) {
|
|
49
|
+
throw new ArcqError(`unknown flag '${arg}' for query`);
|
|
50
|
+
}
|
|
51
|
+
positionals.push(arg);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return { flags, positionals };
|
|
55
|
+
}
|
|
56
|
+
export default async function queryCmd(args) {
|
|
57
|
+
const { flags, positionals } = parseQueryArgs(args);
|
|
58
|
+
const ctx = loadContext();
|
|
59
|
+
const config = loadConfig();
|
|
60
|
+
let layerUrl;
|
|
61
|
+
let where;
|
|
62
|
+
let source;
|
|
63
|
+
if (positionals.length === 1) {
|
|
64
|
+
where = positionals[0];
|
|
65
|
+
if (!ctx) {
|
|
66
|
+
throw new ArcqError('no active layer - run: arcq use <name>');
|
|
67
|
+
}
|
|
68
|
+
layerUrl = ctx.url;
|
|
69
|
+
source =
|
|
70
|
+
ctx.name && ctx.service != null && ctx.layerId != null
|
|
71
|
+
? `${ctx.service}:${ctx.layerId} → ${ctx.name}`
|
|
72
|
+
: ctx.name || ctx.url;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
const resolved = resolveLayerArg(positionals[0], config);
|
|
76
|
+
layerUrl = resolved.url;
|
|
77
|
+
source = resolved.source;
|
|
78
|
+
where = positionals[1] ?? '1=1';
|
|
79
|
+
}
|
|
80
|
+
const token = getToken();
|
|
81
|
+
if (!flags.quiet) {
|
|
82
|
+
const rule = '─'.repeat(60);
|
|
83
|
+
console.error('');
|
|
84
|
+
console.error(rule);
|
|
85
|
+
console.error(`layer: ${source}`);
|
|
86
|
+
console.error(`where: ${where}`);
|
|
87
|
+
console.error(`endpoint: ${layerUrl}/query`);
|
|
88
|
+
console.error(rule);
|
|
89
|
+
console.error('');
|
|
90
|
+
}
|
|
91
|
+
if (flags.count) {
|
|
92
|
+
// Single count request — --out-fields and --limit are ignored here
|
|
93
|
+
// (documented in help), --order-by passes through harmlessly.
|
|
94
|
+
const data = await queryLayer(layerUrl, {
|
|
95
|
+
where,
|
|
96
|
+
f: 'json',
|
|
97
|
+
token,
|
|
98
|
+
returnCountOnly: true,
|
|
99
|
+
...(flags.orderBy !== undefined && { orderByFields: flags.orderBy }),
|
|
100
|
+
});
|
|
101
|
+
console.log(JSON.stringify({ count: data.count ?? 0 }));
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const all = [];
|
|
105
|
+
let offset = 0;
|
|
106
|
+
while (true) {
|
|
107
|
+
const pageSize = flags.limit != null ? Math.min(1000, flags.limit - all.length) : 1000;
|
|
108
|
+
const data = await queryLayer(layerUrl, {
|
|
109
|
+
where,
|
|
110
|
+
outFields: flags.outFields ?? '*',
|
|
111
|
+
f: 'json',
|
|
112
|
+
token,
|
|
113
|
+
resultOffset: offset,
|
|
114
|
+
resultRecordCount: pageSize,
|
|
115
|
+
...(flags.orderBy !== undefined && { orderByFields: flags.orderBy }),
|
|
116
|
+
});
|
|
117
|
+
const features = data.features || [];
|
|
118
|
+
all.push(...features);
|
|
119
|
+
if (!data.exceededTransferLimit || features.length === 0)
|
|
120
|
+
break;
|
|
121
|
+
if (flags.limit != null && all.length >= flags.limit)
|
|
122
|
+
break;
|
|
123
|
+
offset += features.length;
|
|
124
|
+
}
|
|
125
|
+
// Defends against a server returning more rows than asked.
|
|
126
|
+
if (flags.limit != null)
|
|
127
|
+
all.length = Math.min(all.length, flags.limit);
|
|
128
|
+
console.log(JSON.stringify(all.map((f) => f.attributes), null, 2));
|
|
129
|
+
}
|
|
130
|
+
//# sourceMappingURL=query-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-cmd.js","sourceRoot":"","sources":["../../lib/query-cmd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function refreshCmd(): Promise<void>;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { loadConfig } from './config-core.js';
|
|
2
|
+
import { getToken } from './token-core.js';
|
|
3
|
+
import { fetchServiceCatalog } from './arcgis-core.js';
|
|
4
|
+
import { saveCache } from './cache-core.js';
|
|
5
|
+
export default async function refreshCmd() {
|
|
6
|
+
const config = loadConfig();
|
|
7
|
+
const token = getToken();
|
|
8
|
+
const cache = {};
|
|
9
|
+
for (const [name, url] of Object.entries(config.services || {})) {
|
|
10
|
+
console.error(`[arcq] indexing ${name}...`);
|
|
11
|
+
cache[name] = await fetchServiceCatalog(url, token);
|
|
12
|
+
}
|
|
13
|
+
saveCache(cache);
|
|
14
|
+
console.log('[arcq] cache updated');
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=refresh-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refresh-cmd.js","sourceRoot":"","sources":["../../lib/refresh-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,UAAU;IACtC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IAEzB,MAAM,KAAK,GAAU,EAAE,CAAC;IAExB,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,mBAAmB,IAAI,KAAK,CAAC,CAAC;QAC5C,KAAK,CAAC,IAAI,CAAC,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACtD,CAAC;IAED,SAAS,CAAC,KAAK,CAAC,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AACtC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function servicesCmd(args: string[]): void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from './config-core.js';
|
|
2
|
+
export default function servicesCmd(args) {
|
|
3
|
+
const sub = args[0];
|
|
4
|
+
if (sub === 'add') {
|
|
5
|
+
const name = args[1];
|
|
6
|
+
const url = args[2];
|
|
7
|
+
if (!name || !url) {
|
|
8
|
+
console.log('Usage: arcq services add <name> <url>');
|
|
9
|
+
return;
|
|
10
|
+
}
|
|
11
|
+
const config = loadConfig();
|
|
12
|
+
config.services = { ...config.services, [name]: url };
|
|
13
|
+
saveConfig(config);
|
|
14
|
+
console.log(`[arcq] service added → ${name}`);
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
console.log('Usage:');
|
|
18
|
+
console.log(' arcq services add <name> <url>');
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=services-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"services-cmd.js","sourceRoot":"","sources":["../../lib/services-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAE1D,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,IAAc;IAChD,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IAEpB,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YAClB,OAAO,CAAC,GAAG,CAAC,uCAAuC,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QAED,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,CAAC,QAAQ,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;QACtD,UAAU,CAAC,MAAM,CAAC,CAAC;QACnB,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;QAC9C,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IACtB,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function syncCmd(): Promise<void>;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { loadConfig, saveConfig } from './config-core.js';
|
|
2
|
+
import { getToken } from './token-core.js';
|
|
3
|
+
import { fetchServiceCatalog } from './arcgis-core.js';
|
|
4
|
+
function toLayerKey(serviceName, layerName) {
|
|
5
|
+
const slug = layerName
|
|
6
|
+
.toLowerCase()
|
|
7
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
8
|
+
.replace(/^-+|-+$/g, '');
|
|
9
|
+
return `${serviceName}-${slug}`;
|
|
10
|
+
}
|
|
11
|
+
export default async function syncCmd() {
|
|
12
|
+
const config = loadConfig();
|
|
13
|
+
const token = getToken();
|
|
14
|
+
const layers = {};
|
|
15
|
+
for (const [name, url] of Object.entries(config.services || {})) {
|
|
16
|
+
console.error(`[arcq] syncing ${name}...`);
|
|
17
|
+
const catalog = await fetchServiceCatalog(url, token);
|
|
18
|
+
for (const layer of catalog) {
|
|
19
|
+
layers[toLayerKey(name, layer.name)] = layer.url;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
saveConfig({ ...config, layers });
|
|
23
|
+
console.log('[arcq] config layers updated');
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=sync-cmd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sync-cmd.js","sourceRoot":"","sources":["../../lib/sync-cmd.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAEvD,SAAS,UAAU,CAAC,WAAmB,EAAE,SAAiB;IACxD,MAAM,IAAI,GAAG,SAAS;SACnB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC3B,OAAO,GAAG,WAAW,IAAI,IAAI,EAAE,CAAC;AAClC,CAAC;AAED,MAAM,CAAC,OAAO,CAAC,KAAK,UAAU,OAAO;IACnC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,MAAM,KAAK,GAAG,QAAQ,EAAE,CAAC;IACzB,MAAM,MAAM,GAA2B,EAAE,CAAC;IAE1C,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,kBAAkB,IAAI,KAAK,CAAC,CAAC;QAC3C,MAAM,OAAO,GAAG,MAAM,mBAAmB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC;QACnD,CAAC;IACH,CAAC;IAED,UAAU,CAAC,EAAE,GAAG,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAClC,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;AAC9C,CAAC"}
|