@stripe/extensibility-dev-tools 0.23.5

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.
Files changed (253) hide show
  1. package/LICENSE.md +19 -0
  2. package/dist/bin/build-custom-object-definitions.cjs +2111 -0
  3. package/dist/bin/build-custom-object-definitions.d.ts +11 -0
  4. package/dist/bin/build-custom-object-definitions.d.ts.map +1 -0
  5. package/dist/bin/build-custom-object-definitions.js +2088 -0
  6. package/dist/bin/create-upload-image.cjs +2136 -0
  7. package/dist/bin/create-upload-image.d.ts +17 -0
  8. package/dist/bin/create-upload-image.d.ts.map +1 -0
  9. package/dist/bin/create-upload-image.js +2113 -0
  10. package/dist/bin/dev-tools-rpc.cjs +3874 -0
  11. package/dist/bin/dev-tools-rpc.d.ts +3 -0
  12. package/dist/bin/dev-tools-rpc.d.ts.map +1 -0
  13. package/dist/bin/dev-tools-rpc.js +3864 -0
  14. package/dist/bin/gen-schemas.cjs +20739 -0
  15. package/dist/bin/gen-schemas.d.ts +8 -0
  16. package/dist/bin/gen-schemas.d.ts.map +1 -0
  17. package/dist/bin/gen-schemas.js +20715 -0
  18. package/dist/bin/gen-workspace.cjs +3847 -0
  19. package/dist/bin/gen-workspace.d.ts +8 -0
  20. package/dist/bin/gen-workspace.d.ts.map +1 -0
  21. package/dist/bin/gen-workspace.js +3841 -0
  22. package/dist/bin/manifest.cjs +686 -0
  23. package/dist/bin/manifest.d.ts +10 -0
  24. package/dist/bin/manifest.d.ts.map +1 -0
  25. package/dist/bin/manifest.js +663 -0
  26. package/dist/bin/rpc/dispatch.d.ts +10 -0
  27. package/dist/bin/rpc/dispatch.d.ts.map +1 -0
  28. package/dist/bin/rpc/handlers.d.ts +4 -0
  29. package/dist/bin/rpc/handlers.d.ts.map +1 -0
  30. package/dist/bin/rpc/types.d.ts +29 -0
  31. package/dist/bin/rpc/types.d.ts.map +1 -0
  32. package/dist/bin/template-info.cjs +1511 -0
  33. package/dist/bin/template-info.d.ts +9 -0
  34. package/dist/bin/template-info.d.ts.map +1 -0
  35. package/dist/bin/template-info.js +1488 -0
  36. package/dist/custom-objects/build-definitions.d.ts +98 -0
  37. package/dist/custom-objects/build-definitions.d.ts.map +1 -0
  38. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts +191 -0
  39. package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts.map +1 -0
  40. package/dist/custom-objects/generated/proto/custom_objects/pub/api/common/schema.pb.d.ts +131 -0
  41. package/dist/custom-objects/generated/proto/custom_objects/pub/api/common/schema.pb.d.ts.map +1 -0
  42. package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts +1482 -0
  43. package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts.map +1 -0
  44. package/dist/custom-objects/generated/proto/google/protobuf/timestamp.pb.d.ts +167 -0
  45. package/dist/custom-objects/generated/proto/google/protobuf/timestamp.pb.d.ts.map +1 -0
  46. package/dist/custom-objects/generated/proto/proto/annotations.pb.d.ts +64 -0
  47. package/dist/custom-objects/generated/proto/proto/annotations.pb.d.ts.map +1 -0
  48. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts +657 -0
  49. package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts.map +1 -0
  50. package/dist/custom-objects/generated/proto/vendor/metadata/pub/api/api_metadata.pb.d.ts +105 -0
  51. package/dist/custom-objects/generated/proto/vendor/metadata/pub/api/api_metadata.pb.d.ts.map +1 -0
  52. package/dist/custom-objects/generated/proto/vendor/net/idempotency/idempotency_model.pb.d.ts +79 -0
  53. package/dist/custom-objects/generated/proto/vendor/net/idempotency/idempotency_model.pb.d.ts.map +1 -0
  54. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts +129 -0
  55. package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts.map +1 -0
  56. package/dist/custom-objects/generated/proto/vendor/publicapi/api_visibility.pb.d.ts +76 -0
  57. package/dist/custom-objects/generated/proto/vendor/publicapi/api_visibility.pb.d.ts.map +1 -0
  58. package/dist/custom-objects/generated/proto/vendor/publicapi/customize_dispatch_middleware_enum.pb.d.ts +78 -0
  59. package/dist/custom-objects/generated/proto/vendor/publicapi/customize_dispatch_middleware_enum.pb.d.ts.map +1 -0
  60. package/dist/custom-objects/generated/proto/vendor/publicapi/docs_namespace_group_enum.pb.d.ts +146 -0
  61. package/dist/custom-objects/generated/proto/vendor/publicapi/docs_namespace_group_enum.pb.d.ts.map +1 -0
  62. package/dist/custom-objects/generated/proto/vendor/publicapi/documented_enum.pb.d.ts +76 -0
  63. package/dist/custom-objects/generated/proto/vendor/publicapi/documented_enum.pb.d.ts.map +1 -0
  64. package/dist/custom-objects/generated/proto/vendor/publicapi/event_scope_enum.pb.d.ts +92 -0
  65. package/dist/custom-objects/generated/proto/vendor/publicapi/event_scope_enum.pb.d.ts.map +1 -0
  66. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts +124 -0
  67. package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts.map +1 -0
  68. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts +1070 -0
  69. package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts.map +1 -0
  70. package/dist/custom-objects/generated/proto/vendor/publicapi/field_validation_rules.pb.d.ts +279 -0
  71. package/dist/custom-objects/generated/proto/vendor/publicapi/field_validation_rules.pb.d.ts.map +1 -0
  72. package/dist/custom-objects/generated/proto/vendor/publicapi/flavor_enum.pb.d.ts +78 -0
  73. package/dist/custom-objects/generated/proto/vendor/publicapi/flavor_enum.pb.d.ts.map +1 -0
  74. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts +102 -0
  75. package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts.map +1 -0
  76. package/dist/custom-objects/generated/proto/vendor/publicapi/method_kind_enum.pb.d.ts +86 -0
  77. package/dist/custom-objects/generated/proto/vendor/publicapi/method_kind_enum.pb.d.ts.map +1 -0
  78. package/dist/custom-objects/generated/proto/vendor/publicapi/method_priority.pb.d.ts +80 -0
  79. package/dist/custom-objects/generated/proto/vendor/publicapi/method_priority.pb.d.ts.map +1 -0
  80. package/dist/custom-objects/generated/proto/vendor/publicapi/permission_check_enum.pb.d.ts +74 -0
  81. package/dist/custom-objects/generated/proto/vendor/publicapi/permission_check_enum.pb.d.ts.map +1 -0
  82. package/dist/custom-objects/generated/proto/vendor/publicapi/redaction_enum.pb.d.ts +76 -0
  83. package/dist/custom-objects/generated/proto/vendor/publicapi/redaction_enum.pb.d.ts.map +1 -0
  84. package/dist/custom-objects/generated/proto/vendor/publicapi/region_routers.pb.d.ts +103 -0
  85. package/dist/custom-objects/generated/proto/vendor/publicapi/region_routers.pb.d.ts.map +1 -0
  86. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts +153 -0
  87. package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts.map +1 -0
  88. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts +1111 -0
  89. package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts.map +1 -0
  90. package/dist/custom-objects/generated/proto/vendor/vext/annotations.pb.d.ts +602 -0
  91. package/dist/custom-objects/generated/proto/vendor/vext/annotations.pb.d.ts.map +1 -0
  92. package/dist/custom-objects/generated/proto/vendor/vext/extensions.pb.d.ts +144 -0
  93. package/dist/custom-objects/generated/proto/vendor/vext/extensions.pb.d.ts.map +1 -0
  94. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts +851 -0
  95. package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts.map +1 -0
  96. package/dist/custom-objects/generated/proto/vendor/vext/xml_annotations.pb.d.ts +125 -0
  97. package/dist/custom-objects/generated/proto/vendor/vext/xml_annotations.pb.d.ts.map +1 -0
  98. package/dist/custom-objects/to-proto-json.d.ts +17 -0
  99. package/dist/custom-objects/to-proto-json.d.ts.map +1 -0
  100. package/dist/dependencies/index.cjs +601 -0
  101. package/dist/dependencies/index.d.ts +320 -0
  102. package/dist/dependencies/index.d.ts.map +1 -0
  103. package/dist/dependencies/index.js +560 -0
  104. package/dist/extensibility-dev-tools-alpha.d.ts +199 -0
  105. package/dist/extensibility-dev-tools-beta.d.ts +199 -0
  106. package/dist/extensibility-dev-tools-dependencies-alpha.d.ts +51 -0
  107. package/dist/extensibility-dev-tools-dependencies-beta.d.ts +51 -0
  108. package/dist/extensibility-dev-tools-dependencies-internal.d.ts +372 -0
  109. package/dist/extensibility-dev-tools-dependencies-public.d.ts +51 -0
  110. package/dist/extensibility-dev-tools-internal.d.ts +1722 -0
  111. package/dist/extensibility-dev-tools-jsonschema-tools-alpha.d.ts +57 -0
  112. package/dist/extensibility-dev-tools-jsonschema-tools-beta.d.ts +57 -0
  113. package/dist/extensibility-dev-tools-jsonschema-tools-internal.d.ts +123 -0
  114. package/dist/extensibility-dev-tools-jsonschema-tools-public.d.ts +57 -0
  115. package/dist/extensibility-dev-tools-manifest-alpha.d.ts +31 -0
  116. package/dist/extensibility-dev-tools-manifest-beta.d.ts +31 -0
  117. package/dist/extensibility-dev-tools-manifest-internal.d.ts +461 -0
  118. package/dist/extensibility-dev-tools-manifest-public.d.ts +31 -0
  119. package/dist/extensibility-dev-tools-public.d.ts +199 -0
  120. package/dist/extensibility-dev-tools-schemas-alpha.d.ts +9 -0
  121. package/dist/extensibility-dev-tools-schemas-beta.d.ts +9 -0
  122. package/dist/extensibility-dev-tools-schemas-internal.d.ts +41 -0
  123. package/dist/extensibility-dev-tools-schemas-public.d.ts +9 -0
  124. package/dist/extensibility-dev-tools-templates-alpha.d.ts +67 -0
  125. package/dist/extensibility-dev-tools-templates-beta.d.ts +67 -0
  126. package/dist/extensibility-dev-tools-templates-internal.d.ts +554 -0
  127. package/dist/extensibility-dev-tools-templates-public.d.ts +67 -0
  128. package/dist/extensibility-dev-tools-workspace-alpha.d.ts +51 -0
  129. package/dist/extensibility-dev-tools-workspace-beta.d.ts +51 -0
  130. package/dist/extensibility-dev-tools-workspace-internal.d.ts +410 -0
  131. package/dist/extensibility-dev-tools-workspace-public.d.ts +51 -0
  132. package/dist/index.cjs +3810 -0
  133. package/dist/index.d.ts +18 -0
  134. package/dist/index.d.ts.map +1 -0
  135. package/dist/index.js +3758 -0
  136. package/dist/jsonschema-tools.cjs +20451 -0
  137. package/dist/jsonschema-tools.d.ts +98 -0
  138. package/dist/jsonschema-tools.d.ts.map +1 -0
  139. package/dist/jsonschema-tools.js +20404 -0
  140. package/dist/manifest/index.cjs +610 -0
  141. package/dist/manifest/index.d.ts +8 -0
  142. package/dist/manifest/index.d.ts.map +1 -0
  143. package/dist/manifest/index.js +571 -0
  144. package/dist/manifest/manifest-v1.d.ts +102 -0
  145. package/dist/manifest/manifest-v1.d.ts.map +1 -0
  146. package/dist/manifest/manifest-v2.d.ts +253 -0
  147. package/dist/manifest/manifest-v2.d.ts.map +1 -0
  148. package/dist/manifest/stripe-app-manifest.d.ts +114 -0
  149. package/dist/manifest/stripe-app-manifest.d.ts.map +1 -0
  150. package/dist/schemas/index.cjs +20692 -0
  151. package/dist/schemas/index.d.ts +37 -0
  152. package/dist/schemas/index.d.ts.map +1 -0
  153. package/dist/schemas/index.js +20656 -0
  154. package/dist/templates/diff-viewer/diff-generator.d.ts +22 -0
  155. package/dist/templates/diff-viewer/diff-generator.d.ts.map +1 -0
  156. package/dist/templates/diff-viewer/diff-prompt.d.ts +13 -0
  157. package/dist/templates/diff-viewer/diff-prompt.d.ts.map +1 -0
  158. package/dist/templates/diff-viewer/index.d.ts +7 -0
  159. package/dist/templates/diff-viewer/index.d.ts.map +1 -0
  160. package/dist/templates/diff-viewer/terminal-renderer.d.ts +29 -0
  161. package/dist/templates/diff-viewer/terminal-renderer.d.ts.map +1 -0
  162. package/dist/templates/diff-viewer/types.d.ts +58 -0
  163. package/dist/templates/diff-viewer/types.d.ts.map +1 -0
  164. package/dist/templates/extensions/base.d.ts +23 -0
  165. package/dist/templates/extensions/base.d.ts.map +1 -0
  166. package/dist/templates/extensions/billing.bill.discount_calculation.d.ts +6 -0
  167. package/dist/templates/extensions/billing.bill.discount_calculation.d.ts.map +1 -0
  168. package/dist/templates/extensions/billing.customer_balance_application.d.ts +6 -0
  169. package/dist/templates/extensions/billing.customer_balance_application.d.ts.map +1 -0
  170. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts +6 -0
  171. package/dist/templates/extensions/billing.invoice_collection_setting.d.ts.map +1 -0
  172. package/dist/templates/extensions/billing.prorations.d.ts +6 -0
  173. package/dist/templates/extensions/billing.prorations.d.ts.map +1 -0
  174. package/dist/templates/extensions/billing.recurring_billing_item_handling.d.ts +6 -0
  175. package/dist/templates/extensions/billing.recurring_billing_item_handling.d.ts.map +1 -0
  176. package/dist/templates/extensions/core.workflows.custom_action.d.ts +6 -0
  177. package/dist/templates/extensions/core.workflows.custom_action.d.ts.map +1 -0
  178. package/dist/templates/extensions/extend.objects.custom_objects.d.ts +6 -0
  179. package/dist/templates/extensions/extend.objects.custom_objects.d.ts.map +1 -0
  180. package/dist/templates/extensions/extend.workflows.custom_action.d.ts +6 -0
  181. package/dist/templates/extensions/extend.workflows.custom_action.d.ts.map +1 -0
  182. package/dist/templates/extensions/index.d.ts +13 -0
  183. package/dist/templates/extensions/index.d.ts.map +1 -0
  184. package/dist/templates/extensions/registry.d.ts +10 -0
  185. package/dist/templates/extensions/registry.d.ts.map +1 -0
  186. package/dist/templates/extensions/types.d.ts +104 -0
  187. package/dist/templates/extensions/types.d.ts.map +1 -0
  188. package/dist/templates/file-writer.d.ts +140 -0
  189. package/dist/templates/file-writer.d.ts.map +1 -0
  190. package/dist/templates/fs/_impl.d.ts +29 -0
  191. package/dist/templates/fs/_impl.d.ts.map +1 -0
  192. package/dist/templates/fs/filesystem.d.ts +8 -0
  193. package/dist/templates/fs/filesystem.d.ts.map +1 -0
  194. package/dist/templates/fs/in-memory.d.ts +9 -0
  195. package/dist/templates/fs/in-memory.d.ts.map +1 -0
  196. package/dist/templates/fs/index.d.ts +25 -0
  197. package/dist/templates/fs/index.d.ts.map +1 -0
  198. package/dist/templates/fs-utils.d.ts +17 -0
  199. package/dist/templates/fs-utils.d.ts.map +1 -0
  200. package/dist/templates/index.cjs +2248 -0
  201. package/dist/templates/index.d.ts +32 -0
  202. package/dist/templates/index.d.ts.map +1 -0
  203. package/dist/templates/index.js +2203 -0
  204. package/dist/templates/root/index.d.ts +60 -0
  205. package/dist/templates/root/index.d.ts.map +1 -0
  206. package/dist/templates/simple-templates.d.ts +8 -0
  207. package/dist/templates/simple-templates.d.ts.map +1 -0
  208. package/dist/templates/template-manager.d.ts +8 -0
  209. package/dist/templates/template-manager.d.ts.map +1 -0
  210. package/dist/templates/types.d.ts +9 -0
  211. package/dist/templates/types.d.ts.map +1 -0
  212. package/dist/tsconfig.build.tsbuildinfo +1 -0
  213. package/dist/workspace/index.cjs +3756 -0
  214. package/dist/workspace/index.d.ts +336 -0
  215. package/dist/workspace/index.d.ts.map +1 -0
  216. package/dist/workspace/index.js +3731 -0
  217. package/package.json +137 -0
  218. package/templates/extensions/billing.bill.discount_calculation/index.test.ts +15 -0
  219. package/templates/extensions/billing.bill.discount_calculation/index.ts +20 -0
  220. package/templates/extensions/billing.customer_balance_application/index.test.ts +15 -0
  221. package/templates/extensions/billing.customer_balance_application/index.ts +18 -0
  222. package/templates/extensions/billing.invoice_collection_setting/index.test.ts +15 -0
  223. package/templates/extensions/billing.invoice_collection_setting/index.ts +16 -0
  224. package/templates/extensions/billing.prorations/index.test.ts +15 -0
  225. package/templates/extensions/billing.prorations/index.ts +18 -0
  226. package/templates/extensions/billing.recurring_billing_item_handling/index.test.ts +15 -0
  227. package/templates/extensions/billing.recurring_billing_item_handling/index.ts +42 -0
  228. package/templates/extensions/common/.prettierignore +3 -0
  229. package/templates/extensions/common/eslint.config.mts.mustache +95 -0
  230. package/templates/extensions/common/package.json.mustache +26 -0
  231. package/templates/extensions/common/tsconfig.build.json.mustache +15 -0
  232. package/templates/extensions/common/tsconfig.json.mustache +16 -0
  233. package/templates/extensions/core.workflows.custom_action/custom_input.schema.json +6 -0
  234. package/templates/extensions/core.workflows.custom_action/index.test.ts +15 -0
  235. package/templates/extensions/core.workflows.custom_action/index.ts +31 -0
  236. package/templates/extensions/extend.workflows.custom_action/custom_input.schema.json +6 -0
  237. package/templates/extensions/extend.workflows.custom_action/index.test.ts +15 -0
  238. package/templates/extensions/extend.workflows.custom_action/index.ts +31 -0
  239. package/templates/root/.husky/pre-commit +1 -0
  240. package/templates/root/.prettierignore +5 -0
  241. package/templates/root/.prettierrc +7 -0
  242. package/templates/root/_gitignore +28 -0
  243. package/templates/root/custom-objects/package.json +20 -0
  244. package/templates/root/custom-objects/tsconfig.json +9 -0
  245. package/templates/root/eslint.config.mts +95 -0
  246. package/templates/root/package.json.mustache +32 -0
  247. package/templates/root/pnpm-workspace.yaml +7 -0
  248. package/templates/root/stripe-app.yaml.mustache +6 -0
  249. package/templates/root/tools/test.mts +38 -0
  250. package/templates/root/tsconfig.base.json +23 -0
  251. package/templates/root/tsconfig.json +15 -0
  252. package/templates/root/ui/package.json +17 -0
  253. package/templates/root/vitest.config.mts +47 -0
@@ -0,0 +1,1511 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
18
+ // If the importer is in node compatibility mode or this is not an ESM
19
+ // file that has been converted to a CommonJS file using a Babel-
20
+ // compatible transform (i.e. "__esModule" has not been set), then set
21
+ // "default" to the CommonJS "module.exports" for node compatibility.
22
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
23
+ mod
24
+ ));
25
+
26
+ // src/bin/template-info.ts
27
+ var import_yargs = __toESM(require("yargs"), 1);
28
+ var import_helpers = require("yargs/helpers");
29
+ var import_extensibility_tool_utils5 = require("@stripe/extensibility-tool-utils");
30
+
31
+ // src/templates/template-manager.ts
32
+ var import_extensibility_tool_utils = require("@stripe/extensibility-tool-utils");
33
+
34
+ // src/templates/extensions/types.ts
35
+ var _ExtensionTemplateManager = class extends import_extensibility_tool_utils._TemplateManager {
36
+ /**
37
+ * Get summary info for all registered extension templates
38
+ */
39
+ getTemplateInfo() {
40
+ return this.getTemplateEntries().map(([key, t]) => ({
41
+ key,
42
+ description: t.description,
43
+ deprecated: t.deprecated ?? false,
44
+ hidden: t.hidden ?? false,
45
+ methods: t.methods
46
+ }));
47
+ }
48
+ };
49
+
50
+ // src/templates/fs/in-memory.ts
51
+ var import_extensibility_tool_utils2 = require("@stripe/extensibility-tool-utils");
52
+
53
+ // templates-virtual:./_impl.js
54
+ var TEMPLATE_FS_IMAGE = [
55
+ {
56
+ path: "extensions/billing.bill.discount_calculation/index.test.ts",
57
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
58
+
59
+ import MyDiscountCalculation from './index.js';
60
+
61
+ describe('MyDiscountCalculation', () => {
62
+ let instance: MyDiscountCalculation;
63
+
64
+ beforeEach(() => {
65
+ instance = new MyDiscountCalculation();
66
+ });
67
+
68
+ it('should be constructable', () => {
69
+ expect(instance).toBeInstanceOf(MyDiscountCalculation);
70
+ });
71
+ });
72
+ `
73
+ },
74
+ {
75
+ path: "extensions/billing.bill.discount_calculation/index.ts",
76
+ content: `import type { Billing } from '@stripe/extensibility-sdk/extensions';
77
+ import type { Context } from '@stripe/extensibility-sdk/extensions';
78
+
79
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
80
+ interface MyDiscountCalculationConfig extends Record<string, unknown> {}
81
+
82
+ export default class MyDiscountCalculation implements Billing.Bill
83
+ .DiscountCalculation<MyDiscountCalculationConfig> {
84
+ computeDiscounts(
85
+ request: Billing.Bill.DiscountCalculation.DiscountableItem,
86
+ _config: MyDiscountCalculationConfig,
87
+ _context: Context
88
+ ) {
89
+ // TODO: implement your discount logic here
90
+
91
+ return {
92
+ discount: { amount: request.grossAmount },
93
+ };
94
+ }
95
+ }
96
+ `
97
+ },
98
+ {
99
+ path: "extensions/billing.customer_balance_application/index.test.ts",
100
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
101
+
102
+ import MyCustomerBalanceApplication from './index.js';
103
+
104
+ describe('MyCustomerBalanceApplication', () => {
105
+ let instance: MyCustomerBalanceApplication;
106
+
107
+ beforeEach(() => {
108
+ instance = new MyCustomerBalanceApplication();
109
+ });
110
+
111
+ it('should be constructable', () => {
112
+ expect(instance).toBeInstanceOf(MyCustomerBalanceApplication);
113
+ });
114
+ });
115
+ `
116
+ },
117
+ {
118
+ path: "extensions/billing.customer_balance_application/index.ts",
119
+ content: `import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
120
+
121
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
122
+ interface MyCustomerBalanceApplicationConfig extends Record<string, unknown> {}
123
+
124
+ export default class MyCustomerBalanceApplication implements Billing.CustomerBalanceApplication<MyCustomerBalanceApplicationConfig> {
125
+ computeAppliedCustomerBalance(
126
+ request: Billing.CustomerBalanceApplication.CustomerBalanceApplicationInput,
127
+ _config: MyCustomerBalanceApplicationConfig,
128
+ _context: Context
129
+ ) {
130
+ // TODO: implement your customer balance logic here
131
+
132
+ return {
133
+ appliedCustomerBalance: request.customerBalance,
134
+ };
135
+ }
136
+ }
137
+ `
138
+ },
139
+ {
140
+ path: "extensions/billing.invoice_collection_setting/index.test.ts",
141
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
142
+
143
+ import MyInvoiceCollectionSetting from './index.js';
144
+
145
+ describe('MyInvoiceCollectionSetting', () => {
146
+ let instance: MyInvoiceCollectionSetting;
147
+
148
+ beforeEach(() => {
149
+ instance = new MyInvoiceCollectionSetting();
150
+ });
151
+
152
+ it('should be constructable', () => {
153
+ expect(instance).toBeInstanceOf(MyInvoiceCollectionSetting);
154
+ });
155
+ });
156
+ `
157
+ },
158
+ {
159
+ path: "extensions/billing.invoice_collection_setting/index.ts",
160
+ content: `import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
161
+
162
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
163
+ interface MyInvoiceCollectionSettingConfig extends Record<string, unknown> {}
164
+
165
+ export default class MyInvoiceCollectionSetting implements Billing.InvoiceCollectionSetting<MyInvoiceCollectionSettingConfig> {
166
+ collectionOverride(
167
+ _request: Billing.InvoiceCollectionSetting.InvoiceCollectionRequest,
168
+ _config: MyInvoiceCollectionSettingConfig,
169
+ _context: Context
170
+ ) {
171
+ // TODO: implement your collection setting logic here
172
+
173
+ return {};
174
+ }
175
+ }
176
+ `
177
+ },
178
+ {
179
+ path: "extensions/billing.prorations/index.test.ts",
180
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
181
+
182
+ import MyProrations from './index.js';
183
+
184
+ describe('MyProrations', () => {
185
+ let instance: MyProrations;
186
+
187
+ beforeEach(() => {
188
+ instance = new MyProrations();
189
+ });
190
+
191
+ it('should be constructable', () => {
192
+ expect(instance).toBeInstanceOf(MyProrations);
193
+ });
194
+ });
195
+ `
196
+ },
197
+ {
198
+ path: "extensions/billing.prorations/index.ts",
199
+ content: `import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
200
+
201
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
202
+ interface MyProrationsConfig extends Record<string, unknown> {}
203
+
204
+ export default class MyProrations implements Billing.Prorations<MyProrationsConfig> {
205
+ prorateItems(
206
+ _request: Billing.Prorations.ProrateItemsInput,
207
+ _config: MyProrationsConfig,
208
+ _context: Context
209
+ ) {
210
+ // TODO: implement your proration logic here
211
+
212
+ return {
213
+ items: [],
214
+ };
215
+ }
216
+ }
217
+ `
218
+ },
219
+ {
220
+ path: "extensions/billing.recurring_billing_item_handling/index.test.ts",
221
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
222
+
223
+ import MyRecurringBillingItemHandling from './index.js';
224
+
225
+ describe('MyRecurringBillingItemHandling', () => {
226
+ let instance: MyRecurringBillingItemHandling;
227
+
228
+ beforeEach(() => {
229
+ instance = new MyRecurringBillingItemHandling();
230
+ });
231
+
232
+ it('should be constructable', () => {
233
+ expect(instance).toBeInstanceOf(MyRecurringBillingItemHandling);
234
+ });
235
+ });
236
+ `
237
+ },
238
+ {
239
+ path: "extensions/billing.recurring_billing_item_handling/index.ts",
240
+ content: `import type { Billing, Context } from '@stripe/extensibility-sdk/extensions';
241
+
242
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
243
+ interface MyRecurringBillingItemHandlingConfig extends Record<string, unknown> {}
244
+
245
+ export default class MyRecurringBillingItemHandling implements Billing.RecurringBillingItemHandling<MyRecurringBillingItemHandlingConfig> {
246
+ beforeItemCreation(
247
+ _request: Billing.RecurringBillingItemHandling.BeforeItemCreationInput,
248
+ _config: MyRecurringBillingItemHandlingConfig,
249
+ _context: Context
250
+ ) {
251
+ // TODO: implement your before-item-creation logic here
252
+
253
+ return {
254
+ items: [],
255
+ };
256
+ }
257
+
258
+ filterItems(
259
+ _request: Billing.RecurringBillingItemHandling.FilterItemsInput,
260
+ _config: MyRecurringBillingItemHandlingConfig,
261
+ _context: Context
262
+ ) {
263
+ // TODO: implement your filter-items logic here
264
+
265
+ return {
266
+ items: [],
267
+ };
268
+ }
269
+
270
+ groupItems(
271
+ _request: Billing.RecurringBillingItemHandling.GroupItemsInput,
272
+ _config: MyRecurringBillingItemHandlingConfig,
273
+ _context: Context
274
+ ) {
275
+ // TODO: implement your group-items logic here
276
+
277
+ return {
278
+ groups: [],
279
+ };
280
+ }
281
+ }
282
+ `
283
+ },
284
+ {
285
+ path: "extensions/common/.prettierignore",
286
+ content: `dist
287
+ generated
288
+ node_modules
289
+ `
290
+ },
291
+ {
292
+ path: "extensions/common/eslint.config.mts.mustache",
293
+ content: `import eslint from '@eslint/js';
294
+ import { defineConfig } from 'eslint/config';
295
+ import tseslint from 'typescript-eslint';
296
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
297
+
298
+ import globals from 'globals';
299
+
300
+ import stripeAppsConfig from '@stripe/extensibility-eslint-plugin';
301
+ import extensionTypeConfig from '@stripe/extensibility-eslint-plugin/{{extensionInterfaceId}}';
302
+
303
+ export default defineConfig([
304
+ eslint.configs.recommended,
305
+ ...tseslint.configs.recommended,
306
+ ...stripeAppsConfig,
307
+ ...extensionTypeConfig,
308
+
309
+ // Global ignores
310
+ {
311
+ ignores: ['dist', 'generated', 'node_modules'],
312
+ },
313
+
314
+ // TypeScript source files (with type-checking)
315
+ {
316
+ name: 'sources',
317
+ files: ['src/**/*.ts'],
318
+ ignores: ['**/*.test.ts', '**/__tests__/**'],
319
+ languageOptions: {
320
+ globals: {
321
+ ...globals.node,
322
+ },
323
+ parserOptions: {
324
+ projectService: true,
325
+ tsconfigRootDir: import.meta.dirname,
326
+ },
327
+ },
328
+ },
329
+
330
+ // Test files (type-checking, relaxed rules)
331
+ {
332
+ name: 'tests',
333
+ files: ['src/**/*.test.ts', 'src/**/__tests__/**/*.ts'],
334
+ languageOptions: {
335
+ globals: {
336
+ ...globals.node,
337
+ },
338
+ parserOptions: {
339
+ projectService: true,
340
+ tsconfigRootDir: import.meta.dirname,
341
+ },
342
+ },
343
+ rules: {
344
+ '@typescript-eslint/no-explicit-any': 'off',
345
+ '@typescript-eslint/no-unused-vars': 'off',
346
+ 'no-console': 'off',
347
+ },
348
+ },
349
+
350
+ // Config files
351
+ {
352
+ name: 'ts-configs',
353
+ files: ['*.config.m?ts', 'eslint.config.mts'],
354
+ languageOptions: {
355
+ globals: {
356
+ ...globals.node,
357
+ },
358
+ parserOptions: {
359
+ projectService: false,
360
+ },
361
+ },
362
+ rules: {
363
+ '@typescript-eslint/no-unused-vars': 'off',
364
+ },
365
+ },
366
+
367
+ // JavaScript/MJS files (scripts, configs)
368
+ {
369
+ name: 'js-configs',
370
+ files: ['**/*.js', '**/*.mjs'],
371
+ languageOptions: {
372
+ globals: {
373
+ ...globals.node,
374
+ },
375
+ parserOptions: {
376
+ projectService: false,
377
+ },
378
+ },
379
+ rules: {
380
+ '@typescript-eslint/no-require-imports': 'off',
381
+ '@typescript-eslint/no-unused-vars': 'off',
382
+ 'no-unused-vars': 'off',
383
+ },
384
+ },
385
+
386
+ eslintConfigPrettier,
387
+ ]);
388
+ `
389
+ },
390
+ {
391
+ path: "extensions/common/package.json.mustache",
392
+ content: `{
393
+ "name": "{{id}}",
394
+ "version": "{{version}}",
395
+ "description": "{{name}}",
396
+ "private": true,
397
+ "license": "~~proprietary~~",
398
+ "type": "module",
399
+ "scripts": {
400
+ "build": "tsc -p tsconfig.build.json && pnpm build:schemas",
401
+ "build:schemas": "gen-schemas --root ../.. --extension-id \\"$npm_package_name\\" --out-dir generated --schema-name config",
402
+ "lint": "pnpm lint:types && pnpm lint:eslint && pnpm lint:format",
403
+ "lint:types": "tsc -p tsconfig.build.json --noEmit && tsc -p tsconfig.json --noEmit",
404
+ "lint:eslint": "eslint .",
405
+ "lint:format": "prettier --check .",
406
+ "fix:lint": "eslint --fix .",
407
+ "fix:format": "prettier --write .",
408
+ "test": "vitest --root ../.. run --project \\"$npm_package_name\\"",
409
+ "test:watch": "pnpm test --watch",
410
+ "dev": "concurrently -n build,lint,test -c blue,yellow,green 'tsc -p tsconfig.json -w --noEmit' 'chokidar \\"src/**/*.{ts,json}\\" -c \\"eslint .\\"' 'pnpm test --watch --no-clear-screen'",
411
+ "stripe:regen": "gen-workspace --root ../.. --package-dir . --template-id {{extensionInterfaceId}}"
412
+ },
413
+ "lint-staged": {
414
+ "*.{ts,mts,mjs,js}": ["eslint --fix", "prettier --write"],
415
+ "*.{json,md,yaml}": "prettier --write"
416
+ }
417
+ }
418
+ `
419
+ },
420
+ {
421
+ path: "extensions/common/tsconfig.build.json.mustache",
422
+ content: `{
423
+ "extends": "../../tsconfig.base.json",
424
+ "compilerOptions": {
425
+ "lib": null,
426
+ "noLib": true,
427
+ "outDir": "./dist",
428
+ "rootDir": "./src"
429
+ },
430
+ "include": [
431
+ "src/**/*.ts",
432
+ "node_modules/@stripe/extensibility-sdk/tslibs/5.9.3/lib.es2022.{{executionProfile}}.d.ts",
433
+ "node_modules/@stripe/extensibility-sdk/tslibs/lib.{{executionProfile}}.globals.d.ts"
434
+ ],
435
+ "exclude": ["src/**/*.test.ts", "src/**/__tests__"]
436
+ }
437
+ `
438
+ },
439
+ {
440
+ path: "extensions/common/tsconfig.json.mustache",
441
+ content: `{
442
+ "extends": "../../tsconfig.json",
443
+ "compilerOptions": {
444
+ "rootDir": ".",
445
+ "plugins": [
446
+ {
447
+ "name": "@stripe/extensibility-language-server/plugin"
448
+ }
449
+ ]
450
+ },
451
+ "include": [
452
+ "src/**/*.ts",
453
+ "node_modules/@stripe/extensibility-sdk/tslibs/lib.{{executionProfile}}.globals.d.ts"
454
+ ],
455
+ "exclude": ["dist"]
456
+ }
457
+ `
458
+ },
459
+ {
460
+ path: "extensions/core.workflows.custom_action/custom_input.schema.json",
461
+ content: `{
462
+ "$schema": "http://json-schema.org/draft-07/schema#",
463
+ "type": "object",
464
+ "properties": {},
465
+ "additionalProperties": false
466
+ }
467
+ `
468
+ },
469
+ {
470
+ path: "extensions/core.workflows.custom_action/index.test.ts",
471
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
472
+
473
+ import MyCustomAction from './index.js';
474
+
475
+ describe('MyCustomAction', () => {
476
+ let instance: MyCustomAction;
477
+
478
+ beforeEach(() => {
479
+ instance = new MyCustomAction();
480
+ });
481
+
482
+ it('should be constructable', () => {
483
+ expect(instance).toBeInstanceOf(MyCustomAction);
484
+ });
485
+ });
486
+ `
487
+ },
488
+ {
489
+ path: "extensions/core.workflows.custom_action/index.ts",
490
+ content: `import type { Core } from '@stripe/extensibility-sdk/extensions';
491
+ import type { Context } from '@stripe/extensibility-sdk/extensions';
492
+
493
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
494
+ interface MyCustomActionConfig extends Record<string, unknown> {}
495
+
496
+ export default class MyCustomAction implements Core.Workflows
497
+ .CustomAction<MyCustomActionConfig> {
498
+ execute(
499
+ _request: Core.Workflows.CustomAction.ExecuteCustomActionRequest,
500
+ _config: MyCustomActionConfig,
501
+ _context: Context
502
+ ) {
503
+ // TODO: implement your action logic here
504
+
505
+ return {};
506
+ }
507
+
508
+ getFormState(
509
+ _request: Core.Workflows.CustomAction.GetFormStateRequest,
510
+ _config: MyCustomActionConfig,
511
+ _context: Context
512
+ ) {
513
+ // TODO: implement your logic here
514
+
515
+ return {
516
+ values: {},
517
+ config: {},
518
+ };
519
+ }
520
+ }
521
+ `
522
+ },
523
+ {
524
+ path: "extensions/extend.workflows.custom_action/custom_input.schema.json",
525
+ content: `{
526
+ "$schema": "http://json-schema.org/draft-07/schema#",
527
+ "type": "object",
528
+ "properties": {},
529
+ "additionalProperties": false
530
+ }
531
+ `
532
+ },
533
+ {
534
+ path: "extensions/extend.workflows.custom_action/index.test.ts",
535
+ content: `import { beforeEach, describe, it, expect } from 'vitest';
536
+
537
+ import MyCustomAction from './index.js';
538
+
539
+ describe('MyCustomAction', () => {
540
+ let instance: MyCustomAction;
541
+
542
+ beforeEach(() => {
543
+ instance = new MyCustomAction();
544
+ });
545
+
546
+ it('should be constructable', () => {
547
+ expect(instance).toBeInstanceOf(MyCustomAction);
548
+ });
549
+ });
550
+ `
551
+ },
552
+ {
553
+ path: "extensions/extend.workflows.custom_action/index.ts",
554
+ content: `import type { Extend } from '@stripe/extensibility-sdk/extensions';
555
+ import type { Context } from '@stripe/extensibility-sdk/extensions';
556
+
557
+ // eslint-disable-next-line @typescript-eslint/no-empty-object-type
558
+ interface MyCustomActionConfig extends Record<string, unknown> {}
559
+
560
+ export default class MyCustomAction implements Extend.Workflows
561
+ .CustomAction<MyCustomActionConfig> {
562
+ execute(
563
+ _request: Extend.Workflows.CustomAction.ExecuteCustomActionRequest,
564
+ _config: MyCustomActionConfig,
565
+ _context: Context
566
+ ) {
567
+ // TODO: implement your action logic here
568
+
569
+ return {};
570
+ }
571
+
572
+ getFormState(
573
+ _request: Extend.Workflows.CustomAction.GetFormStateRequest,
574
+ _config: MyCustomActionConfig,
575
+ _context: Context
576
+ ) {
577
+ // TODO: implement your logic here
578
+
579
+ return {
580
+ values: {},
581
+ config: {},
582
+ };
583
+ }
584
+ }
585
+ `
586
+ },
587
+ {
588
+ path: "root/.husky/pre-commit",
589
+ content: `pnpm lint-staged
590
+ `
591
+ },
592
+ {
593
+ path: "root/.prettierignore",
594
+ content: `dist
595
+ generated
596
+ node_modules
597
+ pnpm-lock.yaml
598
+ .build
599
+ `
600
+ },
601
+ {
602
+ path: "root/.prettierrc",
603
+ content: `{
604
+ "semi": true,
605
+ "singleQuote": true,
606
+ "tabWidth": 2,
607
+ "trailingComma": "es5",
608
+ "printWidth": 90
609
+ }
610
+ `
611
+ },
612
+ {
613
+ path: "root/_gitignore",
614
+ content: `# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
615
+
616
+ *~
617
+
618
+ # dependencies
619
+ node_modules
620
+ dist
621
+
622
+ # testing
623
+ /coverage
624
+
625
+ # production
626
+ /.build
627
+
628
+ # misc
629
+ .DS_Store
630
+ .env.local
631
+ .env.development.local
632
+ .env.test.local
633
+ .env.production.local
634
+
635
+ npm-debug.log*
636
+ yarn-debug.log*
637
+ yarn-error.log*
638
+ install-deps.log
639
+
640
+ # generated schemas
641
+ generated
642
+ `
643
+ },
644
+ {
645
+ path: "root/custom-objects/package.json",
646
+ content: `{
647
+ "name": "custom-objects",
648
+ "type": "module",
649
+ "version": "0.0.1",
650
+ "license": "UNLICENSED",
651
+ "private": true,
652
+ "scripts": {
653
+ "build": "test -d src && custom-objects-build --input src --output dist || true",
654
+ "lint:types": "test ! -d src || tsc --noEmit",
655
+ "test": "vitest run"
656
+ },
657
+ "dependencies": {
658
+ "@stripe/extensibility-custom-objects": "0.7.4",
659
+ "@stripe/extensibility-sdk": "0.22.4"
660
+ },
661
+ "devDependencies": {
662
+ "@stripe/extensibility-custom-objects-tools": "0.40.0",
663
+ "@stripe/extensibility-test-helpers": "0.2.7"
664
+ }
665
+ }
666
+ `
667
+ },
668
+ {
669
+ path: "root/custom-objects/tsconfig.json",
670
+ content: `{
671
+ "extends": "../tsconfig.base.json",
672
+ "compilerOptions": {
673
+ "module": "ESNext",
674
+ "moduleResolution": "bundler",
675
+ "types": ["vitest/globals"]
676
+ },
677
+ "exclude": ["dist"]
678
+ }
679
+ `
680
+ },
681
+ {
682
+ path: "root/eslint.config.mts",
683
+ content: `import { readFileSync } from 'node:fs';
684
+ import { dirname, resolve } from 'node:path';
685
+ import { fileURLToPath } from 'node:url';
686
+ import eslint from '@eslint/js';
687
+ import { defineConfig } from 'eslint/config';
688
+ import tseslint from 'typescript-eslint';
689
+ import workspaces from 'eslint-plugin-workspaces';
690
+ import eslintConfigPrettier from 'eslint-config-prettier/flat';
691
+
692
+ import globals from 'globals';
693
+
694
+ import stripeAppsConfig from '@stripe/extensibility-eslint-plugin';
695
+
696
+ // Read additional ignore globs from package.json (written by the generate plugin
697
+ // to exclude generated SDK directories from linting).
698
+ let stripeGlobsToIgnore: string[] = [];
699
+ try {
700
+ const configDir = dirname(fileURLToPath(import.meta.url));
701
+ const packageJsonPath = resolve(configDir, './package.json');
702
+ const pkg = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
703
+ const globs = pkg?.stripe?.eslintIgnoreGlobs;
704
+ if (Array.isArray(globs)) {
705
+ stripeGlobsToIgnore = globs.filter(
706
+ (g: unknown): g is string => typeof g === 'string'
707
+ );
708
+ }
709
+ } catch {
710
+ // package.json not found or unparseable \u2014 ignore
711
+ }
712
+
713
+ export default defineConfig([
714
+ eslint.configs.recommended,
715
+ ...tseslint.configs.recommended,
716
+ ...stripeAppsConfig,
717
+
718
+ // Global ignores
719
+ {
720
+ ignores: [
721
+ '.build',
722
+ '**/dist',
723
+ '**/generated',
724
+ '**/node_modules',
725
+ 'extensions/**',
726
+ 'custom-objects',
727
+ 'ui',
728
+ ...stripeGlobsToIgnore,
729
+ ],
730
+ },
731
+
732
+ // Common rules for all files
733
+ {
734
+ plugins: { workspaces },
735
+ rules: {
736
+ ...workspaces.configs.recommended.rules,
737
+ },
738
+ },
739
+
740
+ // Config files (vitest.config.ts, eslint.config.ts, etc.)
741
+ {
742
+ name: 'ts-configs',
743
+ files: ['extensions/*/*.config.m?ts', '*.config.m?ts', 'eslint.config.mts'],
744
+ languageOptions: {
745
+ globals: {
746
+ ...globals.node,
747
+ },
748
+ parserOptions: {
749
+ projectService: false,
750
+ },
751
+ },
752
+ rules: {
753
+ '@typescript-eslint/no-unused-vars': 'off',
754
+ },
755
+ },
756
+
757
+ // JavaScript/MJS files (scripts, configs)
758
+ {
759
+ name: 'js-configs',
760
+ files: ['**/*.js', '**/*.mjs'],
761
+ languageOptions: {
762
+ globals: {
763
+ ...globals.node,
764
+ },
765
+ parserOptions: {
766
+ projectService: false,
767
+ },
768
+ },
769
+ rules: {
770
+ '@typescript-eslint/no-require-imports': 'off',
771
+ '@typescript-eslint/no-unused-vars': 'off',
772
+ 'no-unused-vars': 'off',
773
+ },
774
+ },
775
+
776
+ eslintConfigPrettier,
777
+ ]);
778
+ `
779
+ },
780
+ {
781
+ path: "root/package.json.mustache",
782
+ content: `{
783
+ "name": "{{ appId }}",
784
+ "version": "{{ version }}",
785
+ "description": "{{ appName }}",
786
+ "private": true,
787
+ "license": "~~proprietary~~",
788
+ "engines": {
789
+ "node": ">=20.0.0"
790
+ },
791
+ "packageManager": "pnpm@10.30.3",
792
+ "scripts": {
793
+ "build": "pnpm -r --if-present build",
794
+ "lint": "pnpm lint:types && pnpm lint:eslint && pnpm lint:format",
795
+ "lint:types": "pnpm -r --if-present lint:types",
796
+ "lint:eslint": "eslint . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present lint:eslint",
797
+ "lint:format": "prettier --check .",
798
+ "fix:lint": "eslint --fix . --ignore-pattern 'extensions/**' && pnpm -r --filter './extensions/*' --if-present fix:lint",
799
+ "fix:format": "prettier --write .",
800
+ "test": "tsx tools/test.mts",
801
+ "test:watch": "vitest watch",
802
+ "check": "pnpm build && pnpm lint && pnpm test",
803
+ "prepare": "husky",
804
+ "preimage": "pnpm install --lockfile-only && pnpm build && pnpm lint:types && pnpm lint:eslint && pnpm test",
805
+ "image": "rm -rf .build && create-upload-image .build",
806
+ "postimage": "cp pnpm-lock.yaml .build/",
807
+ "stripe:regen": "gen-workspace --package-dir ."
808
+ },
809
+ "lint-staged": {
810
+ "*.{ts,mts,mjs,js}": ["eslint --fix", "prettier --write"],
811
+ "*.{json,md,yaml}": "prettier --write"
812
+ }
813
+ }
814
+ `
815
+ },
816
+ {
817
+ path: "root/pnpm-workspace.yaml",
818
+ content: `packages:
819
+ - extensions/*
820
+ - custom-objects
821
+ - ui
822
+
823
+ overrides:
824
+ vite: ^6.0.0
825
+ `
826
+ },
827
+ {
828
+ path: "root/stripe-app.yaml.mustache",
829
+ content: `$schema: https://stripe.com/stripe-app/v2.0.0/schema
830
+ id: '{{ appId }}'
831
+ name: '{{ appName }}'
832
+ version: 0.0.1
833
+ declarations:
834
+ distribution_type: private
835
+ `
836
+ },
837
+ {
838
+ path: "root/tools/test.mts",
839
+ content: `#!/usr/bin/env tsx
840
+ /**
841
+ * Runs tests across the workspace:
842
+ * - vitest for script extensions and custom objects (extensions/*)
843
+ * - jest for UI extensions (ui/)
844
+ */
845
+ import { existsSync, readdirSync } from 'node:fs';
846
+ import { execSync } from 'node:child_process';
847
+
848
+ const hasExtensions =
849
+ existsSync('extensions') &&
850
+ readdirSync('extensions').some((name) => existsSync(\`extensions/\${name}/package.json\`));
851
+
852
+ const hasUI = existsSync('ui/package.json');
853
+
854
+ let exitCode = 0;
855
+
856
+ function run(cmd: string): void {
857
+ try {
858
+ execSync(cmd, { stdio: 'inherit' });
859
+ } catch (e: unknown) {
860
+ exitCode = (e as NodeJS.ErrnoException & { status?: number }).status ?? 1;
861
+ }
862
+ }
863
+
864
+ if (hasExtensions) {
865
+ run('vitest run');
866
+ }
867
+
868
+ if (hasUI) {
869
+ try {
870
+ execSync('pnpm --filter "./ui" test', { stdio: 'inherit' });
871
+ } catch {
872
+ // UI test failures are non-fatal
873
+ }
874
+ }
875
+
876
+ process.exit(exitCode);
877
+ `
878
+ },
879
+ {
880
+ path: "root/tsconfig.base.json",
881
+ content: `{
882
+ "compilerOptions": {
883
+ "target": "ES2022",
884
+ "module": "NodeNext",
885
+ "moduleResolution": "NodeNext",
886
+ "lib": ["ES2022"],
887
+ "declaration": true,
888
+ "declarationMap": true,
889
+ "esModuleInterop": true,
890
+ "exactOptionalPropertyTypes": false,
891
+ "forceConsistentCasingInFileNames": true,
892
+ "isolatedModules": true,
893
+ "noFallthroughCasesInSwitch": true,
894
+ "noImplicitReturns": true,
895
+ "removeComments": false,
896
+ "resolveJsonModule": true,
897
+ "skipLibCheck": true,
898
+ "sourceMap": true,
899
+ "strict": true,
900
+ "types": [],
901
+ "verbatimModuleSyntax": true
902
+ }
903
+ }
904
+ `
905
+ },
906
+ {
907
+ path: "root/tsconfig.json",
908
+ content: `{
909
+ "extends": "./tsconfig.base.json",
910
+ "compilerOptions": {
911
+ "noEmit": true,
912
+ "plugins": [
913
+ {
914
+ "name": "@stripe/extensibility-language-server/plugin"
915
+ }
916
+ ],
917
+ "preserveWatchOutput": true,
918
+ "types": ["vitest/globals", "node"]
919
+ },
920
+ "include": ["**/*.ts"],
921
+ "exclude": ["**/node_modules", "**/dist"]
922
+ }
923
+ `
924
+ },
925
+ {
926
+ path: "root/ui/package.json",
927
+ content: `{
928
+ "name": "ui",
929
+ "version": "0.0.1",
930
+ "license": "UNLICENSED",
931
+ "private": true,
932
+ "scripts": {
933
+ "test": "jest --passWithNoTests"
934
+ },
935
+ "dependencies": {
936
+ "@stripe/ui-extension-sdk": "^9.1.0"
937
+ },
938
+ "devDependencies": {
939
+ "@stripe/ui-extension-tools": "^0.0.1",
940
+ "@types/jest": "^27.5.2",
941
+ "@types/react": "^17.0.2"
942
+ }
943
+ }
944
+ `
945
+ },
946
+ {
947
+ path: "root/vitest.config.mts",
948
+ content: `import { defineConfig } from 'vitest/config';
949
+ import { existsSync, readdirSync } from 'fs';
950
+ import { dirname, resolve } from 'path';
951
+ import { fileURLToPath } from 'url';
952
+
953
+ const rootDir = dirname(fileURLToPath(import.meta.url));
954
+ const extensionsDir = resolve(rootDir, 'extensions');
955
+
956
+ const extensionProjects = existsSync(extensionsDir)
957
+ ? readdirSync(extensionsDir)
958
+ .filter((name) => existsSync(resolve(extensionsDir, name, 'package.json')))
959
+ .map((name) => resolve(extensionsDir, name))
960
+ : [];
961
+
962
+ const coProjects = existsSync(resolve(rootDir, 'custom-objects/package.json'))
963
+ ? [resolve(rootDir, 'custom-objects')]
964
+ : [];
965
+
966
+ const projects = [...extensionProjects, ...coProjects];
967
+
968
+ if (projects.length === 0) {
969
+ console.debug(\`No vitest projects detected. This means either:
970
+ - You have no extension projects defined, in which case this warning is expected.
971
+ - There is an internal error detecting vitest projects relative to the project root
972
+ \${rootDir}.
973
+ \`);
974
+ }
975
+
976
+ export default projects.length > 0
977
+ ? defineConfig({
978
+ test: {
979
+ projects,
980
+ passWithNoTests: true,
981
+
982
+ // Only run tests from src, not compiled dist
983
+ exclude: ['**/node_modules', '**/dist'],
984
+ // Place snapshots alongside test files instead of in __snapshots__
985
+ snapshotFormat: {
986
+ escapeString: false,
987
+ printBasicPrototype: false,
988
+ },
989
+ resolveSnapshotPath: (testPath, snapExtension) => {
990
+ return testPath.replace(/\\.test\\.ts$/, \`.test\${snapExtension}\`);
991
+ },
992
+ },
993
+ })
994
+ : defineConfig({ test: { passWithNoTests: true, include: [] } });
995
+ `
996
+ }
997
+ ];
998
+ var _fs = (0, import_extensibility_tool_utils2._createInMemoryTemplateFS)(TEMPLATE_FS_IMAGE);
999
+
1000
+ // src/dependencies/index.ts
1001
+ var import_node_path = __toESM(require("path"), 1);
1002
+ var import_node_fs = __toESM(require("fs"), 1);
1003
+ var import_node_os = __toESM(require("os"), 1);
1004
+ var import_node_child_process = require("child_process");
1005
+ var import_package_json = __toESM(require("@npmcli/package-json"), 1);
1006
+ var semver = __toESM(require("semver"), 1);
1007
+ var import_js_toml = require("js-toml");
1008
+ var import_extensibility_tool_utils3 = require("@stripe/extensibility-tool-utils");
1009
+ function _npmDep(name, version) {
1010
+ return { type: "npm", name, version };
1011
+ }
1012
+ function _devNpmDep(name, version) {
1013
+ return { type: "dev-npm", name, version };
1014
+ }
1015
+
1016
+ // src/templates/extensions/base.ts
1017
+ var import_extensibility_tool_utils4 = require("@stripe/extensibility-tool-utils");
1018
+ var SDK_PACKAGE_NAME = "@stripe/extensibility-sdk";
1019
+ var LANGUAGE_SERVER_PACKAGE_NAME = "@stripe/extensibility-language-server";
1020
+ var LANGUAGE_SERVER_PACKAGE_VERSION = "^0.2.0";
1021
+ function _createExtensionEslintConfigFile(params, context) {
1022
+ const { id, extensionInterfaceId } = params;
1023
+ const { fs: fs2 } = context;
1024
+ return {
1025
+ path: `extensions/${id}/eslint.config.mts`,
1026
+ content: fs2.mustache(
1027
+ { extensionInterfaceId },
1028
+ "common",
1029
+ "eslint.config.mts.mustache"
1030
+ ),
1031
+ precious: true
1032
+ };
1033
+ }
1034
+ function _createBaseOutput(params, context) {
1035
+ const { id } = params;
1036
+ const { fs: fs2 } = context;
1037
+ return {
1038
+ files: [
1039
+ {
1040
+ path: `extensions/${id}/package.json`,
1041
+ content: fs2.mustache(params, "common", "package.json.mustache")
1042
+ },
1043
+ {
1044
+ ..._createExtensionEslintConfigFile(params, context)
1045
+ },
1046
+ {
1047
+ path: `extensions/${id}/tsconfig.build.json`,
1048
+ content: fs2.mustache(params, "common", "tsconfig.build.json.mustache")
1049
+ },
1050
+ {
1051
+ path: `extensions/${id}/tsconfig.json`,
1052
+ content: fs2.mustache(params, "common", "tsconfig.json.mustache")
1053
+ },
1054
+ {
1055
+ path: `extensions/${id}/.prettierignore`,
1056
+ content: fs2.textFile("common", ".prettierignore")
1057
+ }
1058
+ ],
1059
+ methods: {},
1060
+ dependencies: {
1061
+ // Exact pin (no caret) — the SDK is tightly coupled to dev-tools and
1062
+ // must match the version that generated the extension scaffolding.
1063
+ runtime: [_npmDep(SDK_PACKAGE_NAME, (0, import_extensibility_tool_utils4._workspaceVersion)(SDK_PACKAGE_NAME))],
1064
+ dev: [_devNpmDep(LANGUAGE_SERVER_PACKAGE_NAME, LANGUAGE_SERVER_PACKAGE_VERSION)]
1065
+ },
1066
+ postGenerationHooks: [
1067
+ {
1068
+ script: "build",
1069
+ description: "Build extension"
1070
+ },
1071
+ {
1072
+ exec: "prettier --write .",
1073
+ description: "Format generated files"
1074
+ }
1075
+ ]
1076
+ };
1077
+ }
1078
+
1079
+ // src/templates/extensions/core.workflows.custom_action.ts
1080
+ var EXTENSION_INTERFACE_ID = "core.workflows.custom_action";
1081
+ var customActionTemplate = {
1082
+ methods: {
1083
+ execute: { implementation_types: ["script", "remote-function"] },
1084
+ get_form_state: { implementation_types: ["script", "remote-function"] }
1085
+ },
1086
+ description: "Custom actions let your app define actions that users can add to their automated workflows. When a workflow triggers a custom action, Stripe calls your app to execute it.",
1087
+ generate: (params, context) => {
1088
+ const { id } = params;
1089
+ const { fs: fs2 } = context;
1090
+ const base = _createBaseOutput(
1091
+ {
1092
+ ...params,
1093
+ extensionInterfaceId: EXTENSION_INTERFACE_ID,
1094
+ executionProfile: "egress"
1095
+ },
1096
+ context
1097
+ );
1098
+ return {
1099
+ ...base,
1100
+ files: [
1101
+ {
1102
+ path: `extensions/${id}/src/index.ts`,
1103
+ content: fs2.textFile(EXTENSION_INTERFACE_ID, "index.ts"),
1104
+ precious: true
1105
+ },
1106
+ {
1107
+ path: `extensions/${id}/src/custom_input.schema.json`,
1108
+ content: fs2.textFile(EXTENSION_INTERFACE_ID, "custom_input.schema.json"),
1109
+ precious: true
1110
+ },
1111
+ {
1112
+ path: `extensions/${id}/src/index.test.ts`,
1113
+ content: fs2.textFile(EXTENSION_INTERFACE_ID, "index.test.ts"),
1114
+ precious: true
1115
+ },
1116
+ ...base.files
1117
+ ],
1118
+ methods: {
1119
+ execute: {
1120
+ implementation_type: "script",
1121
+ custom_input: {
1122
+ input_schema: {
1123
+ type: "json_schema",
1124
+ content: `extensions/${id}/src/custom_input.schema.json`
1125
+ }
1126
+ }
1127
+ },
1128
+ get_form_state: {
1129
+ implementation_type: "script"
1130
+ }
1131
+ }
1132
+ };
1133
+ }
1134
+ };
1135
+ var core_workflows_custom_action_default = {
1136
+ [EXTENSION_INTERFACE_ID]: customActionTemplate
1137
+ };
1138
+
1139
+ // src/templates/extensions/extend.objects.custom_objects.ts
1140
+ var EXTENSION_INTERFACE_ID2 = "extend.objects.custom_objects";
1141
+ var customObjectsTemplate = {
1142
+ methods: {
1143
+ execute_method: { implementation_types: ["script"] }
1144
+ },
1145
+ description: "Methods extension for custom object actions. Generated at build time \u2014 the transformed custom object class becomes the entry point.",
1146
+ hidden: true,
1147
+ generate: (params, context) => {
1148
+ const base = _createBaseOutput(
1149
+ {
1150
+ ...params,
1151
+ extensionInterfaceId: EXTENSION_INTERFACE_ID2,
1152
+ executionProfile: "egress"
1153
+ },
1154
+ context
1155
+ );
1156
+ return {
1157
+ ...base,
1158
+ methods: {
1159
+ execute_method: {
1160
+ implementation_type: "script"
1161
+ }
1162
+ }
1163
+ };
1164
+ }
1165
+ };
1166
+ var extend_objects_custom_objects_default = {
1167
+ [EXTENSION_INTERFACE_ID2]: customObjectsTemplate
1168
+ };
1169
+
1170
+ // src/templates/extensions/extend.workflows.custom_action.ts
1171
+ var EXTENSION_INTERFACE_ID3 = "extend.workflows.custom_action";
1172
+ var extendCustomActionTemplate = {
1173
+ methods: {
1174
+ execute: { implementation_types: ["script", "remote-function"] },
1175
+ get_form_state: { implementation_types: ["script", "remote-function"] }
1176
+ },
1177
+ description: "Custom actions let your app define actions that users can add to their automated workflows. When a workflow triggers a custom action, Stripe calls your app to execute it.",
1178
+ generate: (params, context) => {
1179
+ const { id } = params;
1180
+ const { fs: fs2 } = context;
1181
+ const base = _createBaseOutput(
1182
+ {
1183
+ ...params,
1184
+ extensionInterfaceId: EXTENSION_INTERFACE_ID3,
1185
+ executionProfile: "egress"
1186
+ },
1187
+ context
1188
+ );
1189
+ return {
1190
+ ...base,
1191
+ files: [
1192
+ {
1193
+ path: `extensions/${id}/src/index.ts`,
1194
+ content: fs2.textFile(EXTENSION_INTERFACE_ID3, "index.ts"),
1195
+ precious: true
1196
+ },
1197
+ {
1198
+ path: `extensions/${id}/src/custom_input.schema.json`,
1199
+ content: fs2.textFile(EXTENSION_INTERFACE_ID3, "custom_input.schema.json"),
1200
+ precious: true
1201
+ },
1202
+ {
1203
+ path: `extensions/${id}/src/index.test.ts`,
1204
+ content: fs2.textFile(EXTENSION_INTERFACE_ID3, "index.test.ts"),
1205
+ precious: true
1206
+ },
1207
+ ...base.files
1208
+ ],
1209
+ methods: {
1210
+ execute: {
1211
+ implementation_type: "script",
1212
+ custom_input: {
1213
+ input_schema: {
1214
+ type: "json_schema",
1215
+ content: `extensions/${id}/src/custom_input.schema.json`
1216
+ }
1217
+ }
1218
+ },
1219
+ get_form_state: {
1220
+ implementation_type: "script"
1221
+ }
1222
+ }
1223
+ };
1224
+ }
1225
+ };
1226
+ var extend_workflows_custom_action_default = {
1227
+ [EXTENSION_INTERFACE_ID3]: extendCustomActionTemplate
1228
+ };
1229
+
1230
+ // src/templates/extensions/billing.customer_balance_application.ts
1231
+ var EXTENSION_INTERFACE_ID4 = "billing.customer_balance_application";
1232
+ var customerBalanceApplicationTemplate = {
1233
+ methods: {
1234
+ compute_applied_customer_balance: { implementation_types: ["script"] }
1235
+ },
1236
+ description: "Implement custom logic to control when and how much customer balance is applied to subscription invoices using scripts.",
1237
+ generate: (params, context) => {
1238
+ const { id } = params;
1239
+ const { fs: fs2 } = context;
1240
+ const base = _createBaseOutput(
1241
+ {
1242
+ ...params,
1243
+ extensionInterfaceId: EXTENSION_INTERFACE_ID4,
1244
+ executionProfile: "restricted"
1245
+ },
1246
+ context
1247
+ );
1248
+ return {
1249
+ ...base,
1250
+ files: [
1251
+ {
1252
+ path: `extensions/${id}/src/index.ts`,
1253
+ content: fs2.textFile(EXTENSION_INTERFACE_ID4, "index.ts"),
1254
+ precious: true
1255
+ },
1256
+ {
1257
+ path: `extensions/${id}/src/index.test.ts`,
1258
+ content: fs2.textFile(EXTENSION_INTERFACE_ID4, "index.test.ts"),
1259
+ precious: true
1260
+ },
1261
+ ...base.files
1262
+ ],
1263
+ methods: {
1264
+ compute_applied_customer_balance: {
1265
+ implementation_type: "script"
1266
+ }
1267
+ }
1268
+ };
1269
+ }
1270
+ };
1271
+ var billing_customer_balance_application_default = {
1272
+ [EXTENSION_INTERFACE_ID4]: customerBalanceApplicationTemplate
1273
+ };
1274
+
1275
+ // src/templates/extensions/billing.bill.discount_calculation.ts
1276
+ var EXTENSION_INTERFACE_ID5 = "billing.bill.discount_calculation";
1277
+ var discountCalculationTemplate = {
1278
+ hidden: true,
1279
+ methods: {
1280
+ compute_discounts: { implementation_types: ["script"] }
1281
+ },
1282
+ description: "Create coupons with custom scripting logic for dynamic discounts based on subscription attributes, customer metadata, and complex business rules.",
1283
+ generate: (params, context) => {
1284
+ const { id } = params;
1285
+ const { fs: fs2 } = context;
1286
+ const base = _createBaseOutput(
1287
+ {
1288
+ ...params,
1289
+ extensionInterfaceId: EXTENSION_INTERFACE_ID5,
1290
+ executionProfile: "restricted"
1291
+ },
1292
+ context
1293
+ );
1294
+ return {
1295
+ ...base,
1296
+ files: [
1297
+ {
1298
+ path: `extensions/${id}/src/index.ts`,
1299
+ content: fs2.textFile(EXTENSION_INTERFACE_ID5, "index.ts"),
1300
+ precious: true
1301
+ },
1302
+ {
1303
+ path: `extensions/${id}/src/index.test.ts`,
1304
+ content: fs2.textFile(EXTENSION_INTERFACE_ID5, "index.test.ts"),
1305
+ precious: true
1306
+ },
1307
+ ...base.files
1308
+ ],
1309
+ methods: {
1310
+ compute_discounts: {
1311
+ implementation_type: "script"
1312
+ }
1313
+ }
1314
+ };
1315
+ }
1316
+ };
1317
+ var billing_bill_discount_calculation_default = {
1318
+ [EXTENSION_INTERFACE_ID5]: discountCalculationTemplate
1319
+ };
1320
+
1321
+ // src/templates/extensions/billing.invoice_collection_setting.ts
1322
+ var EXTENSION_INTERFACE_ID6 = "billing.invoice_collection_setting";
1323
+ var invoiceCollectionSettingTemplate = {
1324
+ hidden: true,
1325
+ methods: {
1326
+ collection_override: { implementation_types: ["script"] }
1327
+ },
1328
+ description: "Use Stripe Scripts to create custom invoice collection logic that controls how your integration handles invoices generated from subscriptions.",
1329
+ generate: (params, context) => {
1330
+ const { id } = params;
1331
+ const { fs: fs2 } = context;
1332
+ const base = _createBaseOutput(
1333
+ {
1334
+ ...params,
1335
+ extensionInterfaceId: EXTENSION_INTERFACE_ID6,
1336
+ executionProfile: "restricted"
1337
+ },
1338
+ context
1339
+ );
1340
+ return {
1341
+ ...base,
1342
+ files: [
1343
+ {
1344
+ path: `extensions/${id}/src/index.ts`,
1345
+ content: fs2.textFile(EXTENSION_INTERFACE_ID6, "index.ts"),
1346
+ precious: true
1347
+ },
1348
+ {
1349
+ path: `extensions/${id}/src/index.test.ts`,
1350
+ content: fs2.textFile(EXTENSION_INTERFACE_ID6, "index.test.ts"),
1351
+ precious: true
1352
+ },
1353
+ ...base.files
1354
+ ],
1355
+ methods: {
1356
+ collection_override: {
1357
+ implementation_type: "script"
1358
+ }
1359
+ }
1360
+ };
1361
+ }
1362
+ };
1363
+ var billing_invoice_collection_setting_default = {
1364
+ [EXTENSION_INTERFACE_ID6]: invoiceCollectionSettingTemplate
1365
+ };
1366
+
1367
+ // src/templates/extensions/billing.prorations.ts
1368
+ var EXTENSION_INTERFACE_ID7 = "billing.prorations";
1369
+ var prorationsTemplate = {
1370
+ methods: {
1371
+ prorate_items: { implementation_types: ["script"] }
1372
+ },
1373
+ description: "Create custom proration logic for subscriptions using scripts to handle upgrades, downgrades, and mid-cycle changes.",
1374
+ generate: (params, context) => {
1375
+ const { id } = params;
1376
+ const { fs: fs2 } = context;
1377
+ const base = _createBaseOutput(
1378
+ {
1379
+ ...params,
1380
+ extensionInterfaceId: EXTENSION_INTERFACE_ID7,
1381
+ executionProfile: "restricted"
1382
+ },
1383
+ context
1384
+ );
1385
+ return {
1386
+ ...base,
1387
+ files: [
1388
+ {
1389
+ path: `extensions/${id}/src/index.ts`,
1390
+ content: fs2.textFile(EXTENSION_INTERFACE_ID7, "index.ts"),
1391
+ precious: true
1392
+ },
1393
+ {
1394
+ path: `extensions/${id}/src/index.test.ts`,
1395
+ content: fs2.textFile(EXTENSION_INTERFACE_ID7, "index.test.ts"),
1396
+ precious: true
1397
+ },
1398
+ ...base.files
1399
+ ],
1400
+ methods: {
1401
+ prorate_items: {
1402
+ implementation_type: "script"
1403
+ }
1404
+ }
1405
+ };
1406
+ }
1407
+ };
1408
+ var billing_prorations_default = {
1409
+ [EXTENSION_INTERFACE_ID7]: prorationsTemplate
1410
+ };
1411
+
1412
+ // src/templates/extensions/billing.recurring_billing_item_handling.ts
1413
+ var EXTENSION_INTERFACE_ID8 = "billing.recurring_billing_item_handling";
1414
+ var template = {
1415
+ methods: {
1416
+ before_item_creation: { implementation_types: ["script"] },
1417
+ filter_items: { implementation_types: ["script"] },
1418
+ group_items: { implementation_types: ["script"] }
1419
+ },
1420
+ description: "Customize how recurring billing items are filtered, grouped, and created during subscription billing runs.",
1421
+ generate: (params, context) => {
1422
+ const { id } = params;
1423
+ const { fs: fs2 } = context;
1424
+ const base = _createBaseOutput(
1425
+ {
1426
+ ...params,
1427
+ extensionInterfaceId: EXTENSION_INTERFACE_ID8,
1428
+ executionProfile: "restricted"
1429
+ },
1430
+ context
1431
+ );
1432
+ return {
1433
+ ...base,
1434
+ files: [
1435
+ {
1436
+ path: `extensions/${id}/src/index.ts`,
1437
+ content: fs2.textFile(EXTENSION_INTERFACE_ID8, "index.ts"),
1438
+ precious: true
1439
+ },
1440
+ {
1441
+ path: `extensions/${id}/src/index.test.ts`,
1442
+ content: fs2.textFile(EXTENSION_INTERFACE_ID8, "index.test.ts"),
1443
+ precious: true
1444
+ },
1445
+ ...base.files
1446
+ ],
1447
+ methods: {
1448
+ before_item_creation: {
1449
+ implementation_type: "script"
1450
+ },
1451
+ filter_items: {
1452
+ implementation_type: "script"
1453
+ },
1454
+ group_items: {
1455
+ implementation_type: "script"
1456
+ }
1457
+ }
1458
+ };
1459
+ }
1460
+ };
1461
+ var billing_recurring_billing_item_handling_default = {
1462
+ [EXTENSION_INTERFACE_ID8]: template
1463
+ };
1464
+
1465
+ // src/templates/extensions/registry.ts
1466
+ var DEFAULT_TEMPLATES = {
1467
+ ...core_workflows_custom_action_default,
1468
+ ...extend_objects_custom_objects_default,
1469
+ ...extend_workflows_custom_action_default,
1470
+ ...billing_customer_balance_application_default,
1471
+ ...billing_bill_discount_calculation_default,
1472
+ ...billing_invoice_collection_setting_default,
1473
+ ...billing_prorations_default,
1474
+ ...billing_recurring_billing_item_handling_default
1475
+ };
1476
+ var registry_default = DEFAULT_TEMPLATES;
1477
+
1478
+ // src/templates/extensions/index.ts
1479
+ var _templateManager = new _ExtensionTemplateManager(
1480
+ registry_default,
1481
+ _fs.scope("extensions")
1482
+ );
1483
+
1484
+ // src/bin/template-info.ts
1485
+ var logger = (0, import_extensibility_tool_utils5._createLogger)({ name: "template-info" });
1486
+ async function main() {
1487
+ await (0, import_yargs.default)((0, import_helpers.hideBin)(process.argv)).usage("Show available extension templates").help().version(false).command(
1488
+ "$0",
1489
+ "List available extension templates",
1490
+ (y) => y.option("output-path", {
1491
+ type: "string",
1492
+ description: "Write JSON result to this file instead of stdout"
1493
+ }),
1494
+ (args) => {
1495
+ const templates = _templateManager.getTemplateInfo().filter((t) => !t.hidden);
1496
+ if (args.outputPath) {
1497
+ (0, import_extensibility_tool_utils5._writeJsonOutput)(args.outputPath, templates);
1498
+ } else {
1499
+ for (const t of templates) {
1500
+ const suffix = t.deprecated ? " (deprecated)" : "";
1501
+ process.stdout.write(` ${t.key} \u2014 ${t.description}${suffix}
1502
+ `);
1503
+ }
1504
+ }
1505
+ }
1506
+ ).parse();
1507
+ }
1508
+ main().catch((err) => {
1509
+ logger.error({ err }, "Unexpected error");
1510
+ process.exit(1);
1511
+ });