@danxbot/plugin-sdk 0.1.5 → 0.2.1

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.
@@ -4,7 +4,8 @@ declare module "@danxbot/card-kit@1" {
4
4
  import { ReactNode } from 'react';
5
5
  export { Link, useNavigate } from 'react-router';
6
6
 
7
- type IssueType = "Epic" | "Bug" | "Feature" | "Story" | "Chore" | "Task";
7
+ type CardTypeKey = string;
8
+
8
9
  type IssueStatus$1 = "Review" | "ToDo" | "In Progress" | "Backlog" | "Done" | "Cancelled";
9
10
  type EffortLevelName = "min" | "very_low" | "low" | "medium" | "high" | "very_high" | "max";
10
11
  type IssueProblemType = "question" | "action";
@@ -17,7 +18,7 @@ declare module "@danxbot/card-kit@1" {
17
18
  repo_name: string;
18
19
  board_id: string;
19
20
  schema_version: number;
20
- type: IssueType;
21
+ type: CardTypeKey;
21
22
  title: string;
22
23
  description: string;
23
24
  summary: string | null;
@@ -389,7 +390,7 @@ declare module "@danxbot/card-kit@1" {
389
390
  interface V2CopyIssue {
390
391
  id: string;
391
392
  parent_id: string | null;
392
- type: IssueType;
393
+ type: CardTypeKey;
393
394
  title: string;
394
395
  description: string;
395
396
  summary: string | null;
@@ -575,7 +576,7 @@ declare module "@danxbot/card-kit@1" {
575
576
  title: string;
576
577
  description?: undefined | string;
577
578
  status: "Cancelled" | "Review" | "ToDo" | "In Progress" | "Backlog" | "Done";
578
- type: "Epic" | "Bug" | "Feature" | "Story" | "Chore" | "Task";
579
+ type: string;
579
580
  priority: number;
580
581
  id: string;
581
582
  parent_id: null | string;
@@ -606,7 +607,7 @@ declare module "@danxbot/card-kit@1" {
606
607
  list_emoji?: undefined | null | string;
607
608
  refs?: undefined | Array<CardRefViewV2>;
608
609
  parent_title?: undefined | null | string;
609
- parent_type?: undefined | null | "Epic" | "Bug" | "Feature" | "Story" | "Chore" | "Task";
610
+ parent_type?: undefined | null | string;
610
611
  parent_created_at?: undefined | null | number;
611
612
  parent_updated_at?: undefined | null | number;
612
613
  parent_blocked?: undefined | null | false | true;
@@ -718,7 +719,7 @@ declare module "@danxbot/card-kit@1" {
718
719
  id: string;
719
720
  name: string;
720
721
  status: "Cancelled" | "Review" | "ToDo" | "In Progress" | "Backlog" | "Done";
721
- type?: undefined | "Epic" | "Bug" | "Feature" | "Story" | "Chore" | "Task";
722
+ type?: undefined | string;
722
723
  priority?: undefined | number;
723
724
  summary?: undefined | null | string;
724
725
  waiting_on: boolean;
@@ -808,6 +809,7 @@ declare module "@danxbot/card-kit@1" {
808
809
  content_hash: string;
809
810
  created_at: string;
810
811
  updated_at: string;
812
+ feedback_consent: boolean;
811
813
  open: boolean;
812
814
  solutions: Array<{
813
815
  id: number;
@@ -1170,7 +1172,7 @@ declare module "@danxbot/card-kit@1" {
1170
1172
  interface CardFaceModel {
1171
1173
  id: string;
1172
1174
  title: string;
1173
- type: IssueType;
1175
+ type: CardTypeKey;
1174
1176
  priority: number;
1175
1177
  statusName: IssueStatus$1;
1176
1178
  status: CardStatusPresentation;
package/dist/cli.js CHANGED
@@ -5932,7 +5932,7 @@ ${output.trim()}`));
5932
5932
  }
5933
5933
  function isManifest(value) {
5934
5934
  const manifest = value;
5935
- return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5935
+ return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.exports) && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5936
5936
  }
5937
5937
  async function readBuiltPlugin(projectDir) {
5938
5938
  const distDir = join3(resolve2(projectDir), PLUGIN_DIST_DIR);
@@ -5942,7 +5942,7 @@ async function readBuiltPlugin(projectDir) {
5942
5942
  } catch (err) {
5943
5943
  throw new Error(`danx-plugin: the build left no readable ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} (is the danxPlugin() preset in vite.config?): ${err.message}`);
5944
5944
  }
5945
- if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry or no files list of paths`);
5945
+ if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry, no exports list or no files list of paths`);
5946
5946
  const files = await Promise.all(manifest.files.map(async (file) => ({ path: file.path, bytes: await readFile2(join3(distDir, file.path)) })));
5947
5947
  return { manifest, files };
5948
5948
  }
package/dist/publish.d.ts CHANGED
@@ -16,6 +16,8 @@ interface PluginManifestFile {
16
16
  /** Lowercase hex. */
17
17
  readonly sha256: string;
18
18
  }
19
+ declare const PLUGIN_VIEW_EXPORTS: readonly ["CardView", "CardListView"];
20
+ type PluginViewExport = (typeof PLUGIN_VIEW_EXPORTS)[number];
19
21
  interface PluginManifest {
20
22
  /** The ES module the app `import()`s, a `path` in `files`. */
21
23
  readonly entry: string;
@@ -25,6 +27,8 @@ interface PluginManifest {
25
27
  readonly screenshot?: string;
26
28
  /** Each shared library's major the plugin was built against (`PLUGIN_RUNTIME_LIBRARIES`), compared with what the app serves. */
27
29
  readonly runtime: Readonly<Record<string, number>>;
30
+ /** DX-5282: which view modules the entry exports (`PLUGIN_VIEW_EXPORTS`), recorded at build from the entry chunk's real exports; never empty. */
31
+ readonly exports: readonly PluginViewExport[];
28
32
  readonly files: readonly PluginManifestFile[];
29
33
  }
30
34
 
package/dist/publish.js CHANGED
@@ -5927,7 +5927,7 @@ ${output.trim()}`));
5927
5927
  }
5928
5928
  function isManifest(value) {
5929
5929
  const manifest = value;
5930
- return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5930
+ return typeof manifest === "object" && manifest !== null && typeof manifest.entry === "string" && Array.isArray(manifest.exports) && Array.isArray(manifest.files) && manifest.files.every((file) => typeof file?.path === "string");
5931
5931
  }
5932
5932
  async function readBuiltPlugin(projectDir) {
5933
5933
  const distDir = join3(resolve2(projectDir), PLUGIN_DIST_DIR);
@@ -5937,7 +5937,7 @@ async function readBuiltPlugin(projectDir) {
5937
5937
  } catch (err) {
5938
5938
  throw new Error(`danx-plugin: the build left no readable ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} (is the danxPlugin() preset in vite.config?): ${err.message}`);
5939
5939
  }
5940
- if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry or no files list of paths`);
5940
+ if (!isManifest(manifest)) throw new Error(`danx-plugin: ${PLUGIN_DIST_DIR}/${PLUGIN_MANIFEST_FILE} in ${projectDir} has no entry, no exports list or no files list of paths`);
5941
5941
  const files = await Promise.all(manifest.files.map(async (file) => ({ path: file.path, bytes: await readFile2(join3(distDir, file.path)) })));
5942
5942
  return { manifest, files };
5943
5943
  }
package/dist/vite.d.ts CHANGED
@@ -14,7 +14,7 @@ interface DanxPluginOptions {
14
14
  * - Anything else is bundled. Bundling a copy of a shared package (`react-dom/client` or `react-router` are not in the contract) would run a second copy
15
15
  * beside the app's, so that fails the build instead of shipping.
16
16
  * - Code-split chunks load by relative import from the entry's folder; CSS is emitted as one `index.css`.
17
- * - `danx-plugin.json` is written beside the output: every file's size and sha256, the entry, the stylesheets and the runtime majors.
17
+ * - `danx-plugin.json` is written beside the output: every file's size and sha256, the entry, the view modules it exports, the stylesheets and the runtime majors.
18
18
  */
19
19
  declare function danxPlugin(options?: DanxPluginOptions): Plugin;
20
20
 
package/dist/vite.js CHANGED
@@ -33,6 +33,9 @@ import { join, relative, sep } from "node:path";
33
33
 
34
34
  // ../../src/plugins/plugin-manifest.ts
35
35
  var PLUGIN_MANIFEST_FILE = "danx-plugin.json";
36
+ var CARD_VIEW_EXPORT = "CardView";
37
+ var CARD_LIST_VIEW_EXPORT = "CardListView";
38
+ var PLUGIN_VIEW_EXPORTS = [CARD_VIEW_EXPORT, CARD_LIST_VIEW_EXPORT];
36
39
 
37
40
  // src/manifest.ts
38
41
  function filesUnder(root, dir = root) {
@@ -46,18 +49,19 @@ function describeFile(root, file) {
46
49
  sha256: createHash("sha256").update(bytes).digest("hex")
47
50
  };
48
51
  }
49
- function buildManifest(outDir, entry) {
52
+ function buildManifest(outDir, entry, exports) {
50
53
  const files = filesUnder(outDir).map((file) => describeFile(outDir, file)).filter((file) => file.path !== PLUGIN_MANIFEST_FILE);
51
54
  if (!files.some((file) => file.path === entry)) throw new Error(`danx-plugin: the build produced no entry module ${entry} in ${outDir}`);
52
55
  return {
53
56
  entry,
54
57
  styles: files.filter((file) => file.path.endsWith(".css")).map((file) => file.path),
55
58
  runtime: pluginRuntimeContract().majors,
59
+ exports: [...exports],
56
60
  files
57
61
  };
58
62
  }
59
- function writeManifest(outDir, entry) {
60
- const manifest = buildManifest(outDir, entry);
63
+ function writeManifest(outDir, entry, exports) {
64
+ const manifest = buildManifest(outDir, entry, exports);
61
65
  writeFileSync(join(outDir, PLUGIN_MANIFEST_FILE), `${JSON.stringify(manifest, null, 2)}
62
66
  `);
63
67
  return manifest;
@@ -72,6 +76,7 @@ function bundledNeverPackage(moduleId) {
72
76
  }
73
77
  function danxPlugin(options = {}) {
74
78
  const entry = options.entry ?? "src/index.tsx";
79
+ let viewExports = [];
75
80
  return {
76
81
  name: "danx-plugin",
77
82
  config() {
@@ -96,6 +101,14 @@ function danxPlugin(options = {}) {
96
101
  };
97
102
  },
98
103
  generateBundle(_options, bundle) {
104
+ const entryChunk = Object.values(bundle).find((output) => output.type === "chunk" && output.isEntry);
105
+ if (entryChunk?.type !== "chunk") throw new Error(`danx-plugin: the build produced no entry chunk for ${entry}`);
106
+ viewExports = PLUGIN_VIEW_EXPORTS.filter((name) => entryChunk.exports.includes(name));
107
+ if (viewExports.length === 0) {
108
+ throw new Error(
109
+ `danx-plugin: ${entry} must export ${PLUGIN_VIEW_EXPORTS.join(" and/or ")}, but it exports ${entryChunk.exports.length === 0 ? "nothing" : entryChunk.exports.join(", ")}.`
110
+ );
111
+ }
99
112
  for (const output of Object.values(bundle)) {
100
113
  if (output.type !== "chunk") continue;
101
114
  for (const id of output.moduleIds) {
@@ -109,7 +122,7 @@ function danxPlugin(options = {}) {
109
122
  },
110
123
  writeBundle(options2) {
111
124
  if (options2.dir === void 0) throw new Error("danx-plugin: the build has no output directory to write the manifest into");
112
- writeManifest(options2.dir, PLUGIN_ENTRY_FILE);
125
+ writeManifest(options2.dir, PLUGIN_ENTRY_FILE, viewExports);
113
126
  }
114
127
  };
115
128
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@danxbot/plugin-sdk",
3
- "version": "0.1.5",
3
+ "version": "0.2.1",
4
4
  "description": "SDK for building 50 Arms card-type plugins (DX-5170): the card kit's type declarations, a Vite preset that builds a plugin against the app's shared runtime and writes its manifest, and the danx-plugin CLI.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -46,7 +46,7 @@
46
46
  "test": "vitest run"
47
47
  },
48
48
  "devDependencies": {
49
- "@danxbot/ui": "26.12.0",
49
+ "@danxbot/ui": "26.23.0",
50
50
  "@types/node": "^22.0.0",
51
51
  "@types/react": "^19.2.2",
52
52
  "esbuild": "^0.25.0",