@meadow-studio/platform 0.0.0-stage → 0.1.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/MeadowPlatform.podspec +17 -0
- package/Package.swift +23 -0
- package/README.md +147 -2
- package/android/build.gradle +42 -0
- package/android/src/main/AndroidManifest.xml +1 -0
- package/android/src/main/java/app/meadow/platform/MeadowAppRatingPlugin.java +38 -0
- package/dist/cli/commands.d.ts +74 -0
- package/dist/cli/commands.d.ts.map +1 -0
- package/dist/cli/commands.js +1062 -0
- package/dist/cli/commands.js.map +1 -0
- package/dist/cli/config.d.ts +123 -0
- package/dist/cli/config.d.ts.map +1 -0
- package/dist/cli/config.js +428 -0
- package/dist/cli/config.js.map +1 -0
- package/dist/cli/meadow.d.ts +8 -0
- package/dist/cli/meadow.d.ts.map +1 -0
- package/dist/cli/meadow.js +463 -0
- package/dist/cli/meadow.js.map +1 -0
- package/dist/cli/recipes.d.ts +10 -0
- package/dist/cli/recipes.d.ts.map +1 -0
- package/dist/cli/recipes.js +575 -0
- package/dist/cli/recipes.js.map +1 -0
- package/dist/cli/sync.d.ts +14 -0
- package/dist/cli/sync.d.ts.map +1 -0
- package/dist/cli/sync.js +310 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/templates.d.ts +27 -0
- package/dist/cli/templates.d.ts.map +1 -0
- package/dist/cli/templates.js +1246 -0
- package/dist/cli/templates.js.map +1 -0
- package/dist/cli/website.d.ts +5 -0
- package/dist/cli/website.d.ts.map +1 -0
- package/dist/cli/website.js +262 -0
- package/dist/cli/website.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/notifications.d.ts +119 -0
- package/dist/notifications.d.ts.map +1 -0
- package/dist/notifications.js +320 -0
- package/dist/notifications.js.map +1 -0
- package/dist/platform.d.ts +163 -0
- package/dist/platform.d.ts.map +1 -0
- package/dist/platform.js +623 -0
- package/dist/platform.js.map +1 -0
- package/dist/purchases.d.ts +88 -0
- package/dist/purchases.d.ts.map +1 -0
- package/dist/purchases.js +296 -0
- package/dist/purchases.js.map +1 -0
- package/dist/ui/app-build.component.d.ts +18 -0
- package/dist/ui/app-build.component.d.ts.map +1 -0
- package/dist/ui/app-build.component.js +56 -0
- package/dist/ui/app-build.component.js.map +1 -0
- package/dist/ui/app-build.model.d.ts +11 -0
- package/dist/ui/app-build.model.d.ts.map +1 -0
- package/dist/ui/app-build.model.js +18 -0
- package/dist/ui/app-build.model.js.map +1 -0
- package/dist/ui/app-links.component.d.ts +14 -0
- package/dist/ui/app-links.component.d.ts.map +1 -0
- package/dist/ui/app-links.component.js +77 -0
- package/dist/ui/app-links.component.js.map +1 -0
- package/dist/ui/app-links.model.d.ts +18 -0
- package/dist/ui/app-links.model.d.ts.map +1 -0
- package/dist/ui/app-links.model.js +17 -0
- package/dist/ui/app-links.model.js.map +1 -0
- package/dist/ui/index.d.ts +5 -0
- package/dist/ui/index.d.ts.map +1 -0
- package/dist/ui/index.js +5 -0
- package/dist/ui/index.js.map +1 -0
- package/docs/CLI.md +376 -0
- package/docs/PLATFORM_GUIDE.md +422 -0
- package/docs/POC_FINDINGS.md +218 -0
- package/docs/PROJECT_BRIEF.md +501 -0
- package/docs/RELEASING.md +49 -0
- package/docs/V0.1_PATH.md +310 -0
- package/ios/Sources/MeadowPlatformPlugin/MeadowAppRatingPlugin.swift +39 -0
- package/package.json +89 -4
- package/schema/meadow-config.schema.json +250 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
# Meadow Platform v0.1 — First Path
|
|
2
|
+
|
|
3
|
+
> This is the historical POC path and dated implementation record. For current capabilities and
|
|
4
|
+
> usage, read [PLATFORM_GUIDE.md](PLATFORM_GUIDE.md). For exact CLI behavior, read
|
|
5
|
+
> [CLI.md](CLI.md).
|
|
6
|
+
|
|
7
|
+
## POC outcome
|
|
8
|
+
|
|
9
|
+
Prove that the early 24h Pushups prototype can consume one private `@meadow-studio/platform` dependency without slowing concept development.
|
|
10
|
+
|
|
11
|
+
The first POC is complete when 24h Pushups can:
|
|
12
|
+
|
|
13
|
+
1. consume the local platform package at its exact `0.1.0` version and validate its packed contents;
|
|
14
|
+
2. provide typed app and environment configuration;
|
|
15
|
+
3. read app version, build number, and native platform through a Meadow-owned API;
|
|
16
|
+
4. pass its existing unit tests and production/device builds; and
|
|
17
|
+
5. build and run on its existing Android target.
|
|
18
|
+
|
|
19
|
+
The POC does not require Firebase, analytics consent, RevenueCat, private-registry publishing, or a generated iOS project. Those are separate adoption decisions after package consumption is proven.
|
|
20
|
+
|
|
21
|
+
## Why this slice comes first
|
|
22
|
+
|
|
23
|
+
Configuration is required by every later integration. App information is small, observable, and exercises Capacitor cleanly. Together they prove the package boundary without introducing infrastructure that an exploratory prototype does not yet need.
|
|
24
|
+
|
|
25
|
+
Analytics, consent, and purchases have native setup and product-policy consequences. They should reuse the configuration and provider boundaries proven by the first POC rather than defining those boundaries themselves.
|
|
26
|
+
|
|
27
|
+
## Phase 0 — Establish the package contract
|
|
28
|
+
|
|
29
|
+
Keep one package and a small root API.
|
|
30
|
+
|
|
31
|
+
Deliverables:
|
|
32
|
+
|
|
33
|
+
- use the shared proven baseline: Angular 20.3, Capacitor 7, TypeScript 5.9, RxJS 7.8, and Node 22;
|
|
34
|
+
- use `npm pack --dry-run` to verify published contents and a local file dependency for the first consumer integration;
|
|
35
|
+
- add package exports so consumers use public entry points only;
|
|
36
|
+
- add a minimal test runner and package-consumer smoke test;
|
|
37
|
+
- confirm the packed artifact contains only intended runtime and declaration files; and
|
|
38
|
+
- document the rule that application credentials are supplied by the consuming app.
|
|
39
|
+
|
|
40
|
+
After the POC is useful in practice, publish immutable versions through GitHub Packages or another private registry. Registry setup is not part of proving the code boundary.
|
|
41
|
+
|
|
42
|
+
## Phase 1 — Typed configuration
|
|
43
|
+
|
|
44
|
+
Create a small, immutable configuration contract containing only values immediately needed by the first consumer.
|
|
45
|
+
|
|
46
|
+
Initial shape to validate:
|
|
47
|
+
|
|
48
|
+
```ts
|
|
49
|
+
export interface MeadowPlatformConfig {
|
|
50
|
+
app: {
|
|
51
|
+
name: string;
|
|
52
|
+
id: string;
|
|
53
|
+
supportEmail?: string;
|
|
54
|
+
privacyUrl?: string;
|
|
55
|
+
};
|
|
56
|
+
environment: 'development' | 'device' | 'production';
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Requirements:
|
|
61
|
+
|
|
62
|
+
- fail early with useful errors for invalid required values;
|
|
63
|
+
- keep credentials and environment selection in the consuming app;
|
|
64
|
+
- do not create a general plugin system;
|
|
65
|
+
- do not include analytics or purchases configuration until those slices establish their real needs; and
|
|
66
|
+
- expose configuration through one documented initialization path.
|
|
67
|
+
|
|
68
|
+
Both real apps use standalone Angular configuration and Angular dependency injection. Start with an Angular provider API. Do not add a framework-neutral core or adapter layer until a non-Angular consumer creates that requirement.
|
|
69
|
+
|
|
70
|
+
## Phase 2 — App information
|
|
71
|
+
|
|
72
|
+
Expose a Meadow-owned value shape rather than Capacitor types.
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
export interface MeadowAppInfo {
|
|
76
|
+
version: string | null;
|
|
77
|
+
buildNumber: string | null;
|
|
78
|
+
platform: 'ios' | 'android' | 'web';
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Requirements:
|
|
83
|
+
|
|
84
|
+
- use Capacitor behind the package boundary;
|
|
85
|
+
- return `null` native metadata on web and when the native plugin is unavailable;
|
|
86
|
+
- avoid exposing native plugin result types; and
|
|
87
|
+
- verify values in a small build-information row in 24h Pushups settings.
|
|
88
|
+
|
|
89
|
+
## Phase 3 — Validate the first POC
|
|
90
|
+
|
|
91
|
+
Validate the locally packed dependency in the actual 24h Pushups prototype.
|
|
92
|
+
|
|
93
|
+
POC gate:
|
|
94
|
+
|
|
95
|
+
- the platform package builds and its public types compile;
|
|
96
|
+
- `npm pack --dry-run` contains only intended files;
|
|
97
|
+
- 24h Pushups resolves the local file dependency as `@meadow-studio/platform@0.1.0`;
|
|
98
|
+
- the app provides its name, application ID, and current environment through the platform API;
|
|
99
|
+
- the Settings page reads version/build/platform through the platform service;
|
|
100
|
+
- existing 24h Pushups tests, lint, production build, and device build pass;
|
|
101
|
+
- the existing Android project synchronizes and builds; and
|
|
102
|
+
- the consumer does not import platform implementation internals.
|
|
103
|
+
|
|
104
|
+
Stop here and assess whether the integration removed duplication while remaining easier to understand than local app code.
|
|
105
|
+
|
|
106
|
+
## Phase 4 — Analytics vertical slice
|
|
107
|
+
|
|
108
|
+
Inventory the analytics behavior already proven in Stay Light before designing the public interface.
|
|
109
|
+
|
|
110
|
+
Start with the minimum consumer capability:
|
|
111
|
+
|
|
112
|
+
```ts
|
|
113
|
+
analytics.track('challenge_created');
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Requirements:
|
|
117
|
+
|
|
118
|
+
- application code imports only Meadow Platform analytics types/functions;
|
|
119
|
+
- disabled analytics is a safe no-op;
|
|
120
|
+
- event names and properties remain app-owned;
|
|
121
|
+
- Firebase-specific initialization and types stay behind the package boundary;
|
|
122
|
+
- provider failures do not break the core app flow; and
|
|
123
|
+
- one real 24h Pushups event is observable in the configured analytics environment.
|
|
124
|
+
|
|
125
|
+
Do not add screen tracking, identity, consent orchestration, event schemas, batching, or multiple providers until an existing app demonstrates the requirement.
|
|
126
|
+
|
|
127
|
+
## Phase 5 — Validate and release v0.1
|
|
128
|
+
|
|
129
|
+
Validate the package in the actual consumer rather than only in unit tests.
|
|
130
|
+
|
|
131
|
+
Release gate:
|
|
132
|
+
|
|
133
|
+
- the platform package builds and its public types compile;
|
|
134
|
+
- a clean consumer install works from the chosen private source;
|
|
135
|
+
- the 24h Pushups web and Android builds succeed;
|
|
136
|
+
- app information is correct on-device;
|
|
137
|
+
- analytics disabled mode and one enabled event both work;
|
|
138
|
+
- the app contains no direct Firebase analytics imports outside native/configuration setup where unavoidable;
|
|
139
|
+
- no credentials or generated app-specific configuration exist in the package;
|
|
140
|
+
- the public API is documented with a minimal integration example; and
|
|
141
|
+
- 24h Pushups pins the released platform version.
|
|
142
|
+
|
|
143
|
+
Generate and validate the iOS consumer only when iOS work begins in 24h Pushups. Tag the proven platform release as `0.1.0`. Treat changes discovered during consumer integration as design feedback, not as exceptions to work around in the app.
|
|
144
|
+
|
|
145
|
+
## Next slice — Purchases
|
|
146
|
+
|
|
147
|
+
After v0.1 proves the package and provider boundary, inventory Stay Light's RevenueCat integration and implement the smallest end-to-end purchase capability needed by 24h Pushups.
|
|
148
|
+
|
|
149
|
+
Start by validating these operations only if the consumer needs them:
|
|
150
|
+
|
|
151
|
+
- initialize with externally supplied configuration;
|
|
152
|
+
- observe premium status;
|
|
153
|
+
- purchase one product/package;
|
|
154
|
+
- restore purchases; and
|
|
155
|
+
- translate provider errors into a small Meadow-owned error model.
|
|
156
|
+
|
|
157
|
+
Keep paywall UI and product-specific messaging in the app. Do not expose RevenueCat customer-info or entitlement types through the public API.
|
|
158
|
+
|
|
159
|
+
### Purchase capability completion — 2026-09-18
|
|
160
|
+
|
|
161
|
+
The slice is now implemented as `MeadowPurchaseService`. It loads app-configured offering packages,
|
|
162
|
+
exposes normalized product and entitlement signals, derives premium state, performs purchase and
|
|
163
|
+
restore, refreshes/listens for customer-info changes, returns a support identifier, and translates
|
|
164
|
+
provider failures into Meadow-owned outcomes and error categories. Generated apps keep platform
|
|
165
|
+
public SDK keys in `.env.meadow.local`, generate an ignored runtime asset before builds, and validate
|
|
166
|
+
the dependency, enabled-platform keys, and catalog identifiers through `meadow doctor`.
|
|
167
|
+
|
|
168
|
+
Paywall UI, product taxonomy and IDs, pricing and entitlement policy, analytics, and store catalog
|
|
169
|
+
remain app-owned. Unit tests, packed-consumer checks, CLI configuration, and clean Android/iOS
|
|
170
|
+
simulator builds validate the shared foundation; real store sandbox transactions remain an app
|
|
171
|
+
release check.
|
|
172
|
+
|
|
173
|
+
## First concrete work session
|
|
174
|
+
|
|
175
|
+
Before writing platform abstractions:
|
|
176
|
+
|
|
177
|
+
1. add explicit package exports and align supported peer/runtime versions with the shared app baseline;
|
|
178
|
+
2. add a minimal test runner and a packed-package smoke test;
|
|
179
|
+
3. implement an Angular `provideMeadowPlatform(...)` configuration entry point;
|
|
180
|
+
4. implement app information behind a Meadow-owned interface; and
|
|
181
|
+
5. integrate the packed artifact into 24h Pushups and show build information in Settings.
|
|
182
|
+
|
|
183
|
+
This creates a small review point before Firebase or RevenueCat dependencies become part of the package contract.
|
|
184
|
+
|
|
185
|
+
## POC implementation status — 2026-09-14
|
|
186
|
+
|
|
187
|
+
The first POC is implemented:
|
|
188
|
+
|
|
189
|
+
- `@meadow-studio/platform` exposes explicit package exports and Angular/Capacitor peer ranges;
|
|
190
|
+
- `provideMeadowPlatform(...)` validates and freezes typed app/environment configuration;
|
|
191
|
+
- `MeadowAppInfoService` returns native version, build number, and platform behind a Meadow-owned interface;
|
|
192
|
+
- web runtimes receive an honest `null` for unavailable native metadata;
|
|
193
|
+
- the Capacitor App module is loaded only when native metadata is requested;
|
|
194
|
+
- platform unit tests and the package dry-run pass;
|
|
195
|
+
- 24h Pushups consumes the package through a local file dependency;
|
|
196
|
+
- development, device, and production builds supply distinct platform environments;
|
|
197
|
+
- Settings displays `Web preview` on web and native version/build/platform on a device;
|
|
198
|
+
- all 48 consumer tests and lint pass; and
|
|
199
|
+
- production, device, Capacitor sync, and Android debug APK builds pass.
|
|
200
|
+
|
|
201
|
+
Native metadata has not been observed on a physical device because no Android device was connected during verification. The production web build also retains its bundle-budget warning: after the analytics foundation, the initial bundle is 4.49 kB over the configured 675 kB warning threshold.
|
|
202
|
+
|
|
203
|
+
## Release readiness status — 2026-09-14
|
|
204
|
+
|
|
205
|
+
The reproducible private-package path is implemented:
|
|
206
|
+
|
|
207
|
+
- CI runs on pushes, pull requests, and manual dispatches with Node 22.15;
|
|
208
|
+
- `npm run version:set -- <patch|minor|major|x.y.z>` updates the package manifest, lockfile, and public runtime version together;
|
|
209
|
+
- `npm run version:check` detects version drift;
|
|
210
|
+
- `npm run test:consumer` creates the real tarball, rejects unexpected packaged files, installs it in a clean temporary consumer, type-checks the public API, and exercises it at runtime;
|
|
211
|
+
- `npm run release:check` runs the complete local release gate; and
|
|
212
|
+
- `docs/RELEASING.md` defines immutable private Git-tag installation and application upgrades.
|
|
213
|
+
|
|
214
|
+
24h Pushups deliberately remains on the local file dependency while the platform changes are under development. After the reviewed platform commit and `v0.1.0` tag exist on the private remote, switch the app dependency to the exact Git tag and regenerate its lockfile. Do not point the app at a tag that is not yet remotely installable.
|
|
215
|
+
|
|
216
|
+
## Analytics foundation status — 2026-09-14
|
|
217
|
+
|
|
218
|
+
The provider-neutral portion of the analytics slice is implemented:
|
|
219
|
+
|
|
220
|
+
- collection starts disabled and can only become effective in a production environment when analytics is configured as available;
|
|
221
|
+
- event names and property names are app-owned allowlists supplied through typed configuration;
|
|
222
|
+
- unexpected events, unexpected properties, nullish values, and non-finite numbers are dropped;
|
|
223
|
+
- enablement updates are serialized for asynchronous providers;
|
|
224
|
+
- provider setup and delivery failures never interrupt application flows;
|
|
225
|
+
- 24h Pushups owns a focused `PushupAnalyticsService` and records `pushups_logged` only after the domain action succeeds; and
|
|
226
|
+
- 24h Pushups keeps analytics disabled, so this integration emits no data.
|
|
227
|
+
|
|
228
|
+
The Firebase transport, native Firebase configuration, persisted consent choice, consent UI, and observable native event delivery remain future work. They should be introduced together when 24h Pushups is ready to collect real product analytics.
|
|
229
|
+
|
|
230
|
+
### Firebase observability completion — 2026-09-17
|
|
231
|
+
|
|
232
|
+
The platform work identified above is now implemented. Analytics and Crashlytics use Meadow-owned
|
|
233
|
+
runtime services backed by native Firebase transports, separate persisted explicit consent, and
|
|
234
|
+
production-only enforcement. `meadow configure firebase`, `meadow sync`, and `meadow doctor` now own the
|
|
235
|
+
repeatable Android and iOS setup, including native collection-off defaults and bundling the iOS
|
|
236
|
+
Firebase configuration resource. An app still owns its consent experience and must confirm one
|
|
237
|
+
event and one test crash against its real Firebase project before release.
|
|
238
|
+
|
|
239
|
+
## App rating foundation status — 2026-09-14
|
|
240
|
+
|
|
241
|
+
The first reusable native capability after the POC is implemented:
|
|
242
|
+
|
|
243
|
+
- `MeadowAppRatingService` presents the system-owned App Store or Play Store rating surface;
|
|
244
|
+
- the private package carries its own Capacitor iOS and Android plugin code, so consuming apps do not copy native files;
|
|
245
|
+
- web and unavailable native runtimes safely return without presenting anything;
|
|
246
|
+
- concurrent requests share one attempt and native failures never interrupt app behavior;
|
|
247
|
+
- Meadow avoids requesting twice for the same app version, waits 120 days between attempts, and caps attempts at two per rolling year;
|
|
248
|
+
- 24h Pushups owns its product qualification and asks only after 100 total pushups and a three-day winning streak;
|
|
249
|
+
- the packed consumer check includes and validates the native package files;
|
|
250
|
+
- 24h Pushups discovers the package as a Capacitor plugin and its Android debug APK compiles with it; and
|
|
251
|
+
- the iOS Swift source type-checks against Capacitor 7, while full 24h iOS integration remains deferred until that app generates an iOS project.
|
|
252
|
+
|
|
253
|
+
No custom rating modal was added. Ratings use the operating-system interface; reusable custom dialogs remain a Meadow Design concern.
|
|
254
|
+
|
|
255
|
+
## CLI foundation status — 2026-09-16
|
|
256
|
+
|
|
257
|
+
The explicitly requested idea-to-release tooling now forms the v0.2 development baseline:
|
|
258
|
+
|
|
259
|
+
- `meadow new <name>` creates a standalone application repository on Angular 22 and Capacitor 8;
|
|
260
|
+
- the generated stack excludes Ionic and Meadow Design while leaving both as app-owned choices;
|
|
261
|
+
- creation installs exact dependencies, generates iOS and Android, validates the app, creates
|
|
262
|
+
phone/tablet Playwright baselines, and makes an initial gitmoji commit;
|
|
263
|
+
- optional prompts add RevenueCat and Supabase client dependencies without platform-owned secrets;
|
|
264
|
+
- `meadow configure` covers Firebase, RevenueCat, Supabase, assets, signing guidance, store metadata,
|
|
265
|
+
and GitHub repository creation;
|
|
266
|
+
- `meadow doctor`, `meadow version`, and `meadow release-check` provide repeatable diagnostics and release
|
|
267
|
+
gates;
|
|
268
|
+
- every generated repository includes GitHub CI for formatting, linting, dependency audit,
|
|
269
|
+
coverage-gated Vitest tests, web build, Playwright screenshot comparison, Android compilation,
|
|
270
|
+
and an unsigned iOS simulator build; and
|
|
271
|
+
- a clean generated project has been validated through dependency audit, web/device builds, unit
|
|
272
|
+
and screenshot tests, Android assembly, and iOS simulator compilation.
|
|
273
|
+
|
|
274
|
+
The historical v0.1 notes above remain evidence of the original POC baseline. New apps use the
|
|
275
|
+
v0.2 CLI baseline documented in [CLI.md](CLI.md).
|
|
276
|
+
|
|
277
|
+
## Local-data recipe status — 2026-09-16
|
|
278
|
+
|
|
279
|
+
The first optional post-creation capability is implemented as `meadow add local-data`:
|
|
280
|
+
|
|
281
|
+
- native apps use `@capacitor-community/sqlite`, while browser development uses its
|
|
282
|
+
IndexedDB-persisted SQLite runtime;
|
|
283
|
+
- the recipe generates a small Meadow-owned database boundary, sequential migrations, transactions,
|
|
284
|
+
and a typed JSON document store;
|
|
285
|
+
- app-specific schemas, decoders, and repositories remain in the consuming app;
|
|
286
|
+
- dependency and runtime versions are pinned, native projects are synchronized, and the complete
|
|
287
|
+
generated-app check runs before the config is marked ready;
|
|
288
|
+
- Android cloud backup is disabled by default for local app data; and
|
|
289
|
+
- the generated release checklist covers migration upgrades, reset/deletion behavior, restore
|
|
290
|
+
policy, and native SQLCipher export-compliance review.
|
|
291
|
+
|
|
292
|
+
This slice is based on the validated repositories in 24h Pushups and the Capacitor SQLite use in
|
|
293
|
+
Nyttebjerggaard, while keeping Stay Light's more specialized recovery behavior app-owned until a
|
|
294
|
+
second app proves that it belongs in the shared foundation.
|
|
295
|
+
|
|
296
|
+
Validation in a clean generated app passed formatting, linting, unit tests, production web build,
|
|
297
|
+
Capacitor synchronization, an Android debug build, and an actual browser SQLite write/read followed
|
|
298
|
+
by an IndexedDB-backed reload. That runtime check caught and fixed an ABI mismatch by pinning
|
|
299
|
+
`sql.js` 1.11.0 to the version used by `jeep-sqlite` 2.8.0. The iOS graph successfully resolved the
|
|
300
|
+
SQLite and SQLCipher packages, but the broader Xcode package update then remained idle and was
|
|
301
|
+
stopped; a full iOS simulator compile for this optional recipe still needs a clean resolver run.
|
|
302
|
+
|
|
303
|
+
## Local-notification capability status — 2026-10-06
|
|
304
|
+
|
|
305
|
+
The later platform work added `meadow add notifications` and a provider-neutral
|
|
306
|
+
`MeadowNotificationService` based on repeated needs in 24h Pushups and Stay Light. The service keeps
|
|
307
|
+
permission prompting explicit, supports one-off and recurring calendar schedules,
|
|
308
|
+
replace/cancel/pending operations, Android channels, and tap actions, and remains safe when disabled
|
|
309
|
+
or running on web. Product copy, IDs, timing policy, navigation, and analytics remain app-owned.
|
|
310
|
+
Android schedules are deliberately inexact by default.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import Capacitor
|
|
2
|
+
import StoreKit
|
|
3
|
+
import UIKit
|
|
4
|
+
|
|
5
|
+
/// Presents Apple's system-owned rating surface. StoreKit intentionally does
|
|
6
|
+
/// not disclose whether the person submitted a rating or dismissed the sheet.
|
|
7
|
+
@objc(MeadowAppRatingPlugin)
|
|
8
|
+
public class MeadowAppRatingPlugin: CAPPlugin, CAPBridgedPlugin {
|
|
9
|
+
public let identifier = "MeadowAppRatingPlugin"
|
|
10
|
+
public let jsName = "MeadowAppRating"
|
|
11
|
+
public let pluginMethods: [CAPPluginMethod] = [
|
|
12
|
+
CAPPluginMethod(name: "requestReview", returnType: CAPPluginReturnPromise),
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
@objc public func requestReview(_ call: CAPPluginCall) {
|
|
16
|
+
// StoreKit ignores review requests in TestFlight. Do not consume Meadow's
|
|
17
|
+
// cooldown when the operating system cannot attempt to show the sheet.
|
|
18
|
+
#if !DEBUG
|
|
19
|
+
if Bundle.main.appStoreReceiptURL?.lastPathComponent == "sandboxReceipt" {
|
|
20
|
+
call.resolve(["attempted": false])
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
#endif
|
|
24
|
+
|
|
25
|
+
DispatchQueue.main.async {
|
|
26
|
+
guard let scene = self.bridge?.viewController?.view.window?.windowScene else {
|
|
27
|
+
call.reject("No active window is available for the App Store review prompt")
|
|
28
|
+
return
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if #available(iOS 18.0, *) {
|
|
32
|
+
AppStore.requestReview(in: scene)
|
|
33
|
+
} else {
|
|
34
|
+
SKStoreReviewController.requestReview(in: scene)
|
|
35
|
+
}
|
|
36
|
+
call.resolve(["attempted": true])
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,91 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meadow-studio/platform",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public",
|
|
6
|
+
"registry": "https://registry.npmjs.org/"
|
|
7
|
+
},
|
|
8
|
+
"type": "module",
|
|
9
|
+
"description": "Meadow app platform to support app development",
|
|
10
|
+
"bin": {
|
|
11
|
+
"meadow": "dist/cli/meadow.js"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"exports": {
|
|
16
|
+
".": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"import": "./dist/index.js"
|
|
19
|
+
},
|
|
20
|
+
"./ui": {
|
|
21
|
+
"types": "./dist/ui/index.d.ts",
|
|
22
|
+
"import": "./dist/ui/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./schema/meadow-config.schema.json": "./schema/meadow-config.schema.json",
|
|
25
|
+
"./package.json": "./package.json"
|
|
26
|
+
},
|
|
27
|
+
"files": [
|
|
28
|
+
"dist",
|
|
29
|
+
"docs",
|
|
30
|
+
"schema",
|
|
31
|
+
"android/src/main",
|
|
32
|
+
"android/build.gradle",
|
|
33
|
+
"ios/Sources",
|
|
34
|
+
"Package.swift",
|
|
35
|
+
"MeadowPlatform.podspec"
|
|
36
|
+
],
|
|
37
|
+
"sideEffects": false,
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=24.15 <25",
|
|
40
|
+
"npm": ">=11 <12"
|
|
41
|
+
},
|
|
42
|
+
"scripts": {
|
|
43
|
+
"test": "npm run build && node --test test/*.test.mjs",
|
|
44
|
+
"test:consumer": "node scripts/test-packed-consumer.mjs",
|
|
45
|
+
"build": "ngc -p tsconfig.json",
|
|
46
|
+
"clean": "rm -rf dist",
|
|
47
|
+
"pack:check": "npm pack --dry-run --cache .cache/npm",
|
|
48
|
+
"prepare": "npm run build",
|
|
49
|
+
"prepublishOnly": "npm run release:check",
|
|
50
|
+
"version:check": "node scripts/version.mjs check",
|
|
51
|
+
"version:set": "node scripts/version.mjs set",
|
|
52
|
+
"check": "npm run version:check && npm test && npm run test:consumer",
|
|
53
|
+
"release:check": "npm run check && npm run pack:check && git diff --check"
|
|
54
|
+
},
|
|
55
|
+
"repository": {
|
|
56
|
+
"type": "git",
|
|
57
|
+
"url": "git+https://github.com/nyttebjerggaard/meadow-studio.git",
|
|
58
|
+
"directory": "platform"
|
|
59
|
+
},
|
|
60
|
+
"keywords": [],
|
|
61
|
+
"author": "",
|
|
62
|
+
"license": "ISC",
|
|
63
|
+
"bugs": {
|
|
64
|
+
"url": "https://github.com/nyttebjerggaard/meadow-studio/issues"
|
|
65
|
+
},
|
|
66
|
+
"homepage": "https://github.com/nyttebjerggaard/meadow-studio/tree/main/platform#readme",
|
|
67
|
+
"capacitor": {
|
|
68
|
+
"ios": {
|
|
69
|
+
"src": "ios"
|
|
70
|
+
},
|
|
71
|
+
"android": {
|
|
72
|
+
"src": "android"
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"peerDependencies": {
|
|
76
|
+
"@angular/core": "^22.1.6",
|
|
77
|
+
"@capacitor/app": "^8.1.1",
|
|
78
|
+
"@capacitor/core": "^8.4.3"
|
|
79
|
+
},
|
|
80
|
+
"devDependencies": {
|
|
81
|
+
"@angular/compiler": "22.1.6",
|
|
82
|
+
"@angular/compiler-cli": "22.1.6",
|
|
83
|
+
"@angular/core": "22.1.6",
|
|
84
|
+
"@capacitor/app": "8.1.1",
|
|
85
|
+
"@capacitor/core": "8.5.2",
|
|
86
|
+
"@types/node": "24.10.1",
|
|
87
|
+
"rxjs": "7.8.2",
|
|
88
|
+
"typescript": "6.0.3",
|
|
89
|
+
"zone.js": "0.16.0"
|
|
90
|
+
}
|
|
91
|
+
}
|