merchi_sdk_ts 1.35.0 → 1.36.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RELEASING.md +43 -0
- package/dist/constants/roles.js +1 -0
- package/dist/entities/cart.js +4 -0
- package/dist/entities/cart.test.js +6 -0
- package/dist/entities/discount.js +5 -0
- package/dist/entities/discount.test.js +9 -0
- package/dist/entities/invoice.js +4 -0
- package/dist/entities/invoice.test.js +6 -0
- package/dist/entities/payment.js +16 -0
- package/dist/entities/payment.test.js +6 -0
- package/package.json +1 -1
- package/src/constants/roles.ts +1 -0
- package/src/entities/cart.test.ts +7 -0
- package/src/entities/cart.ts +3 -0
- package/src/entities/discount.test.ts +9 -0
- package/src/entities/discount.ts +3 -0
- package/src/entities/invoice.test.ts +7 -0
- package/src/entities/invoice.ts +3 -0
- package/src/entities/payment.test.ts +8 -0
- package/src/entities/payment.ts +12 -0
package/RELEASING.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Automatic npm releases
|
|
2
|
+
|
|
3
|
+
Merging to `main` triggers `.github/workflows/publish.yml`. No manually edited version or local `npm publish` is needed after the one-time npm trust setup.
|
|
4
|
+
|
|
5
|
+
## One-time setup
|
|
6
|
+
|
|
7
|
+
In npm package **merchi_sdk_ts** settings, add a GitHub Actions trusted publisher:
|
|
8
|
+
|
|
9
|
+
- Owner: `merchisdk`
|
|
10
|
+
- Repository: `merchi_sdk_ts`
|
|
11
|
+
- Workflow filename: `publish.yml`
|
|
12
|
+
- Environment: leave blank (the job has no GitHub environment)
|
|
13
|
+
- Allow direct publishing (`npm publish`), not stage-only publishing.
|
|
14
|
+
|
|
15
|
+
An npm package owner must authorize this once. There is no `NPM_TOKEN` dependency. Current local npm credentials returned 401, so this trust setup has not been verified or completed by Codex. GitHub branch rules must allow the workflow bot to write the version commit to `main`; the workflow never disables protection or force-pushes.
|
|
16
|
+
|
|
17
|
+
Official setup: https://docs.npmjs.com/trusted-publishers/
|
|
18
|
+
|
|
19
|
+
## Behavior
|
|
20
|
+
|
|
21
|
+
- Builds latest `main` after acquiring a per-repository concurrency slot. Several rapid merges may be included in one release.
|
|
22
|
+
- Uses an explicitly prepared stable version if it is newer than npm latest; otherwise automatically increments the registry's patch version. Major/minor releases remain deliberate changes to package.json.
|
|
23
|
+
- Installs dependencies and builds before publishing. npm install also repairs the historical lockfile/manifest mismatch; the resulting lockfile and version are committed together.
|
|
24
|
+
- Pushes the version commit with `[skip ci]` using `GITHUB_TOKEN`; it does not trigger another push workflow. A concurrent main update rejects the push and prevents publication of that attempt.
|
|
25
|
+
- Publishes through npm OIDC, verifies registry version and git commit, then tags `v<version>`.
|
|
26
|
+
- Re-runs of the already published commit do not bump or republish. If publication failed after the version commit, retries reuse the unpublished version only while it remains newer than latest and unoccupied.
|
|
27
|
+
- The hourly run recovers interrupted releases and packages whose new dependencies were not published yet. A failed build or missing authorization still reports failure; it cannot be solved by inventing credentials or publishing broken code. A manual Actions rerun is optional.
|
|
28
|
+
|
|
29
|
+
Merge/release SDK and invoice before cart and checkout for the initial wallet release. Cart/checkout require invoice 1.3.2 or later; if merged sooner they wait through failed install/retry runs until it exists. Consumers such as Dashboard retain their normal lockfile update/review process; this workflow does not merge or deploy consumers.
|
|
30
|
+
|
|
31
|
+
Validation: local release planner tests and YAML parsing. Package builds and payment regression tests were verified separately. Actual GitHub-to-npm publishing still requires the one-time trusted publisher setup and a merged workflow.
|
|
32
|
+
|
|
33
|
+
## Coexistence with manual publishing
|
|
34
|
+
|
|
35
|
+
Manual npm publishing remains allowed. The planner reads both latest and all occupied versions, skips occupied versions, and recognizes a manually published main commit even when its version differs from package.json. If latest has no gitHead or its commit is not an ancestor of main, automation pauses with a warning; merge the released source into main or investigate the package provenance before continuing. It never assumes unknown manual code is safe to replace.
|
|
36
|
+
|
|
37
|
+
Immediately before publishing, the workflow rechecks latest and version availability. A changed registry or a concurrent same-version manual publication is deferred with a warning, without replacing that version or its Git tag. Network/auth/build failures remain failures; the next scheduled run retries. A successful publish with a lost response is reconciled against the registry gitHead.
|
|
38
|
+
|
|
39
|
+
GitHub concurrency serializes Actions only, not developers' npm commands. npm has no cross-publisher lock or atomic compare-and-set for latest: simultaneous different-version manual and automatic publishes can still race on latest. When doing an exceptional manual release, coordinate to avoid an active publish job (or temporarily disable this workflow and wait for any active job to finish). Prefer the automatic workflow for routine releases. No script force-pushes, unpublishes, or rewrites an existing Git tag. Published version immutability prevents overwriting that version, but does not make latest race-free. First hosted OIDC publication still needs verification after merge.
|
|
40
|
+
|
|
41
|
+
## Release recovery
|
|
42
|
+
|
|
43
|
+
Publication verification queries the exact version with fresh registry reads, retrying up to seven times over 30 seconds without repeating npm publish. Each run also recovers the latest published version's missing Git tag before preparing a new release, including when main has advanced. Recovery requires the registry gitHead to be contained in the checkout history. Existing conflicting tags fail visibly and are never overwritten. Ignored, untracked lockfiles are not staged. Branch rules must still permit the normal version commit push; protection is never changed by this workflow.
|
package/dist/constants/roles.js
CHANGED
|
@@ -34,6 +34,7 @@ export var Role;
|
|
|
34
34
|
Role[Role["MANAGER"] = 6] = "MANAGER";
|
|
35
35
|
Role[Role["ACCOUNTANT"] = 7] = "ACCOUNTANT";
|
|
36
36
|
Role[Role["THEME_EDITOR"] = 8] = "THEME_EDITOR";
|
|
37
|
+
Role[Role["REFERRER"] = 9] = "REFERRER";
|
|
37
38
|
})(Role || (Role = {}));
|
|
38
39
|
export var DOMAIN_MANAGERS = [Role.ADMIN, Role.MANAGER];
|
|
39
40
|
export var MANAGEMENT_TEAM = __spreadArray(__spreadArray([], __read(DOMAIN_MANAGERS), false), [
|
package/dist/entities/cart.js
CHANGED
|
@@ -76,6 +76,10 @@ var Cart = /** @class */ (function (_super) {
|
|
|
76
76
|
Cart.property(),
|
|
77
77
|
__metadata("design:type", Number)
|
|
78
78
|
], Cart.prototype, "id", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
Cart.property(),
|
|
81
|
+
__metadata("design:type", String)
|
|
82
|
+
], Cart.prototype, "stripePaymentEngine", void 0);
|
|
79
83
|
__decorate([
|
|
80
84
|
Cart.property(),
|
|
81
85
|
__metadata("design:type", Date)
|
|
@@ -43,3 +43,9 @@ test('pass cookie tokens to query string', function () {
|
|
|
43
43
|
expect(fetch.mock.calls[0][1]['query']).toEqual(correct);
|
|
44
44
|
return invocation;
|
|
45
45
|
});
|
|
46
|
+
test('preserves server payment engine hint', function () {
|
|
47
|
+
var merchi = new Merchi();
|
|
48
|
+
var entity = new merchi.Cart();
|
|
49
|
+
entity.fromJson({ id: 1, stripePaymentEngine: 'wallet' });
|
|
50
|
+
expect(entity.toJson()).toMatchObject({ stripePaymentEngine: 'wallet' });
|
|
51
|
+
});
|
|
@@ -24,6 +24,7 @@ var __metadata = (this && this.__metadata) || function (k, v) {
|
|
|
24
24
|
};
|
|
25
25
|
import { Entity } from '../entity.js';
|
|
26
26
|
import { DiscountGroup } from './discount_group.js';
|
|
27
|
+
import { User } from './user.js';
|
|
27
28
|
var Discount = /** @class */ (function (_super) {
|
|
28
29
|
__extends(Discount, _super);
|
|
29
30
|
function Discount() {
|
|
@@ -75,6 +76,10 @@ var Discount = /** @class */ (function (_super) {
|
|
|
75
76
|
Discount.property({ arrayType: 'User' }),
|
|
76
77
|
__metadata("design:type", Array)
|
|
77
78
|
], Discount.prototype, "assignedUsers", void 0);
|
|
79
|
+
__decorate([
|
|
80
|
+
Discount.property({ type: User }),
|
|
81
|
+
__metadata("design:type", Object)
|
|
82
|
+
], Discount.prototype, "referrer", void 0);
|
|
78
83
|
__decorate([
|
|
79
84
|
Discount.property({ type: DiscountGroup }),
|
|
80
85
|
__metadata("design:type", Object)
|
|
@@ -13,6 +13,15 @@ test('can set assignedUsers', function () {
|
|
|
13
13
|
discount.assignedUsers = [user];
|
|
14
14
|
expect((_a = discount.assignedUsers) === null || _a === void 0 ? void 0 : _a.map(function (assigned) { return assigned.id; })).toEqual([11]);
|
|
15
15
|
});
|
|
16
|
+
test('can set referrer', function () {
|
|
17
|
+
var _a;
|
|
18
|
+
var merchi = new Merchi();
|
|
19
|
+
var discount = new merchi.Discount();
|
|
20
|
+
var user = new merchi.User();
|
|
21
|
+
user.id = 22;
|
|
22
|
+
discount.referrer = user;
|
|
23
|
+
expect((_a = discount.referrer) === null || _a === void 0 ? void 0 : _a.id).toEqual(22);
|
|
24
|
+
});
|
|
16
25
|
test('discountedUnitCost', function () {
|
|
17
26
|
var merchi = new Merchi();
|
|
18
27
|
var discount = new merchi.Discount();
|
package/dist/entities/invoice.js
CHANGED
|
@@ -47,6 +47,10 @@ var Invoice = /** @class */ (function (_super) {
|
|
|
47
47
|
Invoice.property(),
|
|
48
48
|
__metadata("design:type", Number)
|
|
49
49
|
], Invoice.prototype, "id", void 0);
|
|
50
|
+
__decorate([
|
|
51
|
+
Invoice.property(),
|
|
52
|
+
__metadata("design:type", String)
|
|
53
|
+
], Invoice.prototype, "stripePaymentEngine", void 0);
|
|
50
54
|
__decorate([
|
|
51
55
|
Invoice.property({ type: Date }),
|
|
52
56
|
__metadata("design:type", Object)
|
|
@@ -37,3 +37,9 @@ test('client and invoice tokens supported by merchi', function () {
|
|
|
37
37
|
expect(fetch.mock.calls[0][1]['query']).toEqual(correct);
|
|
38
38
|
return invocation;
|
|
39
39
|
});
|
|
40
|
+
test('preserves server payment engine hint', function () {
|
|
41
|
+
var merchi = new Merchi();
|
|
42
|
+
var entity = new merchi.Invoice();
|
|
43
|
+
entity.fromJson({ id: 1, stripePaymentEngine: 'wallet' });
|
|
44
|
+
expect(entity.toJson()).toMatchObject({ stripePaymentEngine: 'wallet' });
|
|
45
|
+
});
|
package/dist/entities/payment.js
CHANGED
|
@@ -61,6 +61,22 @@ var Payment = /** @class */ (function (_super) {
|
|
|
61
61
|
Payment.property(),
|
|
62
62
|
__metadata("design:type", Number)
|
|
63
63
|
], Payment.prototype, "paymentType", void 0);
|
|
64
|
+
__decorate([
|
|
65
|
+
Payment.property(),
|
|
66
|
+
__metadata("design:type", String)
|
|
67
|
+
], Payment.prototype, "paymentProvider", void 0);
|
|
68
|
+
__decorate([
|
|
69
|
+
Payment.property(),
|
|
70
|
+
__metadata("design:type", String)
|
|
71
|
+
], Payment.prototype, "paymentMethod", void 0);
|
|
72
|
+
__decorate([
|
|
73
|
+
Payment.property(),
|
|
74
|
+
__metadata("design:type", Number)
|
|
75
|
+
], Payment.prototype, "refundedAmount", void 0);
|
|
76
|
+
__decorate([
|
|
77
|
+
Payment.property({ type: String }),
|
|
78
|
+
__metadata("design:type", Object)
|
|
79
|
+
], Payment.prototype, "refundStatus", void 0);
|
|
64
80
|
__decorate([
|
|
65
81
|
Payment.property(),
|
|
66
82
|
__metadata("design:type", String)
|
|
@@ -14,3 +14,9 @@ test('payment refund', function () {
|
|
|
14
14
|
expect(payment.amount).toEqual(10);
|
|
15
15
|
});
|
|
16
16
|
});
|
|
17
|
+
test('wallet method and partial refund survive API serialization', function () {
|
|
18
|
+
var payment = new (new Merchi()).Payment();
|
|
19
|
+
payment.fromJson({ id: 8, amount: 20, paymentType: 1, paymentProvider: 'stripe',
|
|
20
|
+
paymentMethod: 'wechat_pay', refundedAmount: 5, refundStatus: 'pending' });
|
|
21
|
+
expect(payment.toJson()).toMatchObject({ paymentMethod: 'wechat_pay', refundedAmount: 5, refundStatus: 'pending' });
|
|
22
|
+
});
|
package/package.json
CHANGED
package/src/constants/roles.ts
CHANGED
|
@@ -48,3 +48,10 @@ test('pass cookie tokens to query string', () => {
|
|
|
48
48
|
expect(fetch.mock.calls[0][1]['query']).toEqual(correct);
|
|
49
49
|
return invocation;
|
|
50
50
|
});
|
|
51
|
+
|
|
52
|
+
test('preserves server payment engine hint', () => {
|
|
53
|
+
const merchi = new Merchi();
|
|
54
|
+
const entity = new merchi.Cart();
|
|
55
|
+
entity.fromJson({ id: 1, stripePaymentEngine: 'wallet' });
|
|
56
|
+
expect(entity.toJson()).toMatchObject({ stripePaymentEngine: 'wallet' });
|
|
57
|
+
});
|
package/src/entities/cart.ts
CHANGED
|
@@ -15,6 +15,15 @@ test('can set assignedUsers', () => {
|
|
|
15
15
|
expect(discount.assignedUsers?.map((assigned) => assigned.id)).toEqual([11]);
|
|
16
16
|
});
|
|
17
17
|
|
|
18
|
+
test('can set referrer', () => {
|
|
19
|
+
const merchi = new Merchi();
|
|
20
|
+
const discount = new merchi.Discount();
|
|
21
|
+
const user = new merchi.User();
|
|
22
|
+
user.id = 22;
|
|
23
|
+
discount.referrer = user;
|
|
24
|
+
expect(discount.referrer?.id).toEqual(22);
|
|
25
|
+
});
|
|
26
|
+
|
|
18
27
|
test('discountedUnitCost', () => {
|
|
19
28
|
const merchi = new Merchi();
|
|
20
29
|
const discount = new merchi.Discount();
|
package/src/entities/discount.ts
CHANGED
|
@@ -31,6 +31,9 @@ export class Discount extends Entity {
|
|
|
31
31
|
@Discount.property({arrayType: 'User'})
|
|
32
32
|
public assignedUsers?: User[];
|
|
33
33
|
|
|
34
|
+
@Discount.property({type: User})
|
|
35
|
+
public referrer?: User | null;
|
|
36
|
+
|
|
34
37
|
@Discount.property({type: DiscountGroup})
|
|
35
38
|
public discountGroup?: DiscountGroup | null;
|
|
36
39
|
|
|
@@ -41,3 +41,10 @@ test('client and invoice tokens supported by merchi', () => {
|
|
|
41
41
|
expect(fetch.mock.calls[0][1]['query']).toEqual(correct);
|
|
42
42
|
return invocation;
|
|
43
43
|
});
|
|
44
|
+
|
|
45
|
+
test('preserves server payment engine hint', () => {
|
|
46
|
+
const merchi = new Merchi();
|
|
47
|
+
const entity = new merchi.Invoice();
|
|
48
|
+
entity.fromJson({ id: 1, stripePaymentEngine: 'wallet' });
|
|
49
|
+
expect(entity.toJson()).toMatchObject({ stripePaymentEngine: 'wallet' });
|
|
50
|
+
});
|
package/src/entities/invoice.ts
CHANGED
|
@@ -17,3 +17,11 @@ test('payment refund', () => {
|
|
|
17
17
|
expect(payment.amount).toEqual(10);
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
test('wallet method and partial refund survive API serialization', () => {
|
|
23
|
+
const payment = new (new Merchi()).Payment();
|
|
24
|
+
payment.fromJson({ id: 8, amount: 20, paymentType: 1, paymentProvider: 'stripe',
|
|
25
|
+
paymentMethod: 'wechat_pay', refundedAmount: 5, refundStatus: 'pending' });
|
|
26
|
+
expect(payment.toJson()).toMatchObject({ paymentMethod: 'wechat_pay', refundedAmount: 5, refundStatus: 'pending' });
|
|
27
|
+
});
|
package/src/entities/payment.ts
CHANGED
|
@@ -21,6 +21,18 @@ export class Payment extends Entity {
|
|
|
21
21
|
@Payment.property()
|
|
22
22
|
public paymentType?: number;
|
|
23
23
|
|
|
24
|
+
@Payment.property()
|
|
25
|
+
public paymentProvider?: string;
|
|
26
|
+
|
|
27
|
+
@Payment.property()
|
|
28
|
+
public paymentMethod?: string;
|
|
29
|
+
|
|
30
|
+
@Payment.property()
|
|
31
|
+
public refundedAmount?: number;
|
|
32
|
+
|
|
33
|
+
@Payment.property({ type: String })
|
|
34
|
+
public refundStatus?: string | null;
|
|
35
|
+
|
|
24
36
|
@Payment.property()
|
|
25
37
|
public note?: string;
|
|
26
38
|
|