@aidc-toolkit/dev 0.9.19-beta → 0.9.21-beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -50,5 +50,5 @@ export default defineConfig([
50
50
  ...esLintConfigAIDCToolkit,
51
51
  // Additional rules here as required.
52
52
  // ...
53
- );
53
+ ]);
54
54
  ```
@@ -7,44 +7,76 @@
7
7
  "src/publish/",
8
8
  "config/publish.json"
9
9
  ],
10
- "lastBetaPublished": "2025-06-09T02:29:43.810Z"
10
+ "phaseStates": {
11
+ "beta": {
12
+ "dateTime": "2025-11-24T21:48:19.587Z",
13
+ "tag": "v0.9.20-beta"
14
+ }
15
+ }
11
16
  },
12
17
  "core": {
13
18
  "dependencyType": "external",
14
- "lastBetaPublished": "2025-06-09T02:31:46.793Z"
19
+ "phaseStates": {
20
+ "beta": {
21
+ "dateTime": "2025-11-24T21:52:49.177Z",
22
+ "tag": "v0.9.20-beta"
23
+ }
24
+ }
15
25
  },
16
26
  "utility": {
17
27
  "dependencyType": "external",
18
- "lastBetaPublished": "2025-06-09T12:43:30.472Z"
28
+ "phaseStates": {
29
+ "beta": {
30
+ "dateTime": "2025-11-24T21:54:54.413Z",
31
+ "tag": "v0.9.20-beta"
32
+ }
33
+ }
19
34
  },
20
35
  "gs1": {
21
36
  "dependencyType": "external",
22
- "lastBetaPublished": "2025-06-09T12:44:44.764Z"
37
+ "phaseStates": {
38
+ "beta": {
39
+ "dateTime": "2025-11-24T21:55:58.917Z",
40
+ "tag": "v0.9.20-beta"
41
+ }
42
+ }
23
43
  },
24
44
  "demo": {
25
45
  "dependencyType": "none",
26
- "lastBetaPublished": "2025-06-09T13:03:31.157Z"
46
+ "phaseStates": {
47
+ "beta": {
48
+ "dateTime": "2025-11-24T21:56:03.808Z",
49
+ "tag": "v0.9.20-beta"
50
+ }
51
+ }
27
52
  },
28
53
  "app-extension": {
29
- "dependencyType": "internal",
30
- "lastBetaPublished": "2025-06-09T13:03:49.309Z"
31
- },
32
- "app-generator": {
33
- "dependencyType": "internal",
34
- "lastBetaPublished": "2025-06-09T13:03:53.348Z"
54
+ "dependencyType": "external",
55
+ "phaseStates": {
56
+ "beta": {
57
+ "dateTime": "2025-11-24T21:56:40.696Z",
58
+ "tag": "v0.9.20-beta"
59
+ }
60
+ }
35
61
  },
36
62
  "microsoft-add-in": {
37
- "dependencyType": "none"
63
+ "dependencyType": "none",
64
+ "phaseStates": {
65
+ "beta": {
66
+ "dateTime": "2025-11-24T22:04:19.513Z",
67
+ "tag": "v0.9.20-beta"
68
+ }
69
+ }
38
70
  },
39
71
  "aidc-toolkit.github.io": {
40
72
  "directory": "doc",
41
- "additionalDependencies": [
42
- "core",
43
- "utility",
44
- "gs1"
45
- ],
46
73
  "dependencyType": "none",
47
- "lastBetaPublished": "2025-06-09T13:15:55.394Z"
74
+ "phaseStates": {
75
+ "beta": {
76
+ "dateTime": "2025-11-24T22:35:04.601Z",
77
+ "tag": "v0.9.20-beta"
78
+ }
79
+ }
48
80
  }
49
81
  }
50
- }
82
+ }
@@ -11,6 +11,10 @@
11
11
  {
12
12
  "from": ".github/workflows/release.yml",
13
13
  "to": "../gs1/.github/workflows/"
14
+ },
15
+ {
16
+ "from": ".github/workflows/release.yml",
17
+ "to": "../app-extension/.github/workflows/"
14
18
  }
15
19
  ],
16
20
 
package/dev.iml CHANGED
@@ -2,7 +2,9 @@
2
2
  <module type="WEB_MODULE" version="4">
3
3
  <component name="NewModuleRootManager" inherit-compiler-output="true">
4
4
  <exclude-output />
5
- <content url="file://$MODULE_DIR$" />
5
+ <content url="file://$MODULE_DIR$">
6
+ <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7
+ </content>
6
8
  <orderEntry type="inheritedJdk" />
7
9
  <orderEntry type="sourceFolder" forTests="false" />
8
10
  </component>
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-config-template.d.ts","sourceRoot":"","sources":["../src/eslint-config-template.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,uBAAuB,kCAmHlC,CAAC"}
1
+ {"version":3,"file":"eslint-config-template.d.ts","sourceRoot":"","sources":["../src/eslint-config-template.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,uBAAuB,kCAoHlC,CAAC"}
@@ -58,6 +58,7 @@ export const esLintConfigAIDCToolkit = defineConfig([
58
58
  after: true
59
59
  }],
60
60
  "@stylistic/indent": ["error", 4],
61
+ "@stylistic/indent-binary-ops": ["error", 4],
61
62
  "@stylistic/member-delimiter-style": ["error", {
62
63
  multiline: {
63
64
  delimiter: "semi",
@@ -1 +1 @@
1
- {"version":3,"file":"eslint-config-template.js","sourceRoot":"","sources":["../src/eslint-config-template.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"eslint-config-template.js","sourceRoot":"","sources":["../src/eslint-config-template.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aidc-toolkit/dev",
3
- "version": "0.9.19-beta",
3
+ "version": "0.9.21-beta",
4
4
  "description": "Shared development artefacts for AIDC Toolkit",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -37,7 +37,7 @@
37
37
  "@stylistic/eslint-plugin": "^5.6.1",
38
38
  "eslint": "^9.39.1",
39
39
  "eslint-config-love": "^134.0.0",
40
- "eslint-plugin-jsdoc": "^61.4.0",
40
+ "eslint-plugin-jsdoc": "^61.4.1",
41
41
  "jiti": "^2.6.1",
42
42
  "octokit": "^5.0.5",
43
43
  "rimraf": "^6.1.2",
@@ -45,7 +45,7 @@
45
45
  "tslog": "^4.10.2",
46
46
  "tsx": "^4.20.6",
47
47
  "typescript": "^5.9.3",
48
- "typescript-eslint": "^8.47.0",
48
+ "typescript-eslint": "^8.48.0",
49
49
  "yaml": "^2.8.1"
50
50
  }
51
51
  }
@@ -64,6 +64,7 @@ export const esLintConfigAIDCToolkit = defineConfig([
64
64
  after: true
65
65
  }],
66
66
  "@stylistic/indent": ["error", 4],
67
+ "@stylistic/indent-binary-ops": ["error", 4],
67
68
  "@stylistic/member-delimiter-style": ["error", {
68
69
  multiline: {
69
70
  delimiter: "semi",
@@ -0,0 +1,318 @@
1
+ import fs from "node:fs";
2
+ import sharedConfigurationJSON from "../../config/publish.json";
3
+ import localConfigurationJSON from "../../config/publish.local.json";
4
+ import { logger, type LogLevels } from "./logger";
5
+ import { omit, pick, propertyAs } from "./type-helper";
6
+
7
+ export const SHARED_CONFIGURATION_PATH = "config/publish.json";
8
+ export const LOCAL_CONFIGURATION_PATH = "config/publish.local.json";
9
+
10
+ /**
11
+ * Phase.
12
+ */
13
+ export type Phase = "alpha" | "beta" | "production";
14
+
15
+ /**
16
+ * Phase state.
17
+ */
18
+ export interface PhaseState {
19
+ /**
20
+ * Date/time the phase was last published.
21
+ */
22
+ dateTime: Date;
23
+
24
+ /**
25
+ * Tag if any.
26
+ */
27
+ tag?: string | undefined;
28
+
29
+ /**
30
+ * Current step in publication; used to resume after failure recovery.
31
+ */
32
+ step?: string | undefined;
33
+ }
34
+
35
+ /**
36
+ * Phase state in JSON file.
37
+ */
38
+ interface JSONPhaseState extends Omit<PhaseState, "dateTime"> {
39
+ /**
40
+ * Date/time the phase was last published, as a string.
41
+ */
42
+ dateTime: string;
43
+ }
44
+
45
+ /**
46
+ * Dependency type.
47
+ *
48
+ * - external
49
+ * - Installed from NPM
50
+ * - internal
51
+ * - Installed from GitHub
52
+ * - May require "prepare" script( https://docs.npmjs.com/cli/using-npm/scripts)
53
+ * - May require authentication with GitHub
54
+ * - none
55
+ * - Not a dependency of any other repository
56
+ */
57
+ export type DependencyType = "external" | "internal" | "none";
58
+
59
+ /**
60
+ * Shared repository configuration.
61
+ */
62
+ interface SharedRepository {
63
+ /**
64
+ * Directory in which repository resides, if different from repository name.
65
+ */
66
+ readonly directory?: string;
67
+
68
+ /**
69
+ * Dependency type, dictating how it is published.
70
+ */
71
+ readonly dependencyType: DependencyType;
72
+
73
+ /**
74
+ * Additional organization dependencies not included in package configuration.
75
+ */
76
+ readonly additionalDependencies?: readonly string[];
77
+
78
+ /**
79
+ * Paths to exclude when checking for changes.
80
+ */
81
+ readonly excludePaths?: readonly string[];
82
+
83
+ /**
84
+ * Beta and production phase states if any.
85
+ */
86
+ readonly phaseStates?: Readonly<Partial<Record<"beta" | "production", PhaseState>>>;
87
+ }
88
+
89
+ /**
90
+ * Shared repository configuration in JSON file.
91
+ */
92
+ interface JSONSharedRepository extends Omit<SharedRepository, "dependencyType" | "phaseStates"> {
93
+ /**
94
+ * Dependency type, dictating how it is published, as a string.
95
+ */
96
+ readonly dependencyType: string;
97
+
98
+ /**
99
+ * Beta and production phase states if any.
100
+ */
101
+ readonly phaseStates?: Readonly<Partial<Record<"beta" | "production", JSONPhaseState>>>;
102
+ }
103
+
104
+ /**
105
+ * Local repository configuration.
106
+ */
107
+ interface LocalRepository {
108
+ /**
109
+ * Platform if building across platforms, e.g., macOS hosting Windows on Parallels.
110
+ */
111
+ readonly platform?: {
112
+ /**
113
+ * CPU architecture of native modules to install.
114
+ */
115
+ readonly cpu: string;
116
+
117
+ /**
118
+ * OS of native modules to install.
119
+ */
120
+ readonly os: string;
121
+ };
122
+
123
+ /**
124
+ * Alpha phase state if any.
125
+ */
126
+ readonly phaseStates?: Readonly<Partial<Record<"alpha", PhaseState>>>;
127
+ }
128
+
129
+ /**
130
+ * Local repository configuration in JSON file.
131
+ */
132
+ interface JSONLocalRepository extends Omit<LocalRepository, "phaseStates"> {
133
+ /**
134
+ * Alpha phase state if any.
135
+ */
136
+ readonly phaseStates?: Readonly<Partial<Record<"alpha", JSONPhaseState>>>;
137
+ }
138
+
139
+ /**
140
+ * Repository.
141
+ */
142
+ export interface Repository extends SharedRepository, LocalRepository {
143
+ /**
144
+ * Phase states if any.
145
+ */
146
+ readonly phaseStates: Partial<Record<Phase, PhaseState>>;
147
+ }
148
+
149
+ /**
150
+ * Shared configuration.
151
+ */
152
+ interface SharedConfiguration {
153
+ /**
154
+ * Organization that owns the repositories.
155
+ */
156
+ readonly organization: string;
157
+
158
+ /**
159
+ * Repositories.
160
+ */
161
+ readonly repositories: Readonly<Record<string, SharedRepository>>;
162
+ }
163
+
164
+ /**
165
+ * Shared configuration in JSON file.
166
+ */
167
+ interface JSONSharedConfiguration extends Omit<SharedConfiguration, "repositories"> {
168
+ /**
169
+ * Repositories.
170
+ */
171
+ readonly repositories: Readonly<Record<string, JSONSharedRepository>>;
172
+ }
173
+
174
+ /**
175
+ * Local configuration.
176
+ */
177
+ interface LocalConfiguration {
178
+ /**
179
+ * Log level.
180
+ */
181
+ readonly logLevel?: keyof typeof LogLevels;
182
+
183
+ /**
184
+ * Registry hosting organization's alpha repositories.
185
+ */
186
+ readonly alphaRegistry: string;
187
+
188
+ /**
189
+ * Repositories.
190
+ */
191
+ readonly repositories: Readonly<Record<string, LocalRepository>>;
192
+ }
193
+
194
+ /**
195
+ * Local configuration in JSON file.
196
+ */
197
+ interface JSONLocalConfiguration extends Omit<LocalConfiguration, "logLevel" | "repositories"> {
198
+ /**
199
+ * Log level, as a string.
200
+ */
201
+ readonly logLevel?: string;
202
+
203
+ /**
204
+ * Repositories.
205
+ */
206
+ readonly repositories: Readonly<Partial<Record<string, JSONLocalRepository>>>;
207
+ }
208
+
209
+ /**
210
+ * Configuration.
211
+ */
212
+ export interface Configuration extends SharedConfiguration, LocalConfiguration {
213
+ /**
214
+ * Repositories.
215
+ */
216
+ readonly repositories: Readonly<Record<string, Repository>>;
217
+ }
218
+
219
+ const jsonSharedConfiguration: JSONSharedConfiguration = sharedConfigurationJSON;
220
+ const jsonLocalConfiguration: JSONLocalConfiguration = localConfigurationJSON;
221
+
222
+ /**
223
+ * Map JSON phase states to internal phase states.
224
+ *
225
+ * @param jsonPhaseStates
226
+ * JSON phase states.
227
+ *
228
+ * @returns
229
+ * Internal phase states.
230
+ */
231
+ function fromJSONPhaseStates(jsonPhaseStates: Readonly<Partial<Record<Phase, JSONPhaseState>>> | undefined): Readonly<Partial<Record<Phase, PhaseState>>> {
232
+ return Object.fromEntries(Object.entries(jsonPhaseStates ?? {}).map(([phase, jsonPhaseState]) => [phase, {
233
+ ...jsonPhaseState,
234
+ dateTime: new Date(jsonPhaseState.dateTime)
235
+ }]));
236
+ }
237
+
238
+ /**
239
+ * Load configuration from JSON files.
240
+ *
241
+ * @returns
242
+ * Configuration.
243
+ */
244
+ export function loadConfiguration(): Configuration {
245
+ // Merge shared and local configurations.
246
+ return {
247
+ ...jsonSharedConfiguration,
248
+ ...omit(jsonLocalConfiguration, "logLevel"),
249
+ ...propertyAs<keyof typeof LogLevels, JSONLocalConfiguration, "logLevel">(jsonLocalConfiguration, "logLevel"),
250
+ repositories: Object.fromEntries(Object.entries(jsonSharedConfiguration.repositories).map(([repositoryName, jsonSharedRepository]) => {
251
+ const jsonLocalRepository = jsonLocalConfiguration.repositories[repositoryName] ?? {};
252
+
253
+ return [repositoryName, {
254
+ ...jsonSharedRepository,
255
+ ...propertyAs<DependencyType, JSONSharedRepository, "dependencyType">(jsonSharedRepository, "dependencyType"),
256
+ ...jsonLocalRepository,
257
+ phaseStates: {
258
+ ...fromJSONPhaseStates(jsonSharedRepository.phaseStates),
259
+ ...fromJSONPhaseStates(jsonLocalRepository.phaseStates)
260
+ }
261
+ }];
262
+ }))
263
+ };
264
+ }
265
+
266
+ /**
267
+ * Map internal phase states to JSON phase states.
268
+ *
269
+ * @param phaseStates
270
+ * Internal phase states.
271
+ *
272
+ * @returns
273
+ * JSON phase states.
274
+ */
275
+ function toJSONPhaseStates(phaseStates: Readonly<Partial<Record<Phase, PhaseState>>> | undefined): Readonly<Partial<Record<Phase, JSONPhaseState>>> {
276
+ return Object.fromEntries(Object.entries(phaseStates ?? {}).map(([phase, phaseState]) => [phase, {
277
+ ...phaseState,
278
+ dateTime: phaseState.dateTime.toISOString()
279
+ }]));
280
+ }
281
+
282
+ /**
283
+ * Save the configuration.
284
+ *
285
+ * @param configuration
286
+ * Configuration.
287
+ *
288
+ * @param dryRun
289
+ * If true, outputs to logger rather than file.
290
+ */
291
+ export function saveConfiguration(configuration: Configuration, dryRun: boolean): void {
292
+ const jsonSharedConfiguration: JSONSharedConfiguration = {
293
+ ...pick(configuration, "organization"),
294
+ repositories: Object.fromEntries(Object.entries(configuration.repositories).map(([repositoryName, repository]) => [repositoryName, {
295
+ ...pick(repository, "directory", "dependencyType", "additionalDependencies", "excludePaths"),
296
+ phaseStates: toJSONPhaseStates(pick(repository.phaseStates, "beta", "production"))
297
+ }]))
298
+ };
299
+
300
+ const jsonLocalConfiguration: JSONLocalConfiguration = {
301
+ ...pick(configuration, "logLevel", "alphaRegistry"),
302
+ repositories: Object.fromEntries(Object.entries(configuration.repositories).map(([repositoryName, repository]) => [repositoryName, {
303
+ ...pick(repository, "platform"),
304
+ phaseStates: toJSONPhaseStates(pick(repository.phaseStates, "alpha"))
305
+ }]))
306
+ };
307
+
308
+ const saveSharedConfigurationJSON = `${JSON.stringify(jsonSharedConfiguration, null, 2)}\n`;
309
+ const saveLocalConfigurationJSON = `${JSON.stringify(jsonLocalConfiguration, null, 2)}\n`;
310
+
311
+ if (dryRun) {
312
+ logger.info(`Dry run: Saving shared configuration\n${saveSharedConfigurationJSON}\n`);
313
+ logger.info(`Dry run: Saving local configuration\n${saveLocalConfigurationJSON}\n`);
314
+ } else {
315
+ fs.writeFileSync(SHARED_CONFIGURATION_PATH, saveSharedConfigurationJSON);
316
+ fs.writeFileSync(LOCAL_CONFIGURATION_PATH, saveLocalConfigurationJSON);
317
+ }
318
+ }
@@ -1,17 +1,28 @@
1
1
  import { Logger } from "tslog";
2
2
 
3
+ /**
4
+ * Log levels.
5
+ */
6
+ export const LogLevels = {
7
+ Silly: 0,
8
+ Trace: 1,
9
+ Debug: 2,
10
+ Info: 3,
11
+ Warn: 4,
12
+ Error: 5,
13
+ Fatal: 6
14
+ } as const;
15
+
3
16
  /**
4
17
  * Log level.
5
18
  */
6
- enum LogLevel {
7
- Silly, Trace, Debug, Info, Warn, Error, Fatal
8
- }
19
+ export type LogLevel = typeof LogLevels[keyof typeof LogLevels];
9
20
 
10
21
  /**
11
22
  * Logger with a default minimum level of Info.
12
23
  */
13
24
  export const logger = new Logger({
14
- minLevel: LogLevel.Info
25
+ minLevel: LogLevels.Info
15
26
  });
16
27
 
17
28
  /**
@@ -20,11 +31,11 @@ export const logger = new Logger({
20
31
  * @param logLevel
21
32
  * Log level as enumeration value or string.
22
33
  */
23
- export function setLogLevel(logLevel: LogLevel | string): void {
34
+ export function setLogLevel(logLevel: string | number): void {
24
35
  if (typeof logLevel === "string") {
25
- if (logLevel in LogLevel) {
36
+ if (logLevel in LogLevels) {
26
37
  // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion -- String exists as a key.
27
- logger.settings.minLevel = LogLevel[logLevel as keyof typeof LogLevel];
38
+ logger.settings.minLevel = LogLevels[logLevel as keyof typeof LogLevels];
28
39
  } else {
29
40
  logger.error(`Unknown log level ${logLevel}`);
30
41
  }