@basemaps/cli-config 8.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 +35 -0
- package/build/__tests__/util.test.d.ts +1 -0
- package/build/__tests__/util.test.js +15 -0
- package/build/__tests__/util.test.js.map +1 -0
- package/build/bin.d.ts +1 -0
- package/build/bin.js +11 -0
- package/build/bin.js.map +1 -0
- package/build/cli/action.bundle.assets.d.ts +17 -0
- package/build/cli/action.bundle.assets.js +97 -0
- package/build/cli/action.bundle.assets.js.map +1 -0
- package/build/cli/action.bundle.d.ts +21 -0
- package/build/cli/action.bundle.js +58 -0
- package/build/cli/action.bundle.js.map +1 -0
- package/build/cli/action.create.config.d.ts +19 -0
- package/build/cli/action.create.config.js +79 -0
- package/build/cli/action.create.config.js.map +1 -0
- package/build/cli/action.import.d.ts +19 -0
- package/build/cli/action.import.js +335 -0
- package/build/cli/action.import.js.map +1 -0
- package/build/cli/config.diff.d.ts +27 -0
- package/build/cli/config.diff.js +146 -0
- package/build/cli/config.diff.js.map +1 -0
- package/build/cli/config.update.d.ts +24 -0
- package/build/cli/config.update.js +115 -0
- package/build/cli/config.update.js.map +1 -0
- package/build/index.d.ts +105 -0
- package/build/index.js +15 -0
- package/build/index.js.map +1 -0
- package/build/util.d.ts +23 -0
- package/build/util.js +136 -0
- package/build/util.js.map +1 -0
- package/package.json +55 -0
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ConfigId, ConfigPrefix, } from '@basemaps/config';
|
|
2
|
+
import { ConfigDynamoBase, LogConfig } from '@basemaps/shared';
|
|
3
|
+
import PLimit from 'p-limit';
|
|
4
|
+
import { ConfigDiff } from './config.diff.js';
|
|
5
|
+
export const Q = PLimit(10);
|
|
6
|
+
export class Updater {
|
|
7
|
+
/**
|
|
8
|
+
* Class to apply an TileSetConfig source to the tile metadata db
|
|
9
|
+
* @param config a string or TileSetConfig to use
|
|
10
|
+
*/
|
|
11
|
+
constructor(config, oldConfig, isCommit) {
|
|
12
|
+
Object.defineProperty(this, "config", {
|
|
13
|
+
enumerable: true,
|
|
14
|
+
configurable: true,
|
|
15
|
+
writable: true,
|
|
16
|
+
value: void 0
|
|
17
|
+
});
|
|
18
|
+
Object.defineProperty(this, "_oldData", {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
configurable: true,
|
|
21
|
+
writable: true,
|
|
22
|
+
value: void 0
|
|
23
|
+
});
|
|
24
|
+
Object.defineProperty(this, "prefix", {
|
|
25
|
+
enumerable: true,
|
|
26
|
+
configurable: true,
|
|
27
|
+
writable: true,
|
|
28
|
+
value: void 0
|
|
29
|
+
});
|
|
30
|
+
Object.defineProperty(this, "isCommit", {
|
|
31
|
+
enumerable: true,
|
|
32
|
+
configurable: true,
|
|
33
|
+
writable: true,
|
|
34
|
+
value: void 0
|
|
35
|
+
});
|
|
36
|
+
Object.defineProperty(this, "logger", {
|
|
37
|
+
enumerable: true,
|
|
38
|
+
configurable: true,
|
|
39
|
+
writable: true,
|
|
40
|
+
value: void 0
|
|
41
|
+
});
|
|
42
|
+
Object.defineProperty(this, "cfg", {
|
|
43
|
+
enumerable: true,
|
|
44
|
+
configurable: true,
|
|
45
|
+
writable: true,
|
|
46
|
+
value: void 0
|
|
47
|
+
});
|
|
48
|
+
this.config = config;
|
|
49
|
+
this.cfg = oldConfig;
|
|
50
|
+
const prefix = ConfigId.getPrefix(config.id);
|
|
51
|
+
if (prefix == null)
|
|
52
|
+
throw new Error(`Incorrect Config Id ${config.id}`);
|
|
53
|
+
this.prefix = prefix;
|
|
54
|
+
this.isCommit = isCommit ? isCommit : false;
|
|
55
|
+
this.logger = LogConfig.get();
|
|
56
|
+
}
|
|
57
|
+
getDB() {
|
|
58
|
+
if (this.prefix === ConfigPrefix.Imagery)
|
|
59
|
+
return this.cfg.Imagery;
|
|
60
|
+
if (this.prefix === ConfigPrefix.TileSet)
|
|
61
|
+
return this.cfg.TileSet;
|
|
62
|
+
if (this.prefix === ConfigPrefix.Provider)
|
|
63
|
+
return this.cfg.Provider;
|
|
64
|
+
if (this.prefix === ConfigPrefix.Style)
|
|
65
|
+
return this.cfg.Style;
|
|
66
|
+
throw Error(`Unable to find the database table for prefix ${this.prefix}`);
|
|
67
|
+
}
|
|
68
|
+
getConfig() {
|
|
69
|
+
if (this.prefix === ConfigPrefix.Imagery)
|
|
70
|
+
return this.config;
|
|
71
|
+
if (this.prefix === ConfigPrefix.TileSet)
|
|
72
|
+
return this.config;
|
|
73
|
+
if (this.prefix === ConfigPrefix.Provider)
|
|
74
|
+
return this.config;
|
|
75
|
+
if (this.prefix === ConfigPrefix.Style)
|
|
76
|
+
return this.config;
|
|
77
|
+
throw Error(`Failed to cast the config ${this.prefix}`);
|
|
78
|
+
}
|
|
79
|
+
invalidatePath() {
|
|
80
|
+
if (this.prefix === ConfigPrefix.Provider)
|
|
81
|
+
return '/v1/*/WMTSCapabilities.xml';
|
|
82
|
+
else if (this.prefix === ConfigPrefix.Style)
|
|
83
|
+
return `/v1/tiles/togographic/style/${this.config.id.slice(3)}.json`;
|
|
84
|
+
else
|
|
85
|
+
return `/v1/tiles/${this.config.id.slice(3)}/*`;
|
|
86
|
+
}
|
|
87
|
+
getOldData() {
|
|
88
|
+
if (this._oldData)
|
|
89
|
+
return this._oldData;
|
|
90
|
+
this._oldData = this.getDB().get(this.config.id);
|
|
91
|
+
return this._oldData;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Reconcile the differences between the config and the tile metadata DB and update if changed.
|
|
95
|
+
*/
|
|
96
|
+
async reconcile() {
|
|
97
|
+
const newData = this.getConfig();
|
|
98
|
+
const db = this.getDB();
|
|
99
|
+
const oldData = await this.getOldData();
|
|
100
|
+
if (oldData == null || ConfigDiff.showDiff(db.prefix, oldData, newData, this.logger)) {
|
|
101
|
+
const operation = oldData == null ? 'Insert' : 'Update';
|
|
102
|
+
this.logger.info({ type: db.prefix, record: newData.id, description: newData.name, commit: this.isCommit }, `Change:${operation}`);
|
|
103
|
+
if (this.isCommit) {
|
|
104
|
+
if (db instanceof ConfigDynamoBase)
|
|
105
|
+
await db.put(newData);
|
|
106
|
+
else
|
|
107
|
+
throw new Error('Unable to commit changes to: ' + db.prefix);
|
|
108
|
+
}
|
|
109
|
+
return true;
|
|
110
|
+
}
|
|
111
|
+
this.logger.trace({ type: db.prefix, record: newData.id }, 'NoChanges');
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=config.update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.update.js","sourceRoot":"","sources":["../../src/cli/config.update.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export declare const ConfigCli: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
|
|
2
|
+
parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<{
|
|
3
|
+
command: "bundle-assets";
|
|
4
|
+
args: {
|
|
5
|
+
assets: string;
|
|
6
|
+
output: string;
|
|
7
|
+
verbose: boolean;
|
|
8
|
+
extraVerbose: boolean;
|
|
9
|
+
};
|
|
10
|
+
} | {
|
|
11
|
+
command: "bundle";
|
|
12
|
+
args: {
|
|
13
|
+
config: string;
|
|
14
|
+
output: string;
|
|
15
|
+
assets: string | undefined;
|
|
16
|
+
cache: string | undefined;
|
|
17
|
+
verbose: boolean;
|
|
18
|
+
extraVerbose: boolean;
|
|
19
|
+
};
|
|
20
|
+
} | {
|
|
21
|
+
command: "create-config";
|
|
22
|
+
args: {
|
|
23
|
+
target: URL | undefined;
|
|
24
|
+
concurrency: number;
|
|
25
|
+
host: URL | undefined;
|
|
26
|
+
path: URL;
|
|
27
|
+
verbose: boolean;
|
|
28
|
+
extraVerbose: boolean;
|
|
29
|
+
};
|
|
30
|
+
} | {
|
|
31
|
+
command: "import";
|
|
32
|
+
args: {
|
|
33
|
+
config: string;
|
|
34
|
+
output: string;
|
|
35
|
+
target: string | undefined;
|
|
36
|
+
commit: boolean;
|
|
37
|
+
verbose: boolean;
|
|
38
|
+
extraVerbose: boolean;
|
|
39
|
+
};
|
|
40
|
+
}>>;
|
|
41
|
+
} & import("cmd-ts/dist/cjs/helpdoc.js").Named & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive & import("cmd-ts/dist/cjs/helpdoc.js").Versioned> & import("cmd-ts/dist/cjs/helpdoc.js").PrintHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Versioned> & import("cmd-ts/dist/cjs/argparser.js").Register & import("cmd-ts/dist/cjs/runner.js").Handling<{
|
|
42
|
+
command: "bundle-assets";
|
|
43
|
+
args: {
|
|
44
|
+
assets: string;
|
|
45
|
+
output: string;
|
|
46
|
+
verbose: boolean;
|
|
47
|
+
extraVerbose: boolean;
|
|
48
|
+
};
|
|
49
|
+
} | {
|
|
50
|
+
command: "bundle";
|
|
51
|
+
args: {
|
|
52
|
+
config: string;
|
|
53
|
+
output: string;
|
|
54
|
+
assets: string | undefined;
|
|
55
|
+
cache: string | undefined;
|
|
56
|
+
verbose: boolean;
|
|
57
|
+
extraVerbose: boolean;
|
|
58
|
+
};
|
|
59
|
+
} | {
|
|
60
|
+
command: "create-config";
|
|
61
|
+
args: {
|
|
62
|
+
target: URL | undefined;
|
|
63
|
+
concurrency: number;
|
|
64
|
+
host: URL | undefined;
|
|
65
|
+
path: URL;
|
|
66
|
+
verbose: boolean;
|
|
67
|
+
extraVerbose: boolean;
|
|
68
|
+
};
|
|
69
|
+
} | {
|
|
70
|
+
command: "import";
|
|
71
|
+
args: {
|
|
72
|
+
config: string;
|
|
73
|
+
output: string;
|
|
74
|
+
target: string | undefined;
|
|
75
|
+
commit: boolean;
|
|
76
|
+
verbose: boolean;
|
|
77
|
+
extraVerbose: boolean;
|
|
78
|
+
};
|
|
79
|
+
}, {
|
|
80
|
+
command: "bundle-assets";
|
|
81
|
+
value: Promise<void>;
|
|
82
|
+
} | {
|
|
83
|
+
command: "bundle";
|
|
84
|
+
value: Promise<void>;
|
|
85
|
+
} | {
|
|
86
|
+
command: "create-config";
|
|
87
|
+
value: Promise<void>;
|
|
88
|
+
} | {
|
|
89
|
+
command: "import";
|
|
90
|
+
value: Promise<void>;
|
|
91
|
+
}> & {
|
|
92
|
+
run(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<{
|
|
93
|
+
command: "bundle-assets";
|
|
94
|
+
value: Promise<void>;
|
|
95
|
+
} | {
|
|
96
|
+
command: "bundle";
|
|
97
|
+
value: Promise<void>;
|
|
98
|
+
} | {
|
|
99
|
+
command: "create-config";
|
|
100
|
+
value: Promise<void>;
|
|
101
|
+
} | {
|
|
102
|
+
command: "import";
|
|
103
|
+
value: Promise<void>;
|
|
104
|
+
}>>;
|
|
105
|
+
};
|
package/build/index.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { subcommands } from 'cmd-ts';
|
|
2
|
+
import { BundleAssetsCommand } from './cli/action.bundle.assets.js';
|
|
3
|
+
import { BundleCommand } from './cli/action.bundle.js';
|
|
4
|
+
import { CreateConfigCommand } from './cli/action.create.config.js';
|
|
5
|
+
import { ImportCommand } from './cli/action.import.js';
|
|
6
|
+
export const ConfigCli = subcommands({
|
|
7
|
+
name: 'config',
|
|
8
|
+
cmds: {
|
|
9
|
+
bundle: BundleCommand,
|
|
10
|
+
'bundle-assets': BundleAssetsCommand,
|
|
11
|
+
import: ImportCommand,
|
|
12
|
+
'create-config': CreateConfigCommand,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,QAAQ,CAAC;AAErC,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,CAAC,MAAM,SAAS,GAAG,WAAW,CAAC;IACnC,IAAI,EAAE,QAAQ;IACd,IAAI,EAAE;QACJ,MAAM,EAAE,aAAa;QACrB,eAAe,EAAE,mBAAmB;QACpC,MAAM,EAAE,aAAa;QACrB,eAAe,EAAE,mBAAmB;KACrC;CACF,CAAC,CAAC"}
|
package/build/util.d.ts
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export declare function isRecord<T = unknown>(value: unknown): value is Record<string, T>;
|
|
2
|
+
/**
|
|
3
|
+
* Invalidate the cloudfront distribution cache when updating imagery sets
|
|
4
|
+
*/
|
|
5
|
+
export declare function invalidateCache(path: string | string[], commit?: boolean): Promise<void>;
|
|
6
|
+
export declare const HashKey = "linz-hash";
|
|
7
|
+
export declare function getHash(Bucket: string, Key: string): Promise<string | null>;
|
|
8
|
+
export declare function getStaticBucket(): Promise<string>;
|
|
9
|
+
/**
|
|
10
|
+
* Upload a file to the static bucket
|
|
11
|
+
* @param path source file
|
|
12
|
+
* @param target target key @example '/foo/bar.html'
|
|
13
|
+
* @param contentType http content type @example 'application/json'
|
|
14
|
+
* @param cacheControl cache control headers @example 'public, max-age=604800, immutable'
|
|
15
|
+
* @returns whether the item was updated
|
|
16
|
+
*/
|
|
17
|
+
export declare function uploadStaticFile(filePath: URL, target: string, contentType: string, cacheControl: string): Promise<boolean>;
|
|
18
|
+
/**
|
|
19
|
+
* Make a tile imagery title as imagery name
|
|
20
|
+
* @example
|
|
21
|
+
* 'Tasman rural 2018-19 0.3m' => 'tasman_rural_2018-19_0-3m'
|
|
22
|
+
*/
|
|
23
|
+
export declare function nameImageryTitle(title: string): string;
|
package/build/util.js
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { CloudFormationClient, DescribeStacksCommand } from '@aws-sdk/client-cloudformation';
|
|
2
|
+
import { CloudFrontClient, CreateInvalidationCommand, ListDistributionsCommand } from '@aws-sdk/client-cloudfront';
|
|
3
|
+
import { HeadObjectCommand, PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
|
4
|
+
import { fsa, LogConfig } from '@basemaps/shared';
|
|
5
|
+
import { CliId } from '@basemaps/shared/build/cli/info.js';
|
|
6
|
+
import crypto from 'crypto';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
import slugify from 'slugify';
|
|
9
|
+
import { promisify } from 'util';
|
|
10
|
+
import { gzip } from 'zlib';
|
|
11
|
+
// Cloudfront has to be defined in us-east-1
|
|
12
|
+
const cloudFormationClient = new CloudFormationClient({ region: 'us-east-1' });
|
|
13
|
+
const cloudFrontClient = new CloudFrontClient({ region: 'us-east-1' });
|
|
14
|
+
const s3Client = new S3Client({ region: 'us-east-1' });
|
|
15
|
+
/** cloudfront invalidation references need to be unique */
|
|
16
|
+
let InvalidationId = 0;
|
|
17
|
+
export function isRecord(value) {
|
|
18
|
+
return typeof value === 'object' && value !== null;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Invalidate the cloudfront distribution cache when updating imagery sets
|
|
22
|
+
*/
|
|
23
|
+
export async function invalidateCache(path, commit = false) {
|
|
24
|
+
const command = new DescribeStacksCommand({ StackName: 'Edge' });
|
|
25
|
+
const response = await cloudFormationClient.send(command);
|
|
26
|
+
if (response.Stacks?.[0].Outputs == null) {
|
|
27
|
+
LogConfig.get().warn('Unable to find cloud front distribution');
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
const cloudFrontDomain = response.Stacks[0].Outputs.find((f) => f.OutputKey === 'CloudFrontDomain');
|
|
31
|
+
const listDistributionCommand = new ListDistributionsCommand({});
|
|
32
|
+
const cloudFrontDistributions = await cloudFrontClient.send(listDistributionCommand);
|
|
33
|
+
const cf = cloudFrontDistributions.DistributionList?.Items?.find((f) => f.DomainName === cloudFrontDomain?.OutputValue);
|
|
34
|
+
if (cloudFrontDomain == null || cf == null) {
|
|
35
|
+
LogConfig.get().warn('Unable to find cloud front distribution');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
LogConfig.get().info({ path, cfId: cf.Id }, 'Invalidating');
|
|
39
|
+
const Items = Array.isArray(path) ? path : [path];
|
|
40
|
+
if (commit) {
|
|
41
|
+
const invalidationCommand = new CreateInvalidationCommand({
|
|
42
|
+
DistributionId: cf.Id,
|
|
43
|
+
InvalidationBatch: {
|
|
44
|
+
Paths: { Quantity: Items.length, Items },
|
|
45
|
+
CallerReference: `${CliId}-${InvalidationId++}`,
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
await cloudFrontClient.send(invalidationCommand);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
export const HashKey = 'linz-hash';
|
|
52
|
+
export async function getHash(Bucket, Key) {
|
|
53
|
+
try {
|
|
54
|
+
const command = new HeadObjectCommand({ Bucket, Key });
|
|
55
|
+
const obj = await s3Client.send(command);
|
|
56
|
+
return obj.Metadata?.[HashKey] ?? null;
|
|
57
|
+
}
|
|
58
|
+
catch (e) {
|
|
59
|
+
if (isRecord(e) && isRecord(e['$metadata']) && typeof e['$metadata']['httpStatusCode'] === 'number') {
|
|
60
|
+
if (e['$metadata']['httpStatusCode'] === 404)
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
throw e;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Lookup the static bucket from cloudformation
|
|
68
|
+
* @returns
|
|
69
|
+
*/
|
|
70
|
+
let staticBucket;
|
|
71
|
+
export function getStaticBucket() {
|
|
72
|
+
if (staticBucket == null) {
|
|
73
|
+
// Since the bucket is generated inside of CDK lets look up the bucket name
|
|
74
|
+
const command = new DescribeStacksCommand({ StackName: 'Edge' });
|
|
75
|
+
staticBucket = cloudFormationClient.send(command).then((stackInfo) => {
|
|
76
|
+
const val = stackInfo.Stacks?.[0]?.Outputs?.find((f) => f.OutputKey === 'CloudFrontBucket')?.OutputValue;
|
|
77
|
+
if (val == null)
|
|
78
|
+
throw new Error('Failed to find EdgeBucket');
|
|
79
|
+
return val;
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
return staticBucket;
|
|
83
|
+
}
|
|
84
|
+
/** Extensions that should be gzipped before uploading */
|
|
85
|
+
const CompressExt = new Set(['.js', '.html', '.css', '.map', '.json', '.svg']);
|
|
86
|
+
const gzipPromise = promisify(gzip);
|
|
87
|
+
/**
|
|
88
|
+
* Upload a file to the static bucket
|
|
89
|
+
* @param path source file
|
|
90
|
+
* @param target target key @example '/foo/bar.html'
|
|
91
|
+
* @param contentType http content type @example 'application/json'
|
|
92
|
+
* @param cacheControl cache control headers @example 'public, max-age=604800, immutable'
|
|
93
|
+
* @returns whether the item was updated
|
|
94
|
+
*/
|
|
95
|
+
export async function uploadStaticFile(filePath, target, contentType, cacheControl) {
|
|
96
|
+
const fileData = await fsa.read(filePath);
|
|
97
|
+
const hash = crypto.createHash('sha512').update(fileData).digest('base64');
|
|
98
|
+
// S3 keys should not start with a `/`
|
|
99
|
+
if (target.startsWith('/'))
|
|
100
|
+
target = target.slice(1);
|
|
101
|
+
const bucket = await getStaticBucket();
|
|
102
|
+
if (bucket == null)
|
|
103
|
+
throw new Error('Unable to find static bucket');
|
|
104
|
+
const existing = await getHash(bucket, target);
|
|
105
|
+
if (hash === existing)
|
|
106
|
+
return false;
|
|
107
|
+
// Should we compress the file before uploading
|
|
108
|
+
const ext = path.extname(target);
|
|
109
|
+
const contentEncoding = CompressExt.has(ext) ? 'gzip' : undefined;
|
|
110
|
+
const command = new PutObjectCommand({
|
|
111
|
+
Bucket: bucket,
|
|
112
|
+
Key: target,
|
|
113
|
+
Body: contentEncoding === 'gzip' ? await gzipPromise(fileData, { level: 9 }) : fileData,
|
|
114
|
+
Metadata: { [HashKey]: hash },
|
|
115
|
+
ContentType: contentType,
|
|
116
|
+
CacheControl: cacheControl,
|
|
117
|
+
ContentEncoding: contentEncoding,
|
|
118
|
+
});
|
|
119
|
+
await s3Client.send(command);
|
|
120
|
+
return true;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Make a tile imagery title as imagery name
|
|
124
|
+
* @example
|
|
125
|
+
* 'Tasman rural 2018-19 0.3m' => 'tasman_rural_2018-19_0-3m'
|
|
126
|
+
*/
|
|
127
|
+
export function nameImageryTitle(title) {
|
|
128
|
+
return slugify
|
|
129
|
+
.default(title.replace(/\.+/g, '-'), {
|
|
130
|
+
replacement: '_',
|
|
131
|
+
lower: true,
|
|
132
|
+
trim: true,
|
|
133
|
+
})
|
|
134
|
+
.replace(/[^\w-_]/gi, '');
|
|
135
|
+
}
|
|
136
|
+
//# sourceMappingURL=util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@basemaps/cli-config",
|
|
3
|
+
"version": "8.0.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/linz/basemaps.git",
|
|
8
|
+
"directory": "packages/cli-config"
|
|
9
|
+
},
|
|
10
|
+
"author": {
|
|
11
|
+
"name": "Land Information New Zealand",
|
|
12
|
+
"url": "https://linz.govt.nz",
|
|
13
|
+
"organization": true
|
|
14
|
+
},
|
|
15
|
+
"type": "module",
|
|
16
|
+
"engines": {
|
|
17
|
+
"node": ">=16.0.0"
|
|
18
|
+
},
|
|
19
|
+
"license": "MIT",
|
|
20
|
+
"main": "./build/index.js",
|
|
21
|
+
"types": "./build/index.d.ts",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"build": "tsc",
|
|
24
|
+
"test": "node --test"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@basemaps/config": "^8.0.0",
|
|
28
|
+
"@basemaps/config-loader": "^8.0.0",
|
|
29
|
+
"@basemaps/geo": "^8.0.0",
|
|
30
|
+
"@basemaps/shared": "^8.0.0",
|
|
31
|
+
"@cotar/builder": "^6.0.1",
|
|
32
|
+
"@cotar/core": "^6.0.1",
|
|
33
|
+
"@cotar/tar": "^6.0.1",
|
|
34
|
+
"@linzjs/metrics": "^8.0.0",
|
|
35
|
+
"ansi-colors": "^4.1.1",
|
|
36
|
+
"cmd-ts": "^0.12.1",
|
|
37
|
+
"deep-diff": "^1.0.2",
|
|
38
|
+
"node-fetch": "^3.2.3",
|
|
39
|
+
"p-limit": "^4.0.0",
|
|
40
|
+
"slugify": "^1.6.5"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@aws-sdk/client-cloudformation": "^3.470.0",
|
|
44
|
+
"@aws-sdk/client-cloudfront": "^3.470.0",
|
|
45
|
+
"@aws-sdk/client-s3": "^3.470.0",
|
|
46
|
+
"@types/deep-diff": "^1.0.1"
|
|
47
|
+
},
|
|
48
|
+
"publishConfig": {
|
|
49
|
+
"access": "public"
|
|
50
|
+
},
|
|
51
|
+
"files": [
|
|
52
|
+
"build/"
|
|
53
|
+
],
|
|
54
|
+
"gitHead": "852c7c8bcbe06d065de732f23a6ebc2dd6a19cfc"
|
|
55
|
+
}
|