@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.
- package/LICENSE.md +19 -0
- package/dist/bin/build-custom-object-definitions.cjs +2111 -0
- package/dist/bin/build-custom-object-definitions.d.ts +11 -0
- package/dist/bin/build-custom-object-definitions.d.ts.map +1 -0
- package/dist/bin/build-custom-object-definitions.js +2088 -0
- package/dist/bin/create-upload-image.cjs +2136 -0
- package/dist/bin/create-upload-image.d.ts +17 -0
- package/dist/bin/create-upload-image.d.ts.map +1 -0
- package/dist/bin/create-upload-image.js +2113 -0
- package/dist/bin/dev-tools-rpc.cjs +3874 -0
- package/dist/bin/dev-tools-rpc.d.ts +3 -0
- package/dist/bin/dev-tools-rpc.d.ts.map +1 -0
- package/dist/bin/dev-tools-rpc.js +3864 -0
- package/dist/bin/gen-schemas.cjs +20739 -0
- package/dist/bin/gen-schemas.d.ts +8 -0
- package/dist/bin/gen-schemas.d.ts.map +1 -0
- package/dist/bin/gen-schemas.js +20715 -0
- package/dist/bin/gen-workspace.cjs +3847 -0
- package/dist/bin/gen-workspace.d.ts +8 -0
- package/dist/bin/gen-workspace.d.ts.map +1 -0
- package/dist/bin/gen-workspace.js +3841 -0
- package/dist/bin/manifest.cjs +686 -0
- package/dist/bin/manifest.d.ts +10 -0
- package/dist/bin/manifest.d.ts.map +1 -0
- package/dist/bin/manifest.js +663 -0
- package/dist/bin/rpc/dispatch.d.ts +10 -0
- package/dist/bin/rpc/dispatch.d.ts.map +1 -0
- package/dist/bin/rpc/handlers.d.ts +4 -0
- package/dist/bin/rpc/handlers.d.ts.map +1 -0
- package/dist/bin/rpc/types.d.ts +29 -0
- package/dist/bin/rpc/types.d.ts.map +1 -0
- package/dist/bin/template-info.cjs +1511 -0
- package/dist/bin/template-info.d.ts +9 -0
- package/dist/bin/template-info.d.ts.map +1 -0
- package/dist/bin/template-info.js +1488 -0
- package/dist/custom-objects/build-definitions.d.ts +98 -0
- package/dist/custom-objects/build-definitions.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts +191 -0
- package/dist/custom-objects/generated/proto/custom_objects/pub/api/app_api/object_definitions_app_service.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/custom_objects/pub/api/common/schema.pb.d.ts +131 -0
- package/dist/custom-objects/generated/proto/custom_objects/pub/api/common/schema.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts +1482 -0
- package/dist/custom-objects/generated/proto/google/protobuf/descriptor.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/google/protobuf/timestamp.pb.d.ts +167 -0
- package/dist/custom-objects/generated/proto/google/protobuf/timestamp.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/proto/annotations.pb.d.ts +64 -0
- package/dist/custom-objects/generated/proto/proto/annotations.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts +657 -0
- package/dist/custom-objects/generated/proto/proto/extensions.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/metadata/pub/api/api_metadata.pb.d.ts +105 -0
- package/dist/custom-objects/generated/proto/vendor/metadata/pub/api/api_metadata.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/net/idempotency/idempotency_model.pb.d.ts +79 -0
- package/dist/custom-objects/generated/proto/vendor/net/idempotency/idempotency_model.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts +129 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/api_group_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/api_visibility.pb.d.ts +76 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/api_visibility.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/customize_dispatch_middleware_enum.pb.d.ts +78 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/customize_dispatch_middleware_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/docs_namespace_group_enum.pb.d.ts +146 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/docs_namespace_group_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/documented_enum.pb.d.ts +76 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/documented_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/event_scope_enum.pb.d.ts +92 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/event_scope_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts +124 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/extension_interface.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts +1070 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/feature_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/field_validation_rules.pb.d.ts +279 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/field_validation_rules.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/flavor_enum.pb.d.ts +78 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/flavor_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts +102 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/http_error_status.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/method_kind_enum.pb.d.ts +86 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/method_kind_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/method_priority.pb.d.ts +80 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/method_priority.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/permission_check_enum.pb.d.ts +74 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/permission_check_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/redaction_enum.pb.d.ts +76 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/redaction_enum.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/region_routers.pb.d.ts +103 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/region_routers.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts +153 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/rollout_configs.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts +1111 -0
- package/dist/custom-objects/generated/proto/vendor/publicapi/v2ext.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/vext/annotations.pb.d.ts +602 -0
- package/dist/custom-objects/generated/proto/vendor/vext/annotations.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/vext/extensions.pb.d.ts +144 -0
- package/dist/custom-objects/generated/proto/vendor/vext/extensions.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts +851 -0
- package/dist/custom-objects/generated/proto/vendor/vext/privacy_unified_annotations.pb.d.ts.map +1 -0
- package/dist/custom-objects/generated/proto/vendor/vext/xml_annotations.pb.d.ts +125 -0
- package/dist/custom-objects/generated/proto/vendor/vext/xml_annotations.pb.d.ts.map +1 -0
- package/dist/custom-objects/to-proto-json.d.ts +17 -0
- package/dist/custom-objects/to-proto-json.d.ts.map +1 -0
- package/dist/dependencies/index.cjs +601 -0
- package/dist/dependencies/index.d.ts +320 -0
- package/dist/dependencies/index.d.ts.map +1 -0
- package/dist/dependencies/index.js +560 -0
- package/dist/extensibility-dev-tools-alpha.d.ts +199 -0
- package/dist/extensibility-dev-tools-beta.d.ts +199 -0
- package/dist/extensibility-dev-tools-dependencies-alpha.d.ts +51 -0
- package/dist/extensibility-dev-tools-dependencies-beta.d.ts +51 -0
- package/dist/extensibility-dev-tools-dependencies-internal.d.ts +372 -0
- package/dist/extensibility-dev-tools-dependencies-public.d.ts +51 -0
- package/dist/extensibility-dev-tools-internal.d.ts +1722 -0
- package/dist/extensibility-dev-tools-jsonschema-tools-alpha.d.ts +57 -0
- package/dist/extensibility-dev-tools-jsonschema-tools-beta.d.ts +57 -0
- package/dist/extensibility-dev-tools-jsonschema-tools-internal.d.ts +123 -0
- package/dist/extensibility-dev-tools-jsonschema-tools-public.d.ts +57 -0
- package/dist/extensibility-dev-tools-manifest-alpha.d.ts +31 -0
- package/dist/extensibility-dev-tools-manifest-beta.d.ts +31 -0
- package/dist/extensibility-dev-tools-manifest-internal.d.ts +461 -0
- package/dist/extensibility-dev-tools-manifest-public.d.ts +31 -0
- package/dist/extensibility-dev-tools-public.d.ts +199 -0
- package/dist/extensibility-dev-tools-schemas-alpha.d.ts +9 -0
- package/dist/extensibility-dev-tools-schemas-beta.d.ts +9 -0
- package/dist/extensibility-dev-tools-schemas-internal.d.ts +41 -0
- package/dist/extensibility-dev-tools-schemas-public.d.ts +9 -0
- package/dist/extensibility-dev-tools-templates-alpha.d.ts +67 -0
- package/dist/extensibility-dev-tools-templates-beta.d.ts +67 -0
- package/dist/extensibility-dev-tools-templates-internal.d.ts +554 -0
- package/dist/extensibility-dev-tools-templates-public.d.ts +67 -0
- package/dist/extensibility-dev-tools-workspace-alpha.d.ts +51 -0
- package/dist/extensibility-dev-tools-workspace-beta.d.ts +51 -0
- package/dist/extensibility-dev-tools-workspace-internal.d.ts +410 -0
- package/dist/extensibility-dev-tools-workspace-public.d.ts +51 -0
- package/dist/index.cjs +3810 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3758 -0
- package/dist/jsonschema-tools.cjs +20451 -0
- package/dist/jsonschema-tools.d.ts +98 -0
- package/dist/jsonschema-tools.d.ts.map +1 -0
- package/dist/jsonschema-tools.js +20404 -0
- package/dist/manifest/index.cjs +610 -0
- package/dist/manifest/index.d.ts +8 -0
- package/dist/manifest/index.d.ts.map +1 -0
- package/dist/manifest/index.js +571 -0
- package/dist/manifest/manifest-v1.d.ts +102 -0
- package/dist/manifest/manifest-v1.d.ts.map +1 -0
- package/dist/manifest/manifest-v2.d.ts +253 -0
- package/dist/manifest/manifest-v2.d.ts.map +1 -0
- package/dist/manifest/stripe-app-manifest.d.ts +114 -0
- package/dist/manifest/stripe-app-manifest.d.ts.map +1 -0
- package/dist/schemas/index.cjs +20692 -0
- package/dist/schemas/index.d.ts +37 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +20656 -0
- package/dist/templates/diff-viewer/diff-generator.d.ts +22 -0
- package/dist/templates/diff-viewer/diff-generator.d.ts.map +1 -0
- package/dist/templates/diff-viewer/diff-prompt.d.ts +13 -0
- package/dist/templates/diff-viewer/diff-prompt.d.ts.map +1 -0
- package/dist/templates/diff-viewer/index.d.ts +7 -0
- package/dist/templates/diff-viewer/index.d.ts.map +1 -0
- package/dist/templates/diff-viewer/terminal-renderer.d.ts +29 -0
- package/dist/templates/diff-viewer/terminal-renderer.d.ts.map +1 -0
- package/dist/templates/diff-viewer/types.d.ts +58 -0
- package/dist/templates/diff-viewer/types.d.ts.map +1 -0
- package/dist/templates/extensions/base.d.ts +23 -0
- package/dist/templates/extensions/base.d.ts.map +1 -0
- package/dist/templates/extensions/billing.bill.discount_calculation.d.ts +6 -0
- package/dist/templates/extensions/billing.bill.discount_calculation.d.ts.map +1 -0
- package/dist/templates/extensions/billing.customer_balance_application.d.ts +6 -0
- package/dist/templates/extensions/billing.customer_balance_application.d.ts.map +1 -0
- package/dist/templates/extensions/billing.invoice_collection_setting.d.ts +6 -0
- package/dist/templates/extensions/billing.invoice_collection_setting.d.ts.map +1 -0
- package/dist/templates/extensions/billing.prorations.d.ts +6 -0
- package/dist/templates/extensions/billing.prorations.d.ts.map +1 -0
- package/dist/templates/extensions/billing.recurring_billing_item_handling.d.ts +6 -0
- package/dist/templates/extensions/billing.recurring_billing_item_handling.d.ts.map +1 -0
- package/dist/templates/extensions/core.workflows.custom_action.d.ts +6 -0
- package/dist/templates/extensions/core.workflows.custom_action.d.ts.map +1 -0
- package/dist/templates/extensions/extend.objects.custom_objects.d.ts +6 -0
- package/dist/templates/extensions/extend.objects.custom_objects.d.ts.map +1 -0
- package/dist/templates/extensions/extend.workflows.custom_action.d.ts +6 -0
- package/dist/templates/extensions/extend.workflows.custom_action.d.ts.map +1 -0
- package/dist/templates/extensions/index.d.ts +13 -0
- package/dist/templates/extensions/index.d.ts.map +1 -0
- package/dist/templates/extensions/registry.d.ts +10 -0
- package/dist/templates/extensions/registry.d.ts.map +1 -0
- package/dist/templates/extensions/types.d.ts +104 -0
- package/dist/templates/extensions/types.d.ts.map +1 -0
- package/dist/templates/file-writer.d.ts +140 -0
- package/dist/templates/file-writer.d.ts.map +1 -0
- package/dist/templates/fs/_impl.d.ts +29 -0
- package/dist/templates/fs/_impl.d.ts.map +1 -0
- package/dist/templates/fs/filesystem.d.ts +8 -0
- package/dist/templates/fs/filesystem.d.ts.map +1 -0
- package/dist/templates/fs/in-memory.d.ts +9 -0
- package/dist/templates/fs/in-memory.d.ts.map +1 -0
- package/dist/templates/fs/index.d.ts +25 -0
- package/dist/templates/fs/index.d.ts.map +1 -0
- package/dist/templates/fs-utils.d.ts +17 -0
- package/dist/templates/fs-utils.d.ts.map +1 -0
- package/dist/templates/index.cjs +2248 -0
- package/dist/templates/index.d.ts +32 -0
- package/dist/templates/index.d.ts.map +1 -0
- package/dist/templates/index.js +2203 -0
- package/dist/templates/root/index.d.ts +60 -0
- package/dist/templates/root/index.d.ts.map +1 -0
- package/dist/templates/simple-templates.d.ts +8 -0
- package/dist/templates/simple-templates.d.ts.map +1 -0
- package/dist/templates/template-manager.d.ts +8 -0
- package/dist/templates/template-manager.d.ts.map +1 -0
- package/dist/templates/types.d.ts +9 -0
- package/dist/templates/types.d.ts.map +1 -0
- package/dist/tsconfig.build.tsbuildinfo +1 -0
- package/dist/workspace/index.cjs +3756 -0
- package/dist/workspace/index.d.ts +336 -0
- package/dist/workspace/index.d.ts.map +1 -0
- package/dist/workspace/index.js +3731 -0
- package/package.json +137 -0
- package/templates/extensions/billing.bill.discount_calculation/index.test.ts +15 -0
- package/templates/extensions/billing.bill.discount_calculation/index.ts +20 -0
- package/templates/extensions/billing.customer_balance_application/index.test.ts +15 -0
- package/templates/extensions/billing.customer_balance_application/index.ts +18 -0
- package/templates/extensions/billing.invoice_collection_setting/index.test.ts +15 -0
- package/templates/extensions/billing.invoice_collection_setting/index.ts +16 -0
- package/templates/extensions/billing.prorations/index.test.ts +15 -0
- package/templates/extensions/billing.prorations/index.ts +18 -0
- package/templates/extensions/billing.recurring_billing_item_handling/index.test.ts +15 -0
- package/templates/extensions/billing.recurring_billing_item_handling/index.ts +42 -0
- package/templates/extensions/common/.prettierignore +3 -0
- package/templates/extensions/common/eslint.config.mts.mustache +95 -0
- package/templates/extensions/common/package.json.mustache +26 -0
- package/templates/extensions/common/tsconfig.build.json.mustache +15 -0
- package/templates/extensions/common/tsconfig.json.mustache +16 -0
- package/templates/extensions/core.workflows.custom_action/custom_input.schema.json +6 -0
- package/templates/extensions/core.workflows.custom_action/index.test.ts +15 -0
- package/templates/extensions/core.workflows.custom_action/index.ts +31 -0
- package/templates/extensions/extend.workflows.custom_action/custom_input.schema.json +6 -0
- package/templates/extensions/extend.workflows.custom_action/index.test.ts +15 -0
- package/templates/extensions/extend.workflows.custom_action/index.ts +31 -0
- package/templates/root/.husky/pre-commit +1 -0
- package/templates/root/.prettierignore +5 -0
- package/templates/root/.prettierrc +7 -0
- package/templates/root/_gitignore +28 -0
- package/templates/root/custom-objects/package.json +20 -0
- package/templates/root/custom-objects/tsconfig.json +9 -0
- package/templates/root/eslint.config.mts +95 -0
- package/templates/root/package.json.mustache +32 -0
- package/templates/root/pnpm-workspace.yaml +7 -0
- package/templates/root/stripe-app.yaml.mustache +6 -0
- package/templates/root/tools/test.mts +38 -0
- package/templates/root/tsconfig.base.json +23 -0
- package/templates/root/tsconfig.json +15 -0
- package/templates/root/ui/package.json +17 -0
- package/templates/root/vitest.config.mts +47 -0
|
@@ -0,0 +1,571 @@
|
|
|
1
|
+
// src/manifest/stripe-app-manifest.ts
|
|
2
|
+
import { _toSnakeCase } from "@stripe/extensibility-tool-utils";
|
|
3
|
+
|
|
4
|
+
// src/manifest/manifest-v1.ts
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
6
|
+
function formatCustomObjectEntry(entry) {
|
|
7
|
+
return `${entry.filePath}#${entry.className}`;
|
|
8
|
+
}
|
|
9
|
+
function parseCustomObjectEntry(entryString) {
|
|
10
|
+
const parts = entryString.split("#");
|
|
11
|
+
if (parts.length !== 2) {
|
|
12
|
+
throw new Error(
|
|
13
|
+
`Invalid object entry format: ${entryString}. Expected format: "path/to/file.d.ts#ClassName"`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
const [filePath, className] = parts;
|
|
17
|
+
if (!filePath || !className) {
|
|
18
|
+
throw new Error(
|
|
19
|
+
`Invalid object entry format: ${entryString}. Expected format: "path/to/file.d.ts#ClassName"`
|
|
20
|
+
);
|
|
21
|
+
}
|
|
22
|
+
return { filePath, className };
|
|
23
|
+
}
|
|
24
|
+
var _ManifestV1 = class __ManifestV1 {
|
|
25
|
+
constructor(filePath, data) {
|
|
26
|
+
this.filePath = filePath;
|
|
27
|
+
this.data = data;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Load stripe-app.json from disk
|
|
31
|
+
* @param filePath - Path to stripe-app.json
|
|
32
|
+
* @throws Error if file is invalid or cannot be read
|
|
33
|
+
*/
|
|
34
|
+
static load(filePath) {
|
|
35
|
+
if (!existsSync(filePath)) {
|
|
36
|
+
throw new Error(`Manifest file not found: ${filePath}`);
|
|
37
|
+
}
|
|
38
|
+
const content = readFileSync(filePath, "utf-8");
|
|
39
|
+
const data = JSON.parse(content);
|
|
40
|
+
if (!data.id) {
|
|
41
|
+
throw new Error('Manifest must contain "id" field');
|
|
42
|
+
}
|
|
43
|
+
return new __ManifestV1(filePath, data);
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Get the app ID from the manifest
|
|
47
|
+
*/
|
|
48
|
+
getAppId() {
|
|
49
|
+
return this.data.id;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the app name from the manifest
|
|
53
|
+
*/
|
|
54
|
+
getAppName() {
|
|
55
|
+
return this.data.name;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Get all custom objects as structured entries
|
|
59
|
+
*/
|
|
60
|
+
getCustomObjects() {
|
|
61
|
+
const entries = [];
|
|
62
|
+
if (this.data.exported_custom_objects) {
|
|
63
|
+
for (const entry of this.data.exported_custom_objects) {
|
|
64
|
+
entries.push(parseCustomObjectEntry(entry));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return entries;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if a custom object entry exists in the manifest
|
|
71
|
+
*/
|
|
72
|
+
hasCustomObject(entry) {
|
|
73
|
+
const objects = this.getCustomObjects();
|
|
74
|
+
return objects.some(
|
|
75
|
+
(existing) => existing.filePath === entry.filePath && existing.className === entry.className
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Add a custom object entry to the manifest
|
|
80
|
+
* Does nothing if entry already exists
|
|
81
|
+
* @returns true if entry was added, false if it already existed
|
|
82
|
+
*/
|
|
83
|
+
addCustomObject(entry) {
|
|
84
|
+
if (this.hasCustomObject(entry)) {
|
|
85
|
+
return false;
|
|
86
|
+
}
|
|
87
|
+
const entryString = formatCustomObjectEntry(entry);
|
|
88
|
+
this.data.exported_custom_objects ??= [];
|
|
89
|
+
this.data.exported_custom_objects.push(entryString);
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Remove a custom object entry from the manifest
|
|
94
|
+
* @returns true if entry was removed, false if it didn't exist
|
|
95
|
+
*/
|
|
96
|
+
removeCustomObject(entry) {
|
|
97
|
+
if (!this.data.exported_custom_objects) {
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
const entryString = formatCustomObjectEntry(entry);
|
|
101
|
+
const originalLength = this.data.exported_custom_objects.length;
|
|
102
|
+
this.data.exported_custom_objects = this.data.exported_custom_objects.filter(
|
|
103
|
+
(e) => e !== entryString
|
|
104
|
+
);
|
|
105
|
+
if (this.data.exported_custom_objects.length === 0) {
|
|
106
|
+
delete this.data.exported_custom_objects;
|
|
107
|
+
}
|
|
108
|
+
return this.data.exported_custom_objects?.length !== originalLength;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Get the raw manifest data (for reading other fields)
|
|
112
|
+
*/
|
|
113
|
+
getRawData() {
|
|
114
|
+
return this.data;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Save changes back to disk
|
|
118
|
+
*/
|
|
119
|
+
save() {
|
|
120
|
+
writeFileSync(this.filePath, JSON.stringify(this.data, null, 2) + "\n");
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
// src/manifest/manifest-v2.ts
|
|
125
|
+
import { readFile, writeFile } from "fs/promises";
|
|
126
|
+
import * as yaml from "yaml";
|
|
127
|
+
import { _toPascalCase } from "@stripe/extensibility-tool-utils";
|
|
128
|
+
function isNonEmptyString(value) {
|
|
129
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
130
|
+
}
|
|
131
|
+
function isYamlObject(value) {
|
|
132
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
133
|
+
}
|
|
134
|
+
function validateManifestV2Data(data) {
|
|
135
|
+
if (!isNonEmptyString(data.id)) {
|
|
136
|
+
throw new Error('Manifest must contain non-empty "id" field');
|
|
137
|
+
}
|
|
138
|
+
if (!isNonEmptyString(data.name)) {
|
|
139
|
+
throw new Error('Manifest must contain non-empty "name" field');
|
|
140
|
+
}
|
|
141
|
+
if (!isNonEmptyString(data.version)) {
|
|
142
|
+
throw new Error('Manifest must contain non-empty "version" field');
|
|
143
|
+
}
|
|
144
|
+
if ("extensions" in data && !Array.isArray(data.extensions)) {
|
|
145
|
+
throw new Error('Manifest field "extensions" must be an array when provided');
|
|
146
|
+
}
|
|
147
|
+
if ("custom_object_definitions" in data && !isYamlObject(data.custom_object_definitions)) {
|
|
148
|
+
throw new Error(
|
|
149
|
+
'Manifest field "custom_object_definitions" must be an object with a "definitions" array'
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
const coBlock = data.custom_object_definitions;
|
|
153
|
+
const definitions = isYamlObject(coBlock) ? coBlock.definitions : void 0;
|
|
154
|
+
if (!definitions) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
if (!Array.isArray(definitions)) {
|
|
158
|
+
throw new Error(
|
|
159
|
+
'Manifest field "custom_object_definitions.definitions" must be an array'
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
for (let i = 0; i < definitions.length; i++) {
|
|
163
|
+
const def = definitions[i];
|
|
164
|
+
const prefix = `custom_object_definitions.definitions[${String(i)}]`;
|
|
165
|
+
if (!isYamlObject(def) || !isNonEmptyString(def.id)) {
|
|
166
|
+
throw new Error(
|
|
167
|
+
`${prefix}: missing or invalid "id" field. Got: ${JSON.stringify(def)}`
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
if (!isYamlObject(def.specification)) {
|
|
171
|
+
throw new Error(
|
|
172
|
+
`${prefix}: missing or invalid "specification" field. Expected: { type: "typescript", content: "path/to/file.ts" }. Got: ${JSON.stringify(def)}`
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
if (!isNonEmptyString(def.specification.type)) {
|
|
176
|
+
throw new Error(
|
|
177
|
+
`${prefix}: missing or invalid "specification.type" field. Got: ${JSON.stringify(def)}`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
if (!isNonEmptyString(def.specification.content)) {
|
|
181
|
+
throw new Error(
|
|
182
|
+
`${prefix}: missing or invalid "specification.content" field. Got: ${JSON.stringify(def)}`
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
var _ManifestV2 = class __ManifestV2 {
|
|
188
|
+
constructor(filePath, data) {
|
|
189
|
+
this.filePath = filePath;
|
|
190
|
+
this.data = data;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Load stripe-app.yaml from disk
|
|
194
|
+
* @param filePath - Path to stripe-app.yaml
|
|
195
|
+
* @throws Error if file is invalid or cannot be read
|
|
196
|
+
*/
|
|
197
|
+
static async load(filePath) {
|
|
198
|
+
try {
|
|
199
|
+
const content = await readFile(filePath, "utf-8");
|
|
200
|
+
const parsed = yaml.parse(content);
|
|
201
|
+
if (!isYamlObject(parsed)) {
|
|
202
|
+
throw new Error("Invalid stripe-app.yaml format: root must be an object");
|
|
203
|
+
}
|
|
204
|
+
validateManifestV2Data(parsed);
|
|
205
|
+
const data = parsed;
|
|
206
|
+
data.extensions ??= [];
|
|
207
|
+
return new __ManifestV2(filePath, data);
|
|
208
|
+
} catch (err) {
|
|
209
|
+
if (err instanceof Error) {
|
|
210
|
+
throw new Error(`Error reading stripe-app.yaml: ${err.message}`);
|
|
211
|
+
}
|
|
212
|
+
throw new Error(`Error reading stripe-app.yaml: ${String(err)}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Get the app ID from the manifest
|
|
217
|
+
*/
|
|
218
|
+
getAppId() {
|
|
219
|
+
return this.data.id;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Get the app name from the manifest
|
|
223
|
+
*/
|
|
224
|
+
getAppName() {
|
|
225
|
+
return this.data.name;
|
|
226
|
+
}
|
|
227
|
+
// ============================================================
|
|
228
|
+
// Custom Objects
|
|
229
|
+
// ============================================================
|
|
230
|
+
/**
|
|
231
|
+
* Get all custom object definitions, parsed into internal format.
|
|
232
|
+
* Entries are guaranteed structurally valid by load-time validation.
|
|
233
|
+
*/
|
|
234
|
+
getCustomObjects() {
|
|
235
|
+
const definitions = this.data.custom_object_definitions?.definitions;
|
|
236
|
+
if (!definitions || definitions.length === 0) {
|
|
237
|
+
return [];
|
|
238
|
+
}
|
|
239
|
+
return definitions.map((def) => ({
|
|
240
|
+
id: def.id,
|
|
241
|
+
type: def.specification.type,
|
|
242
|
+
path: def.specification.content,
|
|
243
|
+
name: _toPascalCase(def.id)
|
|
244
|
+
}));
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Check if a custom object exists by id
|
|
248
|
+
*/
|
|
249
|
+
hasCustomObject(id) {
|
|
250
|
+
const definitions = this.data.custom_object_definitions?.definitions;
|
|
251
|
+
if (!definitions) return false;
|
|
252
|
+
return definitions.some((def) => def.id === id);
|
|
253
|
+
}
|
|
254
|
+
/**
|
|
255
|
+
* Add a custom object definition.
|
|
256
|
+
*
|
|
257
|
+
* Identity is keyed on `id` alone. The export name is derived via
|
|
258
|
+
* `_toPascalCase(id)` at read time, so `id` should be valid snake_case
|
|
259
|
+
* (e.g., "device", "loyalty_card", "http_request").
|
|
260
|
+
*
|
|
261
|
+
* @param id - Object identifier (e.g., "device", "loyalty_card")
|
|
262
|
+
* @param content - Path to the definition file (e.g., "src/device.object.ts")
|
|
263
|
+
* @param type - Specification type, defaults to "typescript"
|
|
264
|
+
* @returns true if added, false if already exists
|
|
265
|
+
*/
|
|
266
|
+
addCustomObject(id, content, type = "typescript") {
|
|
267
|
+
if (this.hasCustomObject(id)) {
|
|
268
|
+
return false;
|
|
269
|
+
}
|
|
270
|
+
this.data.custom_object_definitions ??= {};
|
|
271
|
+
this.data.custom_object_definitions.definitions ??= [];
|
|
272
|
+
this.data.custom_object_definitions.definitions.push({
|
|
273
|
+
id,
|
|
274
|
+
specification: { type, content }
|
|
275
|
+
});
|
|
276
|
+
return true;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Remove a custom object definition by id
|
|
280
|
+
* @param id - Object identifier to remove
|
|
281
|
+
* @returns true if removed, false if not found
|
|
282
|
+
*/
|
|
283
|
+
removeCustomObject(id) {
|
|
284
|
+
const block = this.data.custom_object_definitions;
|
|
285
|
+
if (!block?.definitions) {
|
|
286
|
+
return false;
|
|
287
|
+
}
|
|
288
|
+
const originalLength = block.definitions.length;
|
|
289
|
+
block.definitions = block.definitions.filter((def) => def.id !== id);
|
|
290
|
+
const newLength = block.definitions.length;
|
|
291
|
+
if (newLength === 0) {
|
|
292
|
+
delete this.data.custom_object_definitions;
|
|
293
|
+
}
|
|
294
|
+
return newLength < originalLength;
|
|
295
|
+
}
|
|
296
|
+
// ============================================================
|
|
297
|
+
// Extensions
|
|
298
|
+
// ============================================================
|
|
299
|
+
/**
|
|
300
|
+
* Add a new extension or update an existing one by ID
|
|
301
|
+
* If an extension with the provided ID exists, it will be replaced entirely
|
|
302
|
+
* @param extension - Extension configuration with all required fields including id
|
|
303
|
+
* @returns The extension ID
|
|
304
|
+
*/
|
|
305
|
+
addOrUpdateExtension(extension) {
|
|
306
|
+
const newExtension = {
|
|
307
|
+
id: extension.id,
|
|
308
|
+
name: extension.name,
|
|
309
|
+
interface_id: extension.interface_id,
|
|
310
|
+
version: extension.version,
|
|
311
|
+
...extension.description !== void 0 && {
|
|
312
|
+
description: extension.description
|
|
313
|
+
},
|
|
314
|
+
...extension.stripe_version !== void 0 && {
|
|
315
|
+
stripe_version: extension.stripe_version
|
|
316
|
+
},
|
|
317
|
+
...extension.script_entry_point !== void 0 && {
|
|
318
|
+
script_entry_point: extension.script_entry_point
|
|
319
|
+
},
|
|
320
|
+
...extension.script !== void 0 && { script: extension.script },
|
|
321
|
+
permissions: extension.permissions,
|
|
322
|
+
methods: extension.methods,
|
|
323
|
+
...extension.configuration !== void 0 && {
|
|
324
|
+
configuration: extension.configuration
|
|
325
|
+
},
|
|
326
|
+
...extension.endpoints !== void 0 && {
|
|
327
|
+
endpoints: extension.endpoints
|
|
328
|
+
}
|
|
329
|
+
};
|
|
330
|
+
this.data.extensions ??= [];
|
|
331
|
+
const existingIndex = this.data.extensions.findIndex(
|
|
332
|
+
(ext) => ext.id === extension.id
|
|
333
|
+
);
|
|
334
|
+
if (existingIndex !== -1) {
|
|
335
|
+
this.data.extensions[existingIndex] = newExtension;
|
|
336
|
+
} else {
|
|
337
|
+
this.data.extensions.push(newExtension);
|
|
338
|
+
}
|
|
339
|
+
return extension.id;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Get a read-only view of all extensions
|
|
343
|
+
*/
|
|
344
|
+
getExtensions() {
|
|
345
|
+
return this.data.extensions ?? [];
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* Get the raw manifest data (for reading other fields)
|
|
349
|
+
*/
|
|
350
|
+
getRawData() {
|
|
351
|
+
return this.data;
|
|
352
|
+
}
|
|
353
|
+
/**
|
|
354
|
+
* Save changes back to disk
|
|
355
|
+
* @throws Error if file cannot be written
|
|
356
|
+
*/
|
|
357
|
+
async save() {
|
|
358
|
+
try {
|
|
359
|
+
const updatedContent = yaml.stringify(this.data);
|
|
360
|
+
await writeFile(this.filePath, updatedContent, "utf-8");
|
|
361
|
+
} catch (err) {
|
|
362
|
+
if (err instanceof Error) {
|
|
363
|
+
throw new Error(`Error writing stripe-app.yaml: ${err.message}`);
|
|
364
|
+
}
|
|
365
|
+
throw new Error(`Error writing stripe-app.yaml: ${String(err)}`);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
|
|
370
|
+
// src/manifest/stripe-app-manifest.ts
|
|
371
|
+
var _StripeAppManifest = class __StripeAppManifest {
|
|
372
|
+
constructor(manifestPath, version, v1, v2) {
|
|
373
|
+
this.manifestPath = manifestPath;
|
|
374
|
+
this.version = version;
|
|
375
|
+
this.v1 = v1;
|
|
376
|
+
this.v2 = v2;
|
|
377
|
+
}
|
|
378
|
+
/**
|
|
379
|
+
* Load a manifest file, automatically detecting the version.
|
|
380
|
+
* @param manifestPath - Path to stripe-app.json or stripe-app.yaml
|
|
381
|
+
* @returns Loaded manifest instance
|
|
382
|
+
*/
|
|
383
|
+
static async load(manifestPath) {
|
|
384
|
+
const version = __StripeAppManifest.detectVersion(manifestPath);
|
|
385
|
+
if (version === "v1") {
|
|
386
|
+
const reader = _ManifestV1.load(manifestPath);
|
|
387
|
+
return new __StripeAppManifest(manifestPath, version, reader, null);
|
|
388
|
+
} else {
|
|
389
|
+
const reader = await _ManifestV2.load(manifestPath);
|
|
390
|
+
return new __StripeAppManifest(manifestPath, version, null, reader);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* Detect manifest version from file path.
|
|
395
|
+
* TODO: Add content-based detection if needed.
|
|
396
|
+
*/
|
|
397
|
+
static detectVersion(manifestPath) {
|
|
398
|
+
const lowerPath = manifestPath.toLowerCase();
|
|
399
|
+
if (lowerPath.endsWith(".yaml") || lowerPath.endsWith(".yml")) {
|
|
400
|
+
return "v2";
|
|
401
|
+
}
|
|
402
|
+
if (lowerPath.endsWith(".json")) {
|
|
403
|
+
return "v1";
|
|
404
|
+
}
|
|
405
|
+
throw new Error(
|
|
406
|
+
`Cannot detect manifest version from path: ${manifestPath}. Expected .json (v1) or .yaml/.yml (v2) extension.`
|
|
407
|
+
);
|
|
408
|
+
}
|
|
409
|
+
/**
|
|
410
|
+
* Get the detected manifest version
|
|
411
|
+
*/
|
|
412
|
+
getVersion() {
|
|
413
|
+
return this.version;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Get the manifest file path
|
|
417
|
+
*/
|
|
418
|
+
getManifestPath() {
|
|
419
|
+
return this.manifestPath;
|
|
420
|
+
}
|
|
421
|
+
// ============================================================
|
|
422
|
+
// App Metadata (supported by both V1 and V2)
|
|
423
|
+
// ============================================================
|
|
424
|
+
/**
|
|
425
|
+
* Get the app ID from the manifest
|
|
426
|
+
*/
|
|
427
|
+
getAppId() {
|
|
428
|
+
if (this.v1) {
|
|
429
|
+
return this.v1.getAppId();
|
|
430
|
+
}
|
|
431
|
+
if (this.v2) {
|
|
432
|
+
return this.v2.getAppId();
|
|
433
|
+
}
|
|
434
|
+
return void 0;
|
|
435
|
+
}
|
|
436
|
+
/**
|
|
437
|
+
* Get the app name from the manifest
|
|
438
|
+
*/
|
|
439
|
+
getAppName() {
|
|
440
|
+
if (this.v1) {
|
|
441
|
+
return this.v1.getAppName();
|
|
442
|
+
}
|
|
443
|
+
if (this.v2) {
|
|
444
|
+
return this.v2.getAppName();
|
|
445
|
+
}
|
|
446
|
+
return void 0;
|
|
447
|
+
}
|
|
448
|
+
// ============================================================
|
|
449
|
+
// Custom Objects (supported by both V1 and V2)
|
|
450
|
+
// ============================================================
|
|
451
|
+
/**
|
|
452
|
+
* Get all custom objects from the manifest
|
|
453
|
+
*/
|
|
454
|
+
getCustomObjects() {
|
|
455
|
+
if (this.v1) {
|
|
456
|
+
return this.v1.getCustomObjects();
|
|
457
|
+
}
|
|
458
|
+
if (this.v2) {
|
|
459
|
+
return this.v2.getCustomObjects().map((obj) => ({
|
|
460
|
+
filePath: obj.path,
|
|
461
|
+
className: obj.name
|
|
462
|
+
}));
|
|
463
|
+
}
|
|
464
|
+
return [];
|
|
465
|
+
}
|
|
466
|
+
/**
|
|
467
|
+
* Check if a custom object entry exists in the manifest.
|
|
468
|
+
*
|
|
469
|
+
* **V2 note:** Identity is keyed on `_toSnakeCase(className)` alone — `filePath`
|
|
470
|
+
* is not considered. Two entries with the same class name but different file
|
|
471
|
+
* paths are treated as the same object. The `_toSnakeCase` → `_toPascalCase`
|
|
472
|
+
* round-trip is lossless for typical class names but lossy for consecutive
|
|
473
|
+
* uppercase (e.g., `HTTPClient` → `http_client` → `HttpClient`). The manifest
|
|
474
|
+
* `id` field is the source of truth; see `_CustomObjectDefinitionYaml` docs.
|
|
475
|
+
*/
|
|
476
|
+
hasCustomObject(entry) {
|
|
477
|
+
if (this.v1) {
|
|
478
|
+
return this.v1.hasCustomObject(entry);
|
|
479
|
+
}
|
|
480
|
+
if (this.v2) {
|
|
481
|
+
return this.v2.hasCustomObject(_toSnakeCase(entry.className));
|
|
482
|
+
}
|
|
483
|
+
return false;
|
|
484
|
+
}
|
|
485
|
+
/**
|
|
486
|
+
* Add a custom object entry to the manifest.
|
|
487
|
+
*
|
|
488
|
+
* **V2 note:** The manifest `id` is derived as `_toSnakeCase(className)` and
|
|
489
|
+
* `filePath` is stored as the specification `content` path. Identity/dedup
|
|
490
|
+
* is based on `id` alone — see `hasCustomObject` for details.
|
|
491
|
+
*
|
|
492
|
+
* @param entry - The custom object entry to add
|
|
493
|
+
* @returns true if entry was added, false if it already existed
|
|
494
|
+
*/
|
|
495
|
+
addCustomObject(entry) {
|
|
496
|
+
if (this.v1) {
|
|
497
|
+
return this.v1.addCustomObject(entry);
|
|
498
|
+
}
|
|
499
|
+
if (this.v2) {
|
|
500
|
+
return this.v2.addCustomObject(_toSnakeCase(entry.className), entry.filePath);
|
|
501
|
+
}
|
|
502
|
+
return false;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Remove a custom object entry from the manifest.
|
|
506
|
+
*
|
|
507
|
+
* **V2 note:** Removal is keyed on `_toSnakeCase(className)` — `filePath` is
|
|
508
|
+
* not considered. See `hasCustomObject` for identity semantics.
|
|
509
|
+
*
|
|
510
|
+
* @param entry - The custom object entry to remove
|
|
511
|
+
* @returns true if entry was removed, false if it didn't exist
|
|
512
|
+
*/
|
|
513
|
+
removeCustomObject(entry) {
|
|
514
|
+
if (this.v1) {
|
|
515
|
+
return this.v1.removeCustomObject(entry);
|
|
516
|
+
}
|
|
517
|
+
if (this.v2) {
|
|
518
|
+
return this.v2.removeCustomObject(_toSnakeCase(entry.className));
|
|
519
|
+
}
|
|
520
|
+
return false;
|
|
521
|
+
}
|
|
522
|
+
// ============================================================
|
|
523
|
+
// Extensions (V2 only)
|
|
524
|
+
// ============================================================
|
|
525
|
+
/**
|
|
526
|
+
* Get all extensions from the manifest
|
|
527
|
+
* @throws Error if manifest version doesn't support extensions
|
|
528
|
+
*/
|
|
529
|
+
getExtensions() {
|
|
530
|
+
if (this.v2) {
|
|
531
|
+
return this.v2.getExtensions();
|
|
532
|
+
}
|
|
533
|
+
throw new Error("Extensions are not supported in V1 manifests (stripe-app.json)");
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Add or update an extension in the manifest.
|
|
537
|
+
* If an extension with the same ID exists, it will be replaced.
|
|
538
|
+
*
|
|
539
|
+
* @param config - Full extension configuration
|
|
540
|
+
* @returns The extension ID
|
|
541
|
+
* @throws Error if manifest version doesn't support extensions
|
|
542
|
+
*/
|
|
543
|
+
addOrUpdateExtension(config) {
|
|
544
|
+
if (this.v2) {
|
|
545
|
+
return this.v2.addOrUpdateExtension(config);
|
|
546
|
+
}
|
|
547
|
+
throw new Error("Extensions are not supported in V1 manifests (stripe-app.json)");
|
|
548
|
+
}
|
|
549
|
+
// ============================================================
|
|
550
|
+
// Persistence
|
|
551
|
+
// ============================================================
|
|
552
|
+
/**
|
|
553
|
+
* Save changes back to disk
|
|
554
|
+
*/
|
|
555
|
+
async save() {
|
|
556
|
+
if (this.v1) {
|
|
557
|
+
this.v1.save();
|
|
558
|
+
return;
|
|
559
|
+
}
|
|
560
|
+
if (this.v2) {
|
|
561
|
+
await this.v2.save();
|
|
562
|
+
return;
|
|
563
|
+
}
|
|
564
|
+
throw new Error("No reader loaded - this should never happen");
|
|
565
|
+
}
|
|
566
|
+
};
|
|
567
|
+
export {
|
|
568
|
+
_ManifestV1,
|
|
569
|
+
_ManifestV2,
|
|
570
|
+
_StripeAppManifest
|
|
571
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* V1 manifest structure (stripe-app.json)
|
|
3
|
+
* @internal
|
|
4
|
+
*/
|
|
5
|
+
export interface _ManifestV1Data {
|
|
6
|
+
/** The app identifier. */
|
|
7
|
+
id: string;
|
|
8
|
+
/** The app version string. */
|
|
9
|
+
version: string;
|
|
10
|
+
/** The app display name. */
|
|
11
|
+
name: string;
|
|
12
|
+
/** List of custom object entries in `path#ClassName` format. */
|
|
13
|
+
exported_custom_objects?: string[];
|
|
14
|
+
/** Additional manifest fields. */
|
|
15
|
+
[key: string]: unknown;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* A parsed custom object entry referencing a file path and export class name.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export interface _CustomObjectEntry {
|
|
22
|
+
/** Relative path to the type definition file (e.g., `src/device.d.ts`). */
|
|
23
|
+
filePath: string;
|
|
24
|
+
/** Name of the exported class in the definition file. */
|
|
25
|
+
className: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Format a custom object entry as the manifest string format
|
|
29
|
+
* @param entry - The custom object entry
|
|
30
|
+
* @returns String in format "path/to/file.d.ts#ClassName"
|
|
31
|
+
* @internal
|
|
32
|
+
*/
|
|
33
|
+
export declare function formatCustomObjectEntry(entry: _CustomObjectEntry): string;
|
|
34
|
+
/**
|
|
35
|
+
* Parse a custom object entry string into structured format
|
|
36
|
+
* @param entryString - String in format "path/to/file.d.ts#ClassName"
|
|
37
|
+
* @returns Parsed CustomObjectEntry
|
|
38
|
+
* @internal
|
|
39
|
+
*/
|
|
40
|
+
export declare function parseCustomObjectEntry(entryString: string): _CustomObjectEntry;
|
|
41
|
+
/**
|
|
42
|
+
* Manages stripe-app.json (V1) manifest file operations
|
|
43
|
+
*
|
|
44
|
+
* Capabilities:
|
|
45
|
+
* - Custom objects (add, remove, has, get)
|
|
46
|
+
* - App metadata (id, name)
|
|
47
|
+
*
|
|
48
|
+
* @example
|
|
49
|
+
* ```ts
|
|
50
|
+
* const manifest = await ManifestV1.load('./stripe-app.json')
|
|
51
|
+
* manifest.addCustomObject({ filePath: 'src/device.d.ts', className: 'Device' })
|
|
52
|
+
* await manifest.save()
|
|
53
|
+
* ```
|
|
54
|
+
* @internal
|
|
55
|
+
*/
|
|
56
|
+
export declare class _ManifestV1 {
|
|
57
|
+
private readonly filePath;
|
|
58
|
+
private data;
|
|
59
|
+
private constructor();
|
|
60
|
+
/**
|
|
61
|
+
* Load stripe-app.json from disk
|
|
62
|
+
* @param filePath - Path to stripe-app.json
|
|
63
|
+
* @throws Error if file is invalid or cannot be read
|
|
64
|
+
*/
|
|
65
|
+
static load(filePath: string): _ManifestV1;
|
|
66
|
+
/**
|
|
67
|
+
* Get the app ID from the manifest
|
|
68
|
+
*/
|
|
69
|
+
getAppId(): string;
|
|
70
|
+
/**
|
|
71
|
+
* Get the app name from the manifest
|
|
72
|
+
*/
|
|
73
|
+
getAppName(): string;
|
|
74
|
+
/**
|
|
75
|
+
* Get all custom objects as structured entries
|
|
76
|
+
*/
|
|
77
|
+
getCustomObjects(): _CustomObjectEntry[];
|
|
78
|
+
/**
|
|
79
|
+
* Check if a custom object entry exists in the manifest
|
|
80
|
+
*/
|
|
81
|
+
hasCustomObject(entry: _CustomObjectEntry): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Add a custom object entry to the manifest
|
|
84
|
+
* Does nothing if entry already exists
|
|
85
|
+
* @returns true if entry was added, false if it already existed
|
|
86
|
+
*/
|
|
87
|
+
addCustomObject(entry: _CustomObjectEntry): boolean;
|
|
88
|
+
/**
|
|
89
|
+
* Remove a custom object entry from the manifest
|
|
90
|
+
* @returns true if entry was removed, false if it didn't exist
|
|
91
|
+
*/
|
|
92
|
+
removeCustomObject(entry: _CustomObjectEntry): boolean;
|
|
93
|
+
/**
|
|
94
|
+
* Get the raw manifest data (for reading other fields)
|
|
95
|
+
*/
|
|
96
|
+
getRawData(): Readonly<_ManifestV1Data>;
|
|
97
|
+
/**
|
|
98
|
+
* Save changes back to disk
|
|
99
|
+
*/
|
|
100
|
+
save(): void;
|
|
101
|
+
}
|
|
102
|
+
//# sourceMappingURL=manifest-v1.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manifest-v1.d.ts","sourceRoot":"","sources":["../../src/manifest/manifest-v1.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,0BAA0B;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,8BAA8B;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,gEAAgE;IAChE,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;IACnC,kCAAkC;IAClC,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,yDAAyD;IACzD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,kBAAkB,GAAG,MAAM,CAEzE;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAc9E;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,WAAW;IAEpB,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,IAAI;IAFd,OAAO;IAKP;;;;OAIG;IACH,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,WAAW;IAgB1C;;OAEG;IACH,QAAQ,IAAI,MAAM;IAIlB;;OAEG;IACH,UAAU,IAAI,MAAM;IAIpB;;OAEG;IACH,gBAAgB,IAAI,kBAAkB,EAAE;IAUxC;;OAEG;IACH,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAQnD;;;;OAIG;IACH,eAAe,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAanD;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO;IAoBtD;;OAEG;IACH,UAAU,IAAI,QAAQ,CAAC,eAAe,CAAC;IAIvC;;OAEG;IACH,IAAI,IAAI,IAAI;CAGb"}
|