@git.zone/tspublish 1.15.0 → 2.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/.smartconfig.json +1 -1
- package/dist_ts/00_commitinfo_data.js +3 -3
- package/dist_ts/classes.tspublish.d.ts +2 -5
- package/dist_ts/classes.tspublish.js +3 -41
- package/dist_ts/index.d.ts +2 -1
- package/dist_ts/index.js +10 -9
- package/dist_ts/paths.d.ts +0 -2
- package/dist_ts/paths.js +1 -4
- package/dist_ts/plugins.d.ts +1 -11
- package/dist_ts/plugins.js +2 -12
- package/package.json +4 -14
- package/readme.md +17 -21
- package/ts/00_commitinfo_data.ts +2 -2
- package/ts/classes.tspublish.ts +2 -43
- package/ts/index.ts +10 -7
- package/ts/paths.ts +0 -8
- package/ts/plugins.ts +1 -11
- package/dist_ts/classes.giteaassets.d.ts +0 -32
- package/dist_ts/classes.giteaassets.js +0 -81
- package/dist_ts/classes.publishmodule.d.ts +0 -40
- package/dist_ts/classes.publishmodule.js +0 -232
- package/dist_ts/logging.d.ts +0 -15
- package/dist_ts/logging.js +0 -87
- package/ts/classes.giteaassets.ts +0 -108
- package/ts/classes.publishmodule.ts +0 -300
- package/ts/logging.ts +0 -104
package/.smartconfig.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"githost": "code.foss.global",
|
|
6
6
|
"gitscope": "git.zone",
|
|
7
7
|
"gitrepo": "tspublish",
|
|
8
|
-
"description": "A tool to
|
|
8
|
+
"description": "A tool to plan and prepare multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.",
|
|
9
9
|
"npmPackagename": "@git.zone/tspublish",
|
|
10
10
|
"license": "MIT",
|
|
11
11
|
"projectDomain": "git.zone",
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tspublish',
|
|
6
|
-
version: '
|
|
7
|
-
description: 'A tool to
|
|
6
|
+
version: '2.0.0',
|
|
7
|
+
description: 'A tool to plan and prepare multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.'
|
|
8
8
|
};
|
|
9
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
9
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiMDBfY29tbWl0aW5mb19kYXRhLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvMDBfY29tbWl0aW5mb19kYXRhLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOztHQUVHO0FBQ0gsTUFBTSxDQUFDLE1BQU0sVUFBVSxHQUFHO0lBQ3hCLElBQUksRUFBRSxxQkFBcUI7SUFDM0IsT0FBTyxFQUFFLE9BQU87SUFDaEIsV0FBVyxFQUFFLGlKQUFpSjtDQUMvSixDQUFBIn0=
|
|
@@ -1,16 +1,13 @@
|
|
|
1
1
|
import * as interfaces from './interfaces/index.js';
|
|
2
|
-
|
|
2
|
+
/** Plans and prepares packages; a release coordinator such as `gitzone release` publishes them. */
|
|
3
3
|
export declare class TsPublish {
|
|
4
|
-
giteaAssetsInstance: GiteaAssets;
|
|
5
|
-
constructor();
|
|
6
|
-
publish(monorepoDirArg: string): Promise<void>;
|
|
7
4
|
/** Read-only package discovery, dependency ordering and manifest validation. */
|
|
8
5
|
plan(directory: string): Promise<interfaces.ITsPublishPlan>;
|
|
9
6
|
/** Prepare built modules for a release owner; never publishes or contacts a registry. */
|
|
10
7
|
prepare(directory: string, outputDirectory: string): Promise<interfaces.ITsPublishPreparedModule[]>;
|
|
11
8
|
/**
|
|
12
9
|
* Discovers every `ts*` descriptor, named or order-only, in dependency order. Build tools and
|
|
13
|
-
* release coordinators call it as a library, so it stays silent
|
|
10
|
+
* release coordinators call it as a library, so it stays silent.
|
|
14
11
|
*/
|
|
15
12
|
getModuleSubDirs(dirArg: string): Promise<Record<string, interfaces.ITsPublishJson>>;
|
|
16
13
|
}
|
|
@@ -1,47 +1,9 @@
|
|
|
1
|
-
import { logInfo, logWarn, logHeader, logPackage, logProgress, logSeparator } from './logging.js';
|
|
2
1
|
import * as plugins from './plugins.js';
|
|
3
2
|
import * as interfaces from './interfaces/index.js';
|
|
4
|
-
import { PublishModule } from './classes.publishmodule.js';
|
|
5
|
-
import { GiteaAssets } from './classes.giteaassets.js';
|
|
6
3
|
import { createPackagePlan, orderPublishModules } from './functions.packageplan.js';
|
|
7
4
|
import { PackagePreparer } from './classes.packagepreparer.js';
|
|
5
|
+
/** Plans and prepares packages; a release coordinator such as `gitzone release` publishes them. */
|
|
8
6
|
export class TsPublish {
|
|
9
|
-
constructor() {
|
|
10
|
-
this.giteaAssetsInstance = new GiteaAssets({
|
|
11
|
-
giteaBaseUrl: 'https://code.foss.global',
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
async publish(monorepoDirArg) {
|
|
15
|
-
logHeader('TSPublish - Module Publisher');
|
|
16
|
-
const publishModules = await this.getModuleSubDirs(monorepoDirArg);
|
|
17
|
-
const plan = await createPackagePlan(monorepoDirArg, publishModules);
|
|
18
|
-
if (!plan.modules.length)
|
|
19
|
-
throw new Error('No named tspublish modules were found.');
|
|
20
|
-
logInfo(`Found ${Object.keys(publishModules).length} publish modules`);
|
|
21
|
-
logSeparator();
|
|
22
|
-
for (const publishModule of Object.keys(publishModules)) {
|
|
23
|
-
logPackage('Module found', `${publishModule} → ${publishModules[publishModule].name}`);
|
|
24
|
-
}
|
|
25
|
-
for (const publishModule of Object.keys(publishModules)) {
|
|
26
|
-
// lets check wether there is a name
|
|
27
|
-
if (!publishModules[publishModule].name) {
|
|
28
|
-
logWarn(`No name found in tspublish.json for ${publishModule}. Skipping...`);
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const publishModuleInstance = new PublishModule(this, {
|
|
32
|
-
monoRepoDir: monorepoDirArg,
|
|
33
|
-
packageSubFolder: publishModule,
|
|
34
|
-
modulePlan: plan.modules.find((module) => module.folder === publishModule),
|
|
35
|
-
});
|
|
36
|
-
const moduleCount = Object.keys(publishModules).indexOf(publishModule) + 1;
|
|
37
|
-
const totalCount = Object.keys(publishModules).length;
|
|
38
|
-
logProgress(moduleCount, totalCount, publishModules[publishModule].name || publishModule);
|
|
39
|
-
await publishModuleInstance.init();
|
|
40
|
-
await publishModuleInstance.createPublishModuleDir();
|
|
41
|
-
await publishModuleInstance.build();
|
|
42
|
-
await publishModuleInstance.publish();
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
7
|
/** Read-only package discovery, dependency ordering and manifest validation. */
|
|
46
8
|
async plan(directory) {
|
|
47
9
|
return createPackagePlan(directory, await this.getModuleSubDirs(directory));
|
|
@@ -53,7 +15,7 @@ export class TsPublish {
|
|
|
53
15
|
}
|
|
54
16
|
/**
|
|
55
17
|
* Discovers every `ts*` descriptor, named or order-only, in dependency order. Build tools and
|
|
56
|
-
* release coordinators call it as a library, so it stays silent
|
|
18
|
+
* release coordinators call it as a library, so it stays silent.
|
|
57
19
|
*/
|
|
58
20
|
async getModuleSubDirs(dirArg) {
|
|
59
21
|
// List all directories
|
|
@@ -76,4 +38,4 @@ export class TsPublish {
|
|
|
76
38
|
return orderPublishModules(publishModules);
|
|
77
39
|
}
|
|
78
40
|
}
|
|
79
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
41
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy50c3B1Ymxpc2guanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9jbGFzc2VzLnRzcHVibGlzaC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLHVCQUF1QixDQUFDO0FBRXBELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBQ3BGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUUvRCxtR0FBbUc7QUFDbkcsTUFBTSxPQUFPLFNBQVM7SUFDcEIsZ0ZBQWdGO0lBQ3pFLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBaUI7UUFDakMsT0FBTyxpQkFBaUIsQ0FBQyxTQUFTLEVBQUUsTUFBTSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQztJQUM5RSxDQUFDO0lBRUQseUZBQXlGO0lBQ2xGLEtBQUssQ0FBQyxPQUFPLENBQUMsU0FBaUIsRUFBRSxlQUF1QjtRQUM3RCxNQUFNLElBQUksR0FBRyxNQUFNLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDeEMsT0FBTyxJQUFJLGVBQWUsQ0FBQyxTQUFTLENBQUMsQ0FBQyxPQUFPLENBQUMsSUFBSSxFQUFFLGVBQWUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7O09BR0c7SUFDSSxLQUFLLENBQUMsZ0JBQWdCLENBQUMsTUFBYztRQUMxQyx1QkFBdUI7UUFDdkIsTUFBTSxXQUFXLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNuRSxNQUFNLGNBQWMsR0FBaUQsRUFBRSxDQUFDO1FBRXhFLEtBQUssTUFBTSxLQUFLLElBQUksV0FBVyxFQUFFLENBQUM7WUFDaEMsTUFBTSxVQUFVLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQztZQUM5QixJQUFJLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO2dCQUNqQyxTQUFTO1lBQ1gsQ0FBQztZQUVELHNEQUFzRDtZQUN0RCxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUM7WUFDekQsTUFBTSxpQkFBaUIsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsZ0JBQWdCLENBQUMsQ0FBQztZQUUxRSxJQUFJLENBQUMsQ0FBQyxNQUFNLE9BQU8sQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxDQUFDO2dCQUM5RCxTQUFTO1lBQ1gsQ0FBQztZQUVELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUMvRixjQUFjLENBQUMsVUFBVSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxnQkFBMEIsQ0FBQyxDQUFDO1FBQ3RFLENBQUM7UUFFRCxPQUFPLG1CQUFtQixDQUFDLGNBQWMsQ0FBQyxDQUFDO0lBQzdDLENBQUM7Q0FDRiJ9
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export * from './classes.tspublish.js';
|
|
2
2
|
export type * from './interfaces/index.js';
|
|
3
|
-
|
|
3
|
+
/** Stdout carries only the JSON result, so a release coordinator can parse it. */
|
|
4
|
+
export declare const runCli: (args?: string[]) => Promise<void>;
|
package/dist_ts/index.js
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
import * as paths from './paths.js';
|
|
2
2
|
import { TsPublish } from './classes.tspublish.js';
|
|
3
|
-
import { logStart } from './logging.js';
|
|
4
3
|
export * from './classes.tspublish.js';
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const usage = `Usage: tspublish plan
|
|
5
|
+
tspublish prepare <new-output-directory>
|
|
6
|
+
|
|
7
|
+
tspublish plans and prepares packages; it does not publish them.
|
|
8
|
+
Publish tspublish modules with \`gitzone release\` (@git.zone/cli 7.0 or later).`;
|
|
9
|
+
/** Stdout carries only the JSON result, so a release coordinator can parse it. */
|
|
10
|
+
export const runCli = async (args = process.argv.slice(2)) => {
|
|
7
11
|
const tspublish = new TsPublish();
|
|
8
|
-
const args = process.argv.slice(2);
|
|
9
12
|
if (args[0] === 'plan' && args.length === 1) {
|
|
10
13
|
console.log(JSON.stringify(await tspublish.plan(paths.cwd), null, 2));
|
|
11
14
|
}
|
|
12
15
|
else if (args[0] === 'prepare' && args.length === 2) {
|
|
13
16
|
console.log(JSON.stringify(await tspublish.prepare(paths.cwd, args[1]), null, 2));
|
|
14
17
|
}
|
|
15
|
-
else if (args.length === 0) {
|
|
16
|
-
await tspublish.publish(paths.cwd);
|
|
17
|
-
}
|
|
18
18
|
else {
|
|
19
|
-
|
|
19
|
+
console.error(usage);
|
|
20
|
+
process.exitCode = 1;
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
23
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssS0FBSyxNQUFNLFlBQVksQ0FBQztBQUNwQyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFFbkQsY0FBYyx3QkFBd0IsQ0FBQztBQUd2QyxNQUFNLEtBQUssR0FBRzs7OztpRkFJbUUsQ0FBQztBQUVsRixrRkFBa0Y7QUFDbEYsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLEtBQUssRUFBRSxPQUFpQixPQUFPLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBaUIsRUFBRTtJQUNwRixNQUFNLFNBQVMsR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO0lBQ2xDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3hFLENBQUM7U0FBTSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUN0RCxPQUFPLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxTQUFTLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDcEYsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JCLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7QUFDSCxDQUFDLENBQUMifQ==
|
package/dist_ts/paths.d.ts
CHANGED
package/dist_ts/paths.js
CHANGED
|
@@ -1,5 +1,2 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
1
|
export const cwd = process.cwd();
|
|
3
|
-
|
|
4
|
-
export const nogitDir = plugins.path.join(packageDir, '.nogit');
|
|
5
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDO0FBRWpDLE1BQU0sQ0FBQyxNQUFNLFVBQVUsR0FBRyxPQUFPLENBQUMsSUFBSSxDQUFDLElBQUksQ0FDekMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsd0JBQXdCLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsRUFDL0QsSUFBSSxDQUNMLENBQUM7QUFDRixNQUFNLENBQUMsTUFBTSxRQUFRLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDIn0=
|
|
2
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGF0aHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9wYXRocy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLENBQUMsTUFBTSxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsRUFBRSxDQUFDIn0=
|
package/dist_ts/plugins.d.ts
CHANGED
|
@@ -3,16 +3,6 @@ import * as fs from 'node:fs/promises';
|
|
|
3
3
|
import { isBuiltin } from 'node:module';
|
|
4
4
|
import * as typescript from 'typescript';
|
|
5
5
|
export { path, fs, isBuiltin, typescript };
|
|
6
|
-
import * as consolecolor from '@push.rocks/consolecolor';
|
|
7
|
-
import * as smartconfig from '@push.rocks/smartconfig';
|
|
8
|
-
import * as smartfile from '@push.rocks/smartfile';
|
|
9
6
|
import { SmartFs } from '@push.rocks/smartfs';
|
|
10
|
-
import * as smartcli from '@push.rocks/smartcli';
|
|
11
|
-
import * as smartdelay from '@push.rocks/smartdelay';
|
|
12
|
-
import * as smartlog from '@push.rocks/smartlog';
|
|
13
|
-
import * as smartnpm from '@push.rocks/smartnpm';
|
|
14
|
-
import * as smartpath from '@push.rocks/smartpath';
|
|
15
|
-
import * as smartrequest from '@push.rocks/smartrequest';
|
|
16
|
-
import * as smartshell from '@push.rocks/smartshell';
|
|
17
7
|
declare const smartfs: SmartFs;
|
|
18
|
-
export {
|
|
8
|
+
export { smartfs };
|
package/dist_ts/plugins.js
CHANGED
|
@@ -5,18 +5,8 @@ import { isBuiltin } from 'node:module';
|
|
|
5
5
|
import * as typescript from 'typescript';
|
|
6
6
|
export { path, fs, isBuiltin, typescript };
|
|
7
7
|
// @push.rocks scope
|
|
8
|
-
import * as consolecolor from '@push.rocks/consolecolor';
|
|
9
|
-
import * as smartconfig from '@push.rocks/smartconfig';
|
|
10
|
-
import * as smartfile from '@push.rocks/smartfile';
|
|
11
8
|
import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
|
|
12
|
-
import * as smartcli from '@push.rocks/smartcli';
|
|
13
|
-
import * as smartdelay from '@push.rocks/smartdelay';
|
|
14
|
-
import * as smartlog from '@push.rocks/smartlog';
|
|
15
|
-
import * as smartnpm from '@push.rocks/smartnpm';
|
|
16
|
-
import * as smartpath from '@push.rocks/smartpath';
|
|
17
|
-
import * as smartrequest from '@push.rocks/smartrequest';
|
|
18
|
-
import * as smartshell from '@push.rocks/smartshell';
|
|
19
9
|
// Create a pre-configured SmartFs instance for Node.js filesystem operations
|
|
20
10
|
const smartfs = new SmartFs(new SmartFsProviderNode());
|
|
21
|
-
export {
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
11
|
+
export { smartfs };
|
|
12
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGx1Z2lucy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3BsdWdpbnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsb0JBQW9CO0FBQ3BCLE9BQU8sS0FBSyxJQUFJLE1BQU0sV0FBVyxDQUFDO0FBQ2xDLE9BQU8sS0FBSyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDdkMsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN4QyxPQUFPLEtBQUssVUFBVSxNQUFNLFlBQVksQ0FBQztBQUN6QyxPQUFPLEVBQUUsSUFBSSxFQUFFLEVBQUUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLENBQUM7QUFFM0Msb0JBQW9CO0FBQ3BCLE9BQU8sRUFBRSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUVuRSw2RUFBNkU7QUFDN0UsTUFBTSxPQUFPLEdBQUcsSUFBSSxPQUFPLENBQUMsSUFBSSxtQkFBbUIsRUFBRSxDQUFDLENBQUM7QUFFdkQsT0FBTyxFQUFFLE9BQU8sRUFBRSxDQUFDIn0=
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@git.zone/tspublish",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "A tool to
|
|
5
|
+
"description": "A tool to plan and prepare multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
7
7
|
"typings": "dist_ts/index.d.ts",
|
|
8
8
|
"type": "module",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"@git.zone/tsbuild": "^4.5.1",
|
|
16
16
|
"@git.zone/tsbundle": "^2.14.0",
|
|
17
17
|
"@git.zone/tsrun": "^2.0.6",
|
|
18
|
-
"@git.zone/tstest": "^6.1.
|
|
19
|
-
"@types/node": "^26.
|
|
18
|
+
"@git.zone/tstest": "^6.1.5",
|
|
19
|
+
"@types/node": "^26.6.1"
|
|
20
20
|
},
|
|
21
21
|
"repository": {
|
|
22
22
|
"type": "git",
|
|
@@ -43,17 +43,7 @@
|
|
|
43
43
|
"readme.md"
|
|
44
44
|
],
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@push.rocks/consolecolor": "^2.0.4",
|
|
47
|
-
"@push.rocks/smartcli": "^4.3.1",
|
|
48
|
-
"@push.rocks/smartconfig": "^6.2.4",
|
|
49
|
-
"@push.rocks/smartdelay": "^3.1.0",
|
|
50
|
-
"@push.rocks/smartfile": "^13.1.3",
|
|
51
46
|
"@push.rocks/smartfs": "^1.5.1",
|
|
52
|
-
"@push.rocks/smartlog": "^3.2.1 || ^4.0.0",
|
|
53
|
-
"@push.rocks/smartnpm": "^2.1.1",
|
|
54
|
-
"@push.rocks/smartpath": "^6.0.0",
|
|
55
|
-
"@push.rocks/smartrequest": "^5.0.3",
|
|
56
|
-
"@push.rocks/smartshell": "^3.3.8",
|
|
57
47
|
"typescript": "^6.0.3"
|
|
58
48
|
},
|
|
59
49
|
"keywords": [
|
package/readme.md
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# @git.zone/tspublish
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Plan and prepare independently installable TypeScript packages from one repository.
|
|
4
4
|
Each component has its own dependency list and package metadata; components share
|
|
5
|
-
the repository version. TsBuild owns compilation.
|
|
6
|
-
all packages before packing,
|
|
5
|
+
the repository version. TsBuild owns compilation. tspublish does not publish:
|
|
6
|
+
`gitzone release` prepares all packages through tspublish before packing,
|
|
7
|
+
journaling and publishing any of them.
|
|
7
8
|
|
|
8
9
|
## Issue Reporting and Security
|
|
9
10
|
|
|
@@ -80,7 +81,7 @@ Supported fields:
|
|
|
80
81
|
| `include` | Exact repository-relative asset files or directories, including applicable notices. No globs or component source/compiled folders; use `folders` to declare source ownership. |
|
|
81
82
|
| `externalRuntimeAssets` | Exact repository-relative files or directories executed by another runtime, such as Deno source. Copied without npm import validation; the package owner must qualify that runtime and its dependency graph. The same filesystem and folder-ownership restrictions as `include` apply. Asset declarations cannot overlap. |
|
|
82
83
|
| `bin` | Executable names using the module's exported `runCli()` entrypoint. Wrappers are generated locally. |
|
|
83
|
-
| `registries` | Destination intent
|
|
84
|
+
| `registries` | Destination intent, returned in the plan for the release coordinator to validate. `gitzone release` requires `["useBase"]`. |
|
|
84
85
|
|
|
85
86
|
Root author, license, repository, homepage, bugs, keywords and funding metadata are
|
|
86
87
|
preserved. The private repository flag, root scripts, unrelated dependencies and
|
|
@@ -183,7 +184,6 @@ repository and decide from `modules.length` whether it has packages to release.
|
|
|
183
184
|
|
|
184
185
|
Discovery is silent: `getModuleSubDirs()`, `plan()` and `prepare()` write nothing to
|
|
185
186
|
the console, because build tools and release coordinators call them as a library.
|
|
186
|
-
Only the standalone publisher reports progress.
|
|
187
187
|
|
|
188
188
|
`prepare()` plans again and materializes the already-built packages. The output
|
|
189
189
|
directory must not exist; its parent must already exist at a canonical path. Output
|
|
@@ -194,35 +194,31 @@ prepared directories and their cleanup.
|
|
|
194
194
|
Neither method installs dependencies, fetches templates, contacts registries,
|
|
195
195
|
publishes packages or terminates the process.
|
|
196
196
|
|
|
197
|
-
The CLI exposes the same operations:
|
|
197
|
+
The CLI exposes the same operations and writes only their JSON result to stdout:
|
|
198
198
|
|
|
199
199
|
```sh
|
|
200
200
|
pnpm exec tspublish plan
|
|
201
201
|
pnpm exec tspublish prepare /absolute/existing-parent/new-package-directory
|
|
202
202
|
```
|
|
203
203
|
|
|
204
|
+
Any other invocation, including a bare `tspublish`, prints usage to stderr and
|
|
205
|
+
exits with status 1.
|
|
206
|
+
|
|
204
207
|
A release coordinator should validate every module's destination intent, prepare
|
|
205
208
|
all modules, pack every package, record the complete immutable artifact set, and
|
|
206
209
|
then publish in the returned dependency order. Publication recovery must reuse
|
|
207
210
|
those retained tarballs rather than rebuilding or preparing again.
|
|
208
211
|
|
|
209
|
-
##
|
|
210
|
-
|
|
211
|
-
The existing `TsPublish.publish(repository)` API and no-argument CLI remain
|
|
212
|
-
available. They build and publish modules sequentially and do not provide
|
|
213
|
-
transaction recovery. Use the owning repository's approved release workflow.
|
|
214
|
-
A repository without a named package still fails with "No named tspublish modules
|
|
215
|
-
were found."
|
|
212
|
+
## Publishing
|
|
216
213
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
An empty registry list means build without publishing.
|
|
214
|
+
Publish tspublish modules with `gitzone release` from `@git.zone/cli` 7.0 or later.
|
|
215
|
+
It publishes every named module inside its journaled release, in plan order and
|
|
216
|
+
before the root package, to the registries in `release.targets.npm`; see
|
|
217
|
+
"Publishing independently installable components" in the `@git.zone/cli` readme.
|
|
222
218
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
219
|
+
Version 2.0.0 removed the standalone publisher, `TsPublish.publish()` and the bare
|
|
220
|
+
`tspublish` command. Remove package scripts that ran it; `gitzone release` refuses
|
|
221
|
+
to release beside one.
|
|
226
222
|
|
|
227
223
|
## Development
|
|
228
224
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@git.zone/tspublish',
|
|
6
|
-
version: '
|
|
7
|
-
description: 'A tool to
|
|
6
|
+
version: '2.0.0',
|
|
7
|
+
description: 'A tool to plan and prepare multiple, concise, and small packages from monorepos, specifically for TypeScript projects within a git environment.'
|
|
8
8
|
}
|
package/ts/classes.tspublish.ts
CHANGED
|
@@ -1,52 +1,11 @@
|
|
|
1
|
-
import { logInfo, logWarn, logHeader, logPackage, logProgress, logSeparator } from './logging.js';
|
|
2
1
|
import * as plugins from './plugins.js';
|
|
3
2
|
import * as interfaces from './interfaces/index.js';
|
|
4
3
|
|
|
5
|
-
import { PublishModule } from './classes.publishmodule.js';
|
|
6
|
-
import { GiteaAssets } from './classes.giteaassets.js';
|
|
7
4
|
import { createPackagePlan, orderPublishModules } from './functions.packageplan.js';
|
|
8
5
|
import { PackagePreparer } from './classes.packagepreparer.js';
|
|
9
6
|
|
|
7
|
+
/** Plans and prepares packages; a release coordinator such as `gitzone release` publishes them. */
|
|
10
8
|
export class TsPublish {
|
|
11
|
-
public giteaAssetsInstance: GiteaAssets;
|
|
12
|
-
|
|
13
|
-
constructor() {
|
|
14
|
-
this.giteaAssetsInstance = new GiteaAssets({
|
|
15
|
-
giteaBaseUrl: 'https://code.foss.global',
|
|
16
|
-
});
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
public async publish(monorepoDirArg: string) {
|
|
20
|
-
logHeader('TSPublish - Module Publisher');
|
|
21
|
-
const publishModules = await this.getModuleSubDirs(monorepoDirArg);
|
|
22
|
-
const plan = await createPackagePlan(monorepoDirArg, publishModules);
|
|
23
|
-
if (!plan.modules.length) throw new Error('No named tspublish modules were found.');
|
|
24
|
-
logInfo(`Found ${Object.keys(publishModules).length} publish modules`);
|
|
25
|
-
logSeparator();
|
|
26
|
-
for (const publishModule of Object.keys(publishModules)) {
|
|
27
|
-
logPackage('Module found', `${publishModule} → ${publishModules[publishModule].name}`);
|
|
28
|
-
}
|
|
29
|
-
for (const publishModule of Object.keys(publishModules)) {
|
|
30
|
-
// lets check wether there is a name
|
|
31
|
-
if (!publishModules[publishModule].name) {
|
|
32
|
-
logWarn(`No name found in tspublish.json for ${publishModule}. Skipping...`);
|
|
33
|
-
continue;
|
|
34
|
-
}
|
|
35
|
-
const publishModuleInstance = new PublishModule(this, {
|
|
36
|
-
monoRepoDir: monorepoDirArg,
|
|
37
|
-
packageSubFolder: publishModule,
|
|
38
|
-
modulePlan: plan.modules.find((module) => module.folder === publishModule),
|
|
39
|
-
});
|
|
40
|
-
const moduleCount = Object.keys(publishModules).indexOf(publishModule) + 1;
|
|
41
|
-
const totalCount = Object.keys(publishModules).length;
|
|
42
|
-
logProgress(moduleCount, totalCount, publishModules[publishModule].name || publishModule);
|
|
43
|
-
await publishModuleInstance.init();
|
|
44
|
-
await publishModuleInstance.createPublishModuleDir();
|
|
45
|
-
await publishModuleInstance.build();
|
|
46
|
-
await publishModuleInstance.publish();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
9
|
/** Read-only package discovery, dependency ordering and manifest validation. */
|
|
51
10
|
public async plan(directory: string): Promise<interfaces.ITsPublishPlan> {
|
|
52
11
|
return createPackagePlan(directory, await this.getModuleSubDirs(directory));
|
|
@@ -60,7 +19,7 @@ export class TsPublish {
|
|
|
60
19
|
|
|
61
20
|
/**
|
|
62
21
|
* Discovers every `ts*` descriptor, named or order-only, in dependency order. Build tools and
|
|
63
|
-
* release coordinators call it as a library, so it stays silent
|
|
22
|
+
* release coordinators call it as a library, so it stays silent.
|
|
64
23
|
*/
|
|
65
24
|
public async getModuleSubDirs(dirArg: string) {
|
|
66
25
|
// List all directories
|
package/ts/index.ts
CHANGED
|
@@ -1,21 +1,24 @@
|
|
|
1
1
|
import * as paths from './paths.js';
|
|
2
2
|
import { TsPublish } from './classes.tspublish.js';
|
|
3
|
-
import { logStart } from './logging.js';
|
|
4
3
|
|
|
5
4
|
export * from './classes.tspublish.js';
|
|
6
5
|
export type * from './interfaces/index.js';
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
const usage = `Usage: tspublish plan
|
|
8
|
+
tspublish prepare <new-output-directory>
|
|
9
|
+
|
|
10
|
+
tspublish plans and prepares packages; it does not publish them.
|
|
11
|
+
Publish tspublish modules with \`gitzone release\` (@git.zone/cli 7.0 or later).`;
|
|
12
|
+
|
|
13
|
+
/** Stdout carries only the JSON result, so a release coordinator can parse it. */
|
|
14
|
+
export const runCli = async (args: string[] = process.argv.slice(2)): Promise<void> => {
|
|
10
15
|
const tspublish = new TsPublish();
|
|
11
|
-
const args = process.argv.slice(2);
|
|
12
16
|
if (args[0] === 'plan' && args.length === 1) {
|
|
13
17
|
console.log(JSON.stringify(await tspublish.plan(paths.cwd), null, 2));
|
|
14
18
|
} else if (args[0] === 'prepare' && args.length === 2) {
|
|
15
19
|
console.log(JSON.stringify(await tspublish.prepare(paths.cwd, args[1]), null, 2));
|
|
16
|
-
} else if (args.length === 0) {
|
|
17
|
-
await tspublish.publish(paths.cwd);
|
|
18
20
|
} else {
|
|
19
|
-
|
|
21
|
+
console.error(usage);
|
|
22
|
+
process.exitCode = 1;
|
|
20
23
|
}
|
|
21
24
|
};
|
package/ts/paths.ts
CHANGED
|
@@ -1,9 +1 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
|
|
3
1
|
export const cwd = process.cwd();
|
|
4
|
-
|
|
5
|
-
export const packageDir = plugins.path.join(
|
|
6
|
-
plugins.smartpath.get.dirnameFromImportMetaUrl(import.meta.url),
|
|
7
|
-
'..',
|
|
8
|
-
);
|
|
9
|
-
export const nogitDir = plugins.path.join(packageDir, '.nogit');
|
package/ts/plugins.ts
CHANGED
|
@@ -6,19 +6,9 @@ import * as typescript from 'typescript';
|
|
|
6
6
|
export { path, fs, isBuiltin, typescript };
|
|
7
7
|
|
|
8
8
|
// @push.rocks scope
|
|
9
|
-
import * as consolecolor from '@push.rocks/consolecolor';
|
|
10
|
-
import * as smartconfig from '@push.rocks/smartconfig';
|
|
11
|
-
import * as smartfile from '@push.rocks/smartfile';
|
|
12
9
|
import { SmartFs, SmartFsProviderNode } from '@push.rocks/smartfs';
|
|
13
|
-
import * as smartcli from '@push.rocks/smartcli';
|
|
14
|
-
import * as smartdelay from '@push.rocks/smartdelay';
|
|
15
|
-
import * as smartlog from '@push.rocks/smartlog';
|
|
16
|
-
import * as smartnpm from '@push.rocks/smartnpm';
|
|
17
|
-
import * as smartpath from '@push.rocks/smartpath';
|
|
18
|
-
import * as smartrequest from '@push.rocks/smartrequest';
|
|
19
|
-
import * as smartshell from '@push.rocks/smartshell';
|
|
20
10
|
|
|
21
11
|
// Create a pre-configured SmartFs instance for Node.js filesystem operations
|
|
22
12
|
const smartfs = new SmartFs(new SmartFsProviderNode());
|
|
23
13
|
|
|
24
|
-
export {
|
|
14
|
+
export { smartfs };
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
interface IRepoFile {
|
|
2
|
-
name: string;
|
|
3
|
-
path: string;
|
|
4
|
-
type: 'file' | 'dir';
|
|
5
|
-
download_url: string | null;
|
|
6
|
-
base64Content: string | null;
|
|
7
|
-
encoding: string | null;
|
|
8
|
-
}
|
|
9
|
-
interface IGiteaAssetsOptions {
|
|
10
|
-
giteaBaseUrl: string;
|
|
11
|
-
token?: string;
|
|
12
|
-
}
|
|
13
|
-
export declare class GiteaAssets {
|
|
14
|
-
private baseUrl;
|
|
15
|
-
private headers;
|
|
16
|
-
constructor(options: IGiteaAssetsOptions);
|
|
17
|
-
/**
|
|
18
|
-
* Get all files in a directory of a repository
|
|
19
|
-
* @param owner - Repository owner
|
|
20
|
-
* @param repo - Repository name
|
|
21
|
-
* @param directory - Directory path ('' for root)
|
|
22
|
-
* @param branch - Branch name (optional)
|
|
23
|
-
* @returns A list of files in the directory
|
|
24
|
-
*/
|
|
25
|
-
getFiles(owner: string, repo: string, directory: string, branch?: string): Promise<IRepoFile[]>;
|
|
26
|
-
/**
|
|
27
|
-
* gets the current cli entry file from the code.foss.global/git.zone/cli repository
|
|
28
|
-
* @returns
|
|
29
|
-
*/
|
|
30
|
-
getBinCliEntryFile(): Promise<IRepoFile>;
|
|
31
|
-
}
|
|
32
|
-
export {};
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
import * as plugins from './plugins.js';
|
|
2
|
-
export class GiteaAssets {
|
|
3
|
-
constructor(options) {
|
|
4
|
-
this.headers = {};
|
|
5
|
-
this.baseUrl = options.giteaBaseUrl;
|
|
6
|
-
if (this.baseUrl.endsWith('/')) {
|
|
7
|
-
this.baseUrl = this.baseUrl.slice(0, -1);
|
|
8
|
-
}
|
|
9
|
-
this.baseUrl += '/api/v1';
|
|
10
|
-
this.headers = options.token
|
|
11
|
-
? { ...this.headers, 'Authorization': `token ${options.token}` }
|
|
12
|
-
: this.headers;
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* Get all files in a directory of a repository
|
|
16
|
-
* @param owner - Repository owner
|
|
17
|
-
* @param repo - Repository name
|
|
18
|
-
* @param directory - Directory path ('' for root)
|
|
19
|
-
* @param branch - Branch name (optional)
|
|
20
|
-
* @returns A list of files in the directory
|
|
21
|
-
*/
|
|
22
|
-
async getFiles(owner, repo, directory, branch) {
|
|
23
|
-
try {
|
|
24
|
-
const requestBuilder = plugins.smartrequest.SmartRequest.create()
|
|
25
|
-
.url(this.baseUrl + `/repos/${owner}/${repo}/contents/${directory}`)
|
|
26
|
-
.headers(this.headers);
|
|
27
|
-
if (branch) {
|
|
28
|
-
requestBuilder.query({ ref: branch });
|
|
29
|
-
}
|
|
30
|
-
const response = await requestBuilder.get();
|
|
31
|
-
let responseBody = await response.json();
|
|
32
|
-
if (!Array.isArray(responseBody) && typeof responseBody === 'object') {
|
|
33
|
-
responseBody = [responseBody];
|
|
34
|
-
}
|
|
35
|
-
else if (Array.isArray(responseBody)) {
|
|
36
|
-
for (const entry of responseBody) {
|
|
37
|
-
if (entry.type === 'dir') {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
else if (entry.type === 'file') {
|
|
41
|
-
const requestBuilder2 = plugins.smartrequest.SmartRequest.create()
|
|
42
|
-
.url(this.baseUrl + `/repos/${owner}/${repo}/contents/${entry.path}`)
|
|
43
|
-
.headers(this.headers);
|
|
44
|
-
if (branch) {
|
|
45
|
-
requestBuilder2.query({ ref: branch });
|
|
46
|
-
}
|
|
47
|
-
const response2 = await requestBuilder2.get();
|
|
48
|
-
const response2Body = await response2.json();
|
|
49
|
-
entry.encoding = response2Body.encoding;
|
|
50
|
-
entry.content = response2Body.content;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
// lets map to the IRepoFile interface
|
|
55
|
-
responseBody = responseBody.map((entry) => {
|
|
56
|
-
return {
|
|
57
|
-
name: entry.name,
|
|
58
|
-
path: entry.path,
|
|
59
|
-
type: entry.type,
|
|
60
|
-
download_url: entry.download_url,
|
|
61
|
-
base64Content: entry.content,
|
|
62
|
-
encoding: entry.encoding,
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
return responseBody;
|
|
66
|
-
}
|
|
67
|
-
catch (error) {
|
|
68
|
-
console.error('Error fetching repository files:', error);
|
|
69
|
-
throw error;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
/**
|
|
73
|
-
* gets the current cli entry file from the code.foss.global/git.zone/cli repository
|
|
74
|
-
* @returns
|
|
75
|
-
*/
|
|
76
|
-
async getBinCliEntryFile() {
|
|
77
|
-
const files = await this.getFiles('git.zone', 'cli', 'assets/templates/cli/cli.js');
|
|
78
|
-
return files[0];
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xhc3Nlcy5naXRlYWFzc2V0cy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL2NsYXNzZXMuZ2l0ZWFhc3NldHMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFnQnhDLE1BQU0sT0FBTyxXQUFXO0lBSXRCLFlBQVksT0FBNEI7UUFGaEMsWUFBTyxHQUE0QixFQUFFLENBQUM7UUFHNUMsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsWUFBWSxDQUFBO1FBQ25DLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNDLENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxJQUFJLFNBQVMsQ0FBQztRQUMxQixJQUFJLENBQUMsT0FBTyxHQUFHLE9BQU8sQ0FBQyxLQUFLO1lBQ3hCLENBQUMsQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFBRSxlQUFlLEVBQUUsU0FBUyxPQUFPLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDaEUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsUUFBUSxDQUNaLEtBQWEsRUFDYixJQUFZLEVBQ1osU0FBaUIsRUFDakIsTUFBZTtRQUVmLElBQUksQ0FBQztZQUNILE1BQU0sY0FBYyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRTtpQkFDOUQsR0FBRyxDQUFDLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxLQUFLLElBQUksSUFBSSxhQUFhLFNBQVMsRUFBRSxDQUFDO2lCQUNuRSxPQUFPLENBQUMsSUFBSSxDQUFDLE9B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
|